fastbin attack
[TOC] 核心: 1.存在堆溢出、use-after-free 等能控制 chunk 内容的漏洞 2.漏洞发生于 fastbin 类型的 chunk 中 3.fastbin的单项链表结构,fd指针的运用
double free
核心是绕过double free
- double_free的基本原理: fastbins 可以看成一个 LIFO 的栈,使用单链表实现,通过 fastbin->fd 来遍历 fastbins。由于 free 的过程会对 free list 做检查,我们不能连续两次 free 同一个 chunk,所以这里在两次 free 之间,增加了一次对其他 chunk 的 free 过程,从而绕过检查顺利执行。然后再 malloc 三次,就有了两个指向同一块内存区域的指针。
- double_free的检查机制:
old就是fastbin头部的chunk
从fastbin取出一个chunk要判断其大小是否对应idx
- 总结:通过 fastbin double free 我们可以使用多个指针控制同一个堆块,这可以用于篡改一些堆块中的关键数据域或者是实现类似于类型混淆的效果。 如果更进一步修改 fd 指针,则能够实现任意地址分配堆块的效果 (首先要通过验证),这就相当于任意地址写任意值的效果。
house of spirit
核心是free的chunk是个fastbin chunk的样子,因此要进行伪造 可以参考这篇文章
- house-of-spirit 是一种通过堆的 fast bin 机制来辅助栈溢出的方法,一般的栈溢出漏洞的利用都希望能够覆盖函数的返回地址以控制 EIP 来劫持控制流,但如果栈溢出的长度无法覆盖返回地址,同时却可以覆盖栈上的一个即将被 free 的堆指针,此时可以将这个指针改写为栈上的地址并在相应位置构造一个 fast bin 块的元数据,接着在 free 操作时,这个栈上的堆块被放到 fast bin 中,下一次 malloc 对应的大小时,由于 fast bin 的先进后出机制,这个栈上的堆块被返回给用户,再次写入时就可能造成返回地址的改写。
- 要绕过的检测: 1.fake chunk 的 ISMMAP 位不能为 1,因为 free 时,如果是 mmap 的 chunk,会单独处理。 2.fake chunk 地址需要对齐, MALLOC_ALIGN_MASK 3.fake chunk 的 size 大小需要满足对应的 fastbin 的需求,同时也得对齐。 4.fake chunk 的 next chunk 的大小不能小于 2 * SIZE_SZ,同时也不能大于av->system_mem 。 5.fake chunk 对应的 fastbin 链表头部不能是该 fake chunk,即不能构成 double free 的情况。
- 总结:1.house of spirit的目的是用fastbin的机制协助进行栈溢出,所以利用的第一步不是去控制一个 chunk,而是控制传给 free 函数的指针,将其指向一个 fake chunk,所以 fake chunk 的伪造是关键。2.技术的缺点也是需要对栈地址进行泄漏,否则无法正确覆盖需要释放的堆指针,且在构造数据时,需要满足对齐的要求等 3.想要使用该技术分配 chunk 到指定地址,其实并不需要修改指定地址的任何内容,关键是要能够修改指定地址的前后的内容使其可以绕过对应的检测
针对how2heap的笔记
alloc to stack
核心是修改chunk的fd指针指向一个伪造的fastbin chunk(fake chunk可以在栈上),那么就可以malloc到fake chunk的位置
- 本质都在于 fastbin 链表的特性:当前 chunk 的 fd 指针指向下一个 chunk。该技术的核心点在于劫持 fastbin 链表中 chunk 的 fd 指针,把 fd 指针指向我们想要分配的栈上,从而实现控制栈中的一些关键数据,比如返回地址等
- 总结:通过该技术我们可以把 fastbin chunk 分配到栈中,从而控制返回地址等关键数据。要实现这一点我们需要劫持 fastbin 中 chunk 的 fd 域,把它指到栈上,当然同时需要栈上存在有满足条件的size值
arbitrary alloc
核心和alloc to stack一样
- arbitrary alloc 其实与 alloc to stack 是完全相同的,唯一的区别是分配的目标不再是栈中。 事实上只要满足目标地址存在合法的 size 域(这个 size 域是构造的,还是自然存在的都无妨),我们可以把 chunk 分配到任意的可写内存中,比如 bss、heap、data、stack 等等
- 总结:可以利用字节错位等方法来绕过 size 域的检验,实现任意地址分配 chunk,最后的效果也就相当于任意地址写任意值