Tcache Attack

Tcache是libc-2.26(包含)正式启用,目的就是为了提升堆管理性能。但是提升了性能,却放弃了很多的安全检查,所以就有更多的漏洞利用手法。

https://blog.csdn.net/qq_41202237/article/details/113400567?spm=1001.2014.3001.5501

Tcache

tcache引入了两个新的结构体。tcache_entrytcache_perthread_struct

tcache_entry

tcache_entry其中的next指针指向下一个大小相同的chunk,其中需要注意的是next指向的是data部分。

接下来是tcache_perthread_struct,是用来管理tcache链表的,这个结构体位于heap段的起始位置,size大小为0x251。每一个thread都会维护一个tcache_perthread_struct结构体,一共有TCACHE_MAX_BINS个计数器TCACHE_MAX_BINS项tcache_entry。

  • tcache_entry 用单向链表的方式链接了相同大小的处于空闲状态(free 后)的 chunk

  • counts 记录了 tcache_entry 链上空闲 chunk 的数目,每条链上最多可以有 7 个 chunk

tcache第一次malloc时会产生0x251大小的堆块用来存放perthread_struct

  • 释放chunk时,如果chunk的size小于small bin size,在进入tcache之前会先放进fastbin或者unsorted bin中

  • 在放入tcache中:

    • 先放到对应的tcache中,直到tcache被填满(7个)
    • tcache被填满后,接下来再释放chunk,就会直接放进fastbin或者unsorted bin中
    • tcache中的chunk不会发生合并,不取消inuse bit
  • 重新申请chunk,并且申请的size符合tcache的范围,则先从tcache中取chunk,直到tcache为空

  • tcache为空后,从bin中找

  • tcache为空时,如果fastbin、small bin、unsorted bin中有size符合的chunk,会先把fastbin、small bin、unsorted bin中的chunk放到tcache中,直到填满,之后再从tcache中取

tcache_get()和tcache_put()

tcache有两个重要的函数,它们是tcache_get()和tcache_put(),看一下源码吧。

tcache_get是将free掉的chunk从tcache中取出

tcache_put是将free掉的chunk放入tcache中

先看一下get吧。

流程很简单,从tc_idx中获取一个指针,tcache->counts减一。

先判断合法,进入tcache_put()函数,传递的一参为要释放的chunk指针,二参为chunk对应的size在tcache中的下标

再看一下tcache_put吧

把释放的chunk放到了tcache->entries[tc_idx]头,没有什么安全保护

2.27的tcache利用

tcache poisoning

将tcache中的chunk的fd改写目的地址,malloc合适的size就可以控制

tcache dup

和fastbin double free有点像,在tcache中,可以对一个chunk多次free,因为此版本的put函数安全检查不高。

tcache house of spirit

和fastbin house of spirit有点类似。但是有了2.27的tcache更简单,因为没有过多的安全检查,只要size满足就可以了

还有很多的tcache的利用,后面的文章再看吧。