House of Roman

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

Basic Information

这是一种非常有趣的技术,通过 fake fastbins、unsorted_bin attack 和 relative overwrites 在没有 leaks 的情况下实现 RCE。然而它已被 patched

Applicability in 2026

  • glibc window:2.23–2.27 上可靠工作(how2heap PoC 在 2.23–2.25 上测试)。从 2.28 开始,“additional checks for unsorted bin integrity” 补丁使得 unsorted‑bin 的写入变得不可靠,因此成功率大幅下降。从 2.34 起删除了 __malloc_hook/__free_hook,使得原始目标不可用。仅在旧的 libc(或保留这些 hooks 的自定义构建)或随附旧 libc 的 CTF 题目上使用。
  • Tcache era (≥2.26): Tcache 会吞掉你的 0x70 allocations 并阻止 fastbin/unsorted 原语。在任何分配之前禁用它(setenv("GLIBC_TUNABLES","glibc.malloc.tcache_count=0",1);)或向每个 0x70 tcache bin 填充 7 次 free 来清空它。
  • Safe-linking: 它适用于 ≥2.32 的 tcache/fastbin,但 House of Roman 只需要对已存在于 fd/bk 中的 libc 地址进行 partial pointer overwrite,因此 safe-linking 在这里并不能帮助防御方(攻击者从不伪造新的指针)。真正的阻断因素是 hooks 的移除和 unsorted-bin 的完整性检查。

Code

Goal

  • 通过滥用 relative pointers 实现 RCE

Requirements

  • 编辑 fastbin 和 unsorted bin 指针
  • 需要暴力破解 12 位随机性(约 0.02% 的成功概率)

Attack Steps

Part 1: Fastbin Chunk points to __malloc_hook

Create several chunks:

  • fastbin_victim (0x60, offset 0): UAF chunk,稍后用于编辑 heap pointer,使其指向 libc 的值。
  • chunk2 (0x80, offset 0x70): 用于良好对齐
  • main_arena_use (0x80, offset 0x100)
  • relative_offset_heap (0x60, offset 0x190): 位于 main_arena_use chunk 上的相对偏移

然后执行 free(main_arena_use),该操作会将此 chunk 放入 unsorted 列表,并在 fdbk 指针中得到指向 main_arena + 0x68 的指针。

现在分配一个新的 chunk fake_libc_chunk(0x60),因为它将包含指向 main_arena + 0x68fdbk 指针。

随后释放 relative_offset_heapfastbin_victim

/*
Current heap layout:
0x0:   fastbin_victim       - size 0x70
0x70:  alignment_filler     - size 0x90
0x100: fake_libc_chunk      - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main        - size 0x20
0x190: relative_offset_heap - size 0x70

bin layout:
fastbin:  fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
  • fastbin_victimfd 指向 relative_offset_heap
  • relative_offset_heap 是相对于 fake_libc_chunk 的偏移,fake_libc_chunk 包含一个指向 main_arena + 0x68 的指针
  • 修改 fastbin_victim.fd 的最后一个字节会使 fastbin_victim 指向 main_arena + 0x68

要做上面的操作,攻击者需要能够修改 fastbin_victim 的 fd 指针。

然而,main_arena + 0x68 并不那么有用,所以把它修改为指向 __malloc_hook

注意 __memalign_hook 通常以 0x7f 开头并且前面为零,所以有可能把它伪造为 0x70 fast bin 中的一个值。因为地址的最后 4 位是 随机,有 2^4=16 种可能使值最终指向我们关注的位置。因此在这里执行一个 BF 攻击,使 chunk 结尾像:0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)

(For more info about the rest of the bytes check the explanation in the how2heap example). If the brute force fails the program just crashes (restart until it works).

然后,执行 2 次 malloc 来移除最初的 2 个 fast bin chunks,第三次分配会得到一个位于 __malloc_hook 的 chunk。

malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);

第2部分:Unsorted_bin attack

更多信息请查看:

Unsorted Bin Attack

但基本上它允许将 main_arena + 0x68 写入到 chunk->bk 指定的任何位置。对于攻击我们选择 __malloc_hook。然后,在覆盖它之后我们将使用相对覆盖将其指向 one_gadget

为此我们先获取一个 chunk 并将其放入 unsorted bin

uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate

puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);

Use an UAF in this chunk to point unsorted_bin_ptr->bk to the address of __malloc_hook (we brute forced this previously).

Caution

注意该攻击会破坏 unsorted bin(因此也会影响 small 和 large)。所以我们现在只能 use allocations from the fast bin now(更复杂的程序可能会有其他分配并崩溃),并且要触发这一点我们必须 alloc the same size or the program will crash.

So, to trigger the write of main_arena + 0x68 in __malloc_hook we perform after setting __malloc_hook in unsorted_bin_ptr->bk we just need to do: malloc(0x80)

步骤 3:将 __malloc_hook 设置为 system

在第一步中我们控制了一个包含 __malloc_hook 的 chunk(变量为 malloc_hook_chunk),在第二步我们设法在那里写入了 main_arena + 0x68

现在,我们滥用对 malloc_hook_chunk 的部分覆盖,利用我们写入的 libc 地址(main_arena + 0x68)去指向一个 one_gadget 地址

这里需要暴力猜测 12 位随机性(更多信息见 how2heap 的示例)。

最后,一旦正确的地址被覆盖,调用 malloc 并触发 one_gadget

现代提示与变体

  • Unsorted-bin hardening (2.28+): 对 unsorted chunks 的额外完整性检查(大小合理性 + 链表链接)使得经典的 unsorted‑bin 写入变得脆弱。要通过 _int_malloc,你必须保持 fd/bk 链接一致且大小合理,这通常需要比简单的 partial overwrite 更强的原语。
  • Hook removal (2.34+): 随着 __malloc_hook 被移除,将原语改为落在任何你稍后可重用的可写 GOT/global(例如在非-PIE 二进制中覆盖 exit@GOT),或转而使用 House of Pie 风格的 top‑chunk 劫持来控制 top 而不是 hook。
  • Any‑address fastbin alloc (romanking98 writeup): 第二部分展示了修复 0x71 freelist 并利用 unsorted‑bin 写入使 fastbin 分配落在 __free_hook 上,然后放置 system("/bin/sh") 并在 libc‑2.24(hook 移除前)通过 free() 触发它。

参考资料

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks