1 |
|
0x01 malloc(1)
1 | pwndbg> heap |
0x02:unsigned long long fake_chunks[10] attribute ((aligned (16)));
这步操作怎么肥四噢?1
2
3
4pwndbg> p &fake_chunks
$7 = (unsigned long long (*)[10]) 0x7fffffffde40
pwndbg> p fake_chunks
$8 = {0xff00000000, 0xff00, 0x0, 0x0, 0x1, 0x4008ed, 0x0, 0x0, 0x4008a0, 0x4005b0}
fakechunk的地址在栈上
0x03:构造一个fastbin
1 | fake_chunks[1] = 0x40; // this is the size |
0x04:
1 | a = &fake_chunks[2]; |
0x06malloc(0x30)
1 | 输出:malloc(0x30): 0x7fffffffde50 |
返回了栈上的地址
0x07总结
伪造一个fake_fastbin,注意这个fake_chunk的大小,要在fastbins里,太大不会被丢到fastbins里
伪造的fast_chunk被丢到对应的fastbins里去之后再申请对应大小的空间,申请的是这个被丢进来的fast_chunk。
通过构造 fake chunk,然后将其 free
掉,就可以在下一次 malloc 时返回 fake chunk 的地址,即任意我们可控的区域。
house-of-spirit 是一种通过堆的 fast bin 机制来==辅助栈溢出==的方法,一般的栈溢出漏
洞的利用都希望能够覆盖函数的返回地址以控制 EIP 来劫持控制流,但如果栈溢出
的长度无法覆盖返回地址,同时却可以覆盖栈上的一个即将被 free 的堆指针,此时
可以将这个指针改写为栈上的地址并在相应位置构造一个 fast bin 块的元数据,接
着在 free 操作时,这个栈上的堆块被放到 fast bin 中,下一次 malloc 对应的大小
时,由于 fast bin 的先进后出机制,这个栈上的堆块被返回给用户,再次写入时就
可能造成返回地址的改写。
。所以利用的第一步不是去控制一个 chunk,而是==控制传
给 free 函数的指针==,将其指向一个 fake chunk。所以== fake chunk 的伪造是关键==。
首先 malloc(1) 用于初始化内存环境,然后在 fake chunk 区域伪造出两个 chunk。
另外正如上面所说的,==需要一个传递给 free 函数的可以被修改的指针==,无论是通过
栈溢出还是其它什么方式
PREV_INUSE 位并不影响 free
的过程,但 ==IS_MMAPPED 位和 NON_MAIN_ARENA 位都要为零==。其次,在 64 位 系统中fast chunk的大小要在32~128字节之间。最后,是next chunk的大小,必须大于2*SIZE_SZ(即大于16),小于av->system_mem (即小于128kb),才能绕过对 next chunk 大小的检查。