House Of Spirit
House Of Spirit 是 Fastbin Attack
中的一种,也是 the Malloc Maleficarum
中的一种技术
通过free技术来达到任意地址读写的目的(WAA):技术中利用free函数来释放一个原本属于栈中的一块地址(伪造为 fake chunk ),将地址free到堆的bin链中,然后实现对栈地址的读写
// 当然也可以不在栈中,任意可写的段都可以
Fastbin检查机制
- 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 的情况
主要是检查当前chunk的size,和下一个chunk的size
House Of Spirit 利用姿势
1 |
|
1 | fake_chunks: 0x7fffffffdcc0 |
可以发现:函数“free”把栈上的“fake_chunks”送入了“tcachebins”
1 | pwndbg> bins |
// 这里的“fake_chunks”被送入了“tcachebins”,如果是低libc版本就送入“fastbins”
house of spirit 简单的来说就是 free 一个假的 fastbin 堆块,然后再下次 malloc 的时候就会返回该假堆块
利用条件:
- 需要修改模块,不需要控制free模块的参数:申请到堆上,把目标地址写入修改模块的控制范围
- 需要控制free模块的参数,不需要修改模块:申请到栈上,用目标地址覆盖返回地址
- 在“计数器”后面存在可以控制的区域,同时修改模块也可以在此处写入内容(也可以获取现成的数字)
版本对 House Of Spirit 的影响
不同 libc 的版本“释放检查”不同,像 libc-2.23 就只有上文的两个检查,后续会尽量把不同版本的 House Of Spirit 都复现一遍,直到完全没法打为止
libc-2.23
上文提到的,基本的 free 检查
1 | //检查p的大小是否小于global_max_fast |
libc-2.27
多了一个检查
1 | if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0) |
检查下一个 chunk 的 pre_size 是否为 NULL,一般在伪造 size 的时候多写一步就可以了
后续版本都没有添加新的检查(最新测试到 libc-2.31)
注意
在64位的程序中:可以轻易实现 House Of Spirit(至少在 libc-2.31及其之前的版本是这样)
但是在32位的程序中:只有在 libc-2.23 版本成功实现 House Of Spirit,其他版本均报错
1 | free():invalid pointer |
看了源码,定位了报错的位置,但是还是不知道原因……