前言:下面就是我根据一些博客,做了一些自己的整理和补充,配合viki食用更加
一、利用前提
- 存在堆溢出、use-after-free 等能控制 chunk 内容的漏洞
- 漏洞发生于 fastbin 类型的 chunk 中
二、利用原理
- fastbin是通过单链表来存储释放堆块的,并且由 fastbin 管理的 chunk 即使被释放,其 next_chunk 的 prev_inuse 位也不会被清空。
- 其实核心漏洞的演示就如下面所示
int main(void){
void *chunk1,*chunk2,*chunk3;
chunk1=malloc(0x30);
chunk2=malloc(0x30);
chunk3=malloc(0x30); //进行释放
free(chunk1);
free(chunk2);
free(chunk3);
return 0;
}
- fastbins的链表就会被构造成下面这样
最最最核心的思想
这个free chunk和 malloc chunk都是我们的chunk1(注意它的双重身份)(其实就是两个指针指向了同一个地址)我们可以通过它malloc chunk的身份修改它user段的第一个字段也就是free chunk中的bk指针所在位置,可以达到在不同位置(bss、栈等)分配chunk,期间需要绕过一些检测。
三、四种姿势
1、Fastbin Double Free
1.1介绍
Fastbin Double Free 是指 fastbin 的 chunk 可以被多次释放,因此可以在 fastbin 链表中存在多次。这样导致的后果是多次分配可以从 fastbin 链表中取出同一个堆块,相当于多个指针指向同一个堆块,结合堆块的数据内容可以实现类似于类型混淆 (type confused) 的效果。
Fastbin Double Free 能够成功利用主要有两部分的原因
- fastbin 的堆块被释放后 next_chunk 的 pre_inuse 位不会被清空
- fastbin 在执行 free 的时候仅验证了 main_arena 直接指向的块,即链表指针头部的块。对于链表后面的块,并没有进行验证。
1.2演示
这里printf输出的就是bss_chunk段的地址
1.3解释
图片中字有点小师傅们页面放大看一下
注意点1
这是我理解的4次malloc所分配的chunk,我们主要是为了获得第4次malloc的chunk(第一次是为了修改fd,中间两次是把fastbin中的chunk分配掉),前三次分配的chunk都是fastbin中的,第四次由于fd被修改,使得堆管理器误以为fastbin中还有这么个玩意,然后顺着被修改的fd找到了chunk_b的位置,这次演示是修改倒了bss段。
注意点2
值得注意的是,我们在 main 函数的第一步就进行了bss_chunk.size=0x21;的操作,这是因为_int_malloc 会对欲分配位置的 size 域进行验证,如果其 size 与当前 fastbin 链表应有 size 不符就会抛出异常。
2、House Of Spirit
1.1介绍
1.1.1该技术的核心
在于在目标位置处伪造 fastbin chunk,并将其释放,从而达到分配指定地址的 chunk 的目的。
1.1.2需要绕过的检测
- fake chunk 的 ISMMAP 位不能为 1,因为 free 时,如果是 mmap 的 chunk,会单独处理。
- fake chunk 地址需要对齐, MALLOC_ALIGN_MASK
- fake chunk 的 size 大小需要满足对应的 fastbin 的需求,同时也得对齐。
- fake chunk 的 next chunk 的大小不能小于 2 * SIZE_SZ,同时也不能大于av->system_mem 。
- fake chunk 对应的 fastbin 链表头部不能是该 fake chunk,即不能构成 double free 的情况。
1.2演示
github上搜how2heap上面会有相关的演示方式,这里就直接附带viki的链接看一下
1.3解释
注意点1
关键就是要让我们修改的目标地址(不可控区域)的前后内容可以修改以达到绕过检测的目的
(骗堆管理器觉得我们要修改的区域是一个chunk
这里的不可控区域多为函数指针或者或返回地址等
3、Alloc to Stack和Arbitrary Alloc
这个和上面两种的思路差不多,核心都是修改到一个你想要的地方