CTFshow pwn164
CTFshow pwn164 (tcache dup)
前言
一步一步来吧,这是一道2.27版本的利用。同时是需要打__IO_2_1_stdout_去泄露libc地址的。但是难度不大,因为tcache bin 有些太拉胯了。给它一个uaf ,它可以自己double free 7次。这是什么?然后利用realloc 的一个特性,既可以malloc 又 可以 free。
七剑下天山 遇上 双料特工 ,简直无敌了。
ida分析
delete功能

1.典型的uaf 没有置空,但是ptr是哪来的?
2.继续看,add功能
add功能

1.ptr在这里,也就是刚刚分配的堆块的指针。
2.realloc,一个很有问题的函数。当size不为0时且ptr不为空时:realloc 会检测ptr 的大小,如果ptr_size>=size,就重新分配,切割;否则,会先free ptr,再分配,然后两者都会返回分配的空间的指针。当size不为0且ptr为空时,与malloc等效,返回指针。当size为0且ptr不为空时,与free等效,并且返回空。size为0且ptr为空,梅栾邕。
神秘选项

1.一次置空ptr的机会
思路分析
1.首先还是查看保护机制–全开。第一步还是老步骤,泄露libc。同样在这里只能通过unsorted bin中的堆块,来泄露。但是因为是2.27版本,所以需要先把tcache bin填满,才能让堆块进入unsorted bin。同时,此题没有show来打印,所以需要劫持__IO_2_1_stdout_ ,然后puts时,会把相关信息打出来。那么通过gdb 观察 stdout 的地址与main_arena的地址,修改低位两字节即可。这里需要注意一点。当我们把tcache bin 填满,且把这个堆块放入unsorted bin中后。如果直接add 这个堆块,是会把tcache bin 中的这个堆块申请出来的。如图:
2.如果要实现tcache dup 的话,应该是先把unsorted bin 中的这个堆块拿出来,并且覆盖fd针的低位,使得stdout被链入tcache bin 中。然后在把这两个堆块申清出来。所以我们要在这个堆块前面,申请一个堆块a。a堆块与我们这个堆块地址相邻,在申请前,先把a堆块申请出来,再申请两个堆块大小之和的堆块大小,这样a会先被free,然后与这个堆块合并再被分配出来。如图:
3.然后就是劫持stdout ,拿到libc后就是,同样的操作,去分配到free hook并篡改成system。同时在free hook -8 的位置布置”/bin/sh;” 最后free() 就可以触发,getshell了
exp
1 | from esy import * |


