glibc2.23——house of orange
字数 1767 2025-08-29 08:30:05
House of Orange 攻击技术详解
概述
House of Orange 是一种针对 glibc 堆管理机制的利用技术,最初来源于 2016 年一道名为 "orange" 的 CTF 题目。该技术主要用于在程序限制堆块申请或缺乏 free 功能的情况下,实现 libc 地址泄露和最终获取 shell 的目的。
技术背景
适用版本
- 主要针对 glibc 2.23 及更早版本
- 2.23 以后版本对 vtable 检查更加严格,增加了利用难度
典型应用场景
- 程序限制了堆块申请大小(无法直接申请到 unsortbin)
- 程序没有提供显式的 free 功能
- 需要绕过某些安全限制获取 shell
攻击流程
第一阶段:获取 libc 地址
核心思想
通过修改 top chunk 的 size 字段,强制将 top chunk 放入 unsortbin 中。
具体步骤
- 控制 top chunk 的 size 字段:通过堆溢出或其他方式修改 top chunk 的 size
- 满足三个关键条件:
(unsigned long)(old_size) >= MINSIZEprev_inuse(old_top) = 1((unsigned long)old_end & (pagesize - 1)) == 0(页对齐)
- 申请大堆块:申请一个比修改后 top chunk size 更大的堆块
- 这将导致原 top chunk 被放入 unsortbin
- 注意避免触发 mmap 分配
示例
原 top chunk size 为 0x2fe1,可修改为 0xfe1(保持页对齐)
第二阶段:获取堆地址(2.23 以前版本需要)
方法一:largebin 泄露
- 申请 largebin 范围内的堆块
- 利用 largebin 的 fd_nextsize 泄露堆地址
方法二:unsortbin attack
- 如果程序未开启 PIE 或已知程序基地址
- 堆块指针保存在 bss 段上时可用
- 通过 unsortbin attack 泄露堆地址
第三阶段:劫持 IO 流
关键函数链
malloc_printerr -> __libc_message -> __GI_abort -> _IO_flush_all_lockp -> _IO_OVERFLOW
核心结构
- _IO_FILE_plus 结构体:
- 继承自 _IO_FILE
- 包含 _IO_jump_t 类型指针(虚函数表 vtable)
- _IO_list_all:
- 指向 IO_2_1_stderr
- 需要劫持的目标
关键偏移
- vtable 偏移:0xd8(64位)
- chain 字段偏移:0x68
利用步骤
- 伪造 unsortbin:
- 修改 unsortbin 的 size 为 0x61
- 将 unsortbin 的 bk 字段改为 _IO_list_all - 0x10
- 触发 unsortbin attack:
- 使 _IO_list_all 指向 main_arena + 88
- 伪造 IO 结构:
- 在 smallbin[6](main_arena + 0xc0)处伪造 vtable
- 设置 _IO_write_ptr > _IO_write_base 绕过 fflush 检查
- 设置 vtable:
- 将 _IO_overflow(vtable 第4项)替换为 system
- 将 fd 指针设置为 "/bin/sh"
例题分析
题目特征
- 64位程序
- 没有 free 功能
- 允许申请大堆块
- 存在堆溢出漏洞
- 未开启 PIE
利用思路
- 使用 house of orange 泄露 libc 地址
- 通过 unsortbin attack 泄露堆地址
- 利用堆溢出劫持 IO 流
- 触发 malloc 错误执行 shell
防御措施
- 升级 glibc 版本(2.24+ 对 vtable 有更严格检查)
- 启用所有保护机制(ASLR, PIE, etc.)
- 严格检查堆操作边界
- 避免在堆中存储敏感指针
总结
House of Orange 是一种高级堆利用技术,通过精心构造堆布局和伪造 IO 结构,实现在受限环境下的代码执行。理解该技术需要对 glibc 的堆管理和 IO 子系统有深入认识。随着 glibc 版本的更新,该技术的利用条件变得更加苛刻,但在特定环境下仍具有实用价值。