Tcache_Attack(1)
本文最后更新于 2024年11月10日 下午
Tcache_Attack(1)
Tcache_konwledge(引用CTF-Wiki)
tcache是glibc 2.26(Ubuntu 17.10)之后引入的一种技术,其目的是为了提升堆管理的性能。我们都知道,一旦某个整体的应用添加了更加复杂的执行流程,那么就意味着整体执行的速度就会降低,那么为了弥补这一部分的欠缺,就不得不有所牺牲。所以虽然提升了整体的性能,但却舍弃了很多安全检查,这就意味着更多新的漏洞就伴随而来,也增添了很多利用方式
tcache引入了两个新的结构体:tcache_entry
和tcache_perthread_struct
。增添的两个结构体其实与fastbin有些类似,但是也有一定的区别
tcache_entry结构体如下:
1 |
|
与fastbin不同的是,tcache_entry的next指向的是下一个chunk的data域,fastbin的next指向的是下个chunk的头指针。
tcache_perthread_struct结构体如下:
1 |
|
这个结构体是用来管理tcache链表的,这个结构体位于heap段的起始位置,其中
- tcache_entry 用单向链表的方式链接了相同大小的处于空闲状态(free 后)的 chunk
- counts 记录了 tcache_entry 链上空闲 chunk 的数目,每条链上最多可以有 7 个 chunk
tcache_get()函数
1 |
|
可以看到这个函数很简单,获取一个chunk指针,然后count-1,没有太多的安全检查
tcache_put()函数
1 |
|
tcache_put()函数就是简单在tcahe链头插入一个chunk,也没有做过多的安全检查
Tcache usage
第一次malloc时会在heap头回显一块内存用来存放
tcache_perthread_struct
,这块内存size一般为0x251申请的内存块符合 fastbin 大小时并且在 fastbin 内找到可用的空闲块时,会把该 fastbin 链上的其他内存块放入 tcache 中。
申请的内存块符合 smallbin 大小时并且在 smallbin 内找到可用的空闲块时,会把该 smallbin 链上的其他内存块放入 tcache 中。
当在 unsorted bin 链上循环处理时,当找到大小合适的链时,并不直接返回,而是先放到 tcache 中,继续处理。
tcache 取出:在内存申请的开始部分,首先会判断申请大小块,在 tcache 是否存在,如果存在就直接从 tcache 中摘取,否则再使用_int_malloc 分配。
PWN Tcache
tcache poisoning
因为tcache_get没有对next进行检查,所以我们可以覆盖tcache的fd指针,从而实现对任意地址的malloc
我们申请两个chunk并释放
可以看到这时chunkb的fd是chunka
而经过覆盖之后就可以把任意地址挂进tcachebin
tcache dup
这种利用方法其实就是fastbin中的double_free,如果在释放的时候指针未置空,可以对一个chunk释放两次
我们申请一个chunk a连续释放两次
可以看到此时同一个chunk a被挂进去两次
此时我们在申请chunk b,那么这次启用的是第二次挂进去的chunk a,此时打印chunk_a和chunk_b的fd指针会发现其实都是chunk_a
tcache house of spirit
tcache house of spirit这种利用方式是由于tcache_put()函数检查不严格造成的,跟fastbin的很像,
他的原理就是,将一个tcache bin中的chunk的fd指针改成我们伪造的fake_chunk,然后申请一个chunk,那么malloc在申请的同时,会把本没有free的fake_chunk挂进tcache bin,甚至他的检查比fastbin还要松一点,这里就不具体说明了,请参考博主的另一篇文章