House Of Orange
House Of Orange 的利用比较特殊(题目中不存在 free 函数或其他释放堆块的函数 )
House Of Orange 核心就是通过漏洞利用获得 free 的效果
这种操作的原理简单来说是当前堆的 top chunk 尺寸不足以满足申请分配的大小的时候,原来的 top chunk 会被释放并被置入 unsorted bin 中,通过这一点可以在没有 free 函数情况下获取到 unsorted bins
然后利用 unsorted bin attack 结合 FSOP(也就是通过修改 IO_list_all 劫持到伪造的 IO_FILE 结构上)从而getshell
House Of Orange 利用姿势
1 |
|
申请 “0x2000” 字节后:
1 | Free chunk (unsortedbin) | PREV_INUSE |
申请 “0x60” 字节后:
1 | Allocated chunk | PREV_INUSE |
直接在 top chunk 中向上申请了( libc-2.27 和 libc-2.31 直接挂掉)
伪造的 top chunk size 的要求 :
- 伪造的 size 必须要对齐到内存页(0x0fe1、0x1fe1、0x2fe1、0x3fe)
- size 要大于 MINSIZE(0x10)
- size 要小于之后申请的 chunk size + MINSIZE(0X10)
- size 的 prev inuse 位必须为“1”
伪造 top chunk size 时,需要保持最后3字节与GDB中显示的真正 top chunk size 一致
利用条件:
- 有堆溢出(溢出得足够多,至少可以修改 top chunk size)
- 可以申请较大的空间
- 没有释放模块(看见程序没有 free,realloc等函数时,优先考虑打House Of Orange)
后续可以配合 unsortedbin attack 和 FSOP 获取 shell,简略过程为:
- 利用 unsortedbin attack 在 _IO_list_all 中写入 main_arean + 88
- 如果把 main_arean + 88 当成一个 IO_FILE 结构体,那么
struct _IO_FILE *_chain
指针的地址为 main_arena + 88 + 0x68(main_arena+0xc0) - 而 main_arena + 0xc0 中存储有大小为“0x60”的 smallbin 中第一个 chunk 的地址
- 如果可以在大小为“0x60”的第一个 small chunk 中伪造 IO_FILE 结构体
详细过程在分析 FSOP 时说明
版本对 House Of Orange 的影响
libc-2.23
House Of Orange 适用于 libc-2.23 及之前的版本,libc-2.24 版本增加了 vtable check,但仍然可以绕过,libc-2.27 及之后的版本取消了 abort 刷新流的操作,所以这个方法基本就失效了
libc-2.24
1 | /* Perform vtable pointer validation. If validation fails, terminate |
IO_validate_vtable
要求我们的vtable
必须在__stop___libc_IO_vtables
和__start___libc_IO_vtables
之间,这就意味着我们不能利用任意地址来充当vtable
libc-2.27(完全失效)