去年12月份打的比赛,一共6道pwn,和室友一起做了5道,出了两道tcache,这可能算是我第一次在比赛里面做出来题,所以记得比较清楚哈~
tcache的题做起来感觉很有意思,主要是对tcache的安全限制太小了。这里的两道题都值得好好的做一下,其中的houseofAtum
更是第一次出现在比赛里面。题目相关的文件可以在这里下载。
three
程序存在UAF,能分配3个chunk,没有输出。利用分为三个步骤
- double free拿到heap上0x250大小的tcache结构体,设置0x250对应的tcache数量大于7,释放并分配chunk拿到unsorted bin的地址
- 部分写unsorted bin的地址,通过tcache分配到stdout结构体所在内存,覆盖
flag
、_IO_write_base
等指针泄露libc地址,参考:https://vigneshsrao.github.io/babytcache/ - 利用tcache覆盖
__free_hook
为one_gadget
拿到shell
可能需要多次对tcache结构体进行编辑控制tcache bins的长度,来让一些chunk放入fastbin中
1 | from pwn import * |
houseofAtum
程序仍然存在UAF,但只允许分配最多2个chunk,且多了输出函数。
利用思路:
- 将
tcachebin
和fastbin
结合起来,tcachebin
中数量大于7后0x50大小的chunk会被放入fastbin
中 tcachebin
中的链表指针指向的是chunk的fd,fastbin
中的链表指针指向的是chunk的prev_size
域,这个域的内容是我们可以控制的- 先在tcachebin中布置好chunk1–>chunk2–>chunk2……,再在fastbin中布置chunk1–>chuk2,此时
tcachebin
中的chunk1指针会被修改为指向chunk2的prev_size
,再连续分配两次后,prev_size
域中的内容会被放入tcachebins
中,该内容可以控制,导致可以分配任意地址的内存(上述操作后chunk2的部分字段和chunk1重叠,修改chunk2的size字段为0x61,这样chunk2释放后不会放入0x50的tcachebin,这样就能拿到指定位置的chunk了) - 通过任意分配内存拿到chunk1+0x10处的虚假chunk3,修改chunk1使chunk3的size为0x91,连续释放8次chunk3,拿到unsortedbin地址,实现泄露libc地址
- 把chunk3放入tcachebin,修改fd为
__free_hook
地址,通过修改其size让其放入其它大小的tcachebins,最后拿到__free_hook
位置的内存,修改为one_gadget
拿到shell
1 | from pwn import * |