fastbin
Fast Bin分类的chunk的大小为32~128(0x80)字节,如果chunk在被释放时发现其大小满足这个要求,则将该chunk放入Fast Bin,且在被释放后不修改下一个chunk的PREV_INUSE标志位。Fast Bin在堆管理器中以单链表的形式存储,不同大小的Fast Bin存储在对应大小的单链表结构中,其单链表的存取机制是LIFO(后进先出)。一个最新被加入Fast Bin的chunk,其fd指针指向上一次加入 Fast Bin的chunk。
或者直接在linux终端输入
apt install glibc-source
Fastbin|Fastbin attack
上面介绍了Fastbin是单链表结构,使用fd指针连接的LIFO结构。在Glibc 2.25及其之前版本,在被释放后,会先判断其大小是否不超过global_max_ fast的大小,如果是,则放入Fast Bin,则进行其他操作。在chunk的大小满足不超过global_max_fas的条件后,还会判断其大小是否超过最小chunk且小于系统内存,然后将该chunk加入相应大小的链表。
Fast Bin的申请操作也不复杂,先判断申请的大小是否不超过global max fast的大小,如果满足, 则从该大小的链表中取出一个chunk.但是在取出chunk后,代码
if(__builtin__expect(fastbin_index(chunksize(victim))!=idx,0))
对取出的chunk的合法性进行了验证,验证该chunk的size部位必须与该链表应该存储的chunk的size部位一致。换句话说,如果该链表存储的是size为0x70大小的chunk,那么从该链表取出的chunk的size部位也必须是0x70。在确定chunk的size部位合法后, 会返回该chunk.(从源码看,Ptmalloc2存在很多严格的检查,但是很多检查需要开启MALLOC DEBUG才会生效。这个参数默认是关闭的,具体请查阅Ptmalloc2源码。)
根据对源码分析,我们可以得出Ptmalloc2在处理Fast Bin大小的chunk时,对chunk的合法性的检查并不多。所以,我们可以利用以下缺陷进行漏洞利用。
1、修改fd指针
针对一个已经在Fast Bin的chunk,我们可以修改其fd指针指向目标内存,这样在下次分配该大小的 chunk时就可以分配到目标内存。但是在分配Fast Bin时,Ptmalloc2存在一个对chunk的size位的检 查,我们可以通过修改目标内存的size位来绕过这个检查。
(1)修改fd指针低位 想要实现分配到目标内存区域,则需要知道目标内存地址,但是由于系统ASLR的限制,我们需要通 过其他漏洞获得内存地址,这意味着需要额外的漏洞来进行漏洞利用。但是堆的分配在系统中的偏移是固定的,分配的堆内存的地址相对于堆内存的基地址是固定的,通过修改fd指针的低位,我们不需要进行信息泄漏也可以进行内存的Overlap实现攻击。
(2)Double Free List