# House of Roman {{#include ../../banners/hacktricks-training.md}} ## 基本信息 这是一种非常有趣的技术,允许通过假快块、未排序的 bin 攻击和相对覆盖来实现 RCE,而无需泄漏。然而,它已经被 [**修补**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)。 ### 代码 - 你可以在 [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c) 找到一个示例 ### 目标 - 通过滥用相对指针实现 RCE ### 要求 - 编辑快块和未排序 bin 指针 - 必须暴力破解 12 位随机数(0.02% 的成功率) ## 攻击步骤 ### 第 1 部分:快块指向 \_\_malloc_hook 创建几个块: - `fastbin_victim` (0x60, 偏移 0): UAF 块,稍后编辑堆指针以指向 LibC 值。 - `chunk2` (0x80, 偏移 0x70): 用于良好的对齐 - `main_arena_use` (0x80, 偏移 0x100) - `relative_offset_heap` (0x60, 偏移 0x190): 在 'main_arena_use' 块上的相对偏移 然后 `free(main_arena_use)`,这将把这个块放入未排序列表,并在 `fd` 和 `bk` 指针中获取指向 `main_arena + 0x68` 的指针。 现在分配一个新的块 `fake_libc_chunk(0x60)`,因为它将包含指向 `main_arena + 0x68` 的指针在 `fd` 和 `bk` 中。 然后 `relative_offset_heap` 和 `fastbin_victim` 被释放。 ```c /* 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_victim` 有一个指向 `relative_offset_heap` 的 `fd` - `relative_offset_heap` 是从 `fake_libc_chunk` 的距离偏移量,其中包含指向 `main_arena + 0x68` 的指针 - 只需更改 `fastbin_victim.fd` 的最后一个字节,就可以使 `fastbin_victim points` 指向 `main_arena + 0x68` 对于之前的操作,攻击者需要能够修改 `fastbin_victim` 的 fd 指针。 然后,`main_arena + 0x68` 并不是那么有趣,所以让我们修改它,使指针指向 **`__malloc_hook`**。 请注意,`__memalign_hook` 通常以 `0x7f` 开头,并且在它之前是零,因此可以将其伪装为 `0x70` 快速堆中的一个值。由于地址的最后 4 位是 **随机** 的,因此有 `2^4=16` 种可能性使值最终指向我们感兴趣的地方。因此在这里执行 BF 攻击,使得块最终变成:**`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`。** (有关其余字节的更多信息,请查看 [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ 示例](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c) 中的解释)。如果 BF 不起作用,程序就会崩溃(所以重新开始,直到它有效)。 然后,执行 2 次 malloc 以移除 2 个初始快速堆块,并分配第三个以获取一个块在 **`__malloc_hook:`** 中。 ```c malloc(0x60); malloc(0x60); uint8_t* malloc_hook_chunk = malloc(0x60); ``` ### Part 2: Unsorted_bin 攻击 有关更多信息,请查看: {{#ref}} unsorted-bin-attack.md {{#endref}} 但基本上,它允许将 `main_arena + 0x68` 写入 `chunk->bk` 指定的任何位置。对于攻击,我们选择 `__malloc_hook`。然后,在覆盖它之后,我们将使用相对覆盖来指向 `one_gadget`。 为此,我们开始获取一个 chunk 并将其放入 **unsorted bin**: ```c 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); ``` 在这个块中使用 UAF 将 `unsorted_bin_ptr->bk` 指向 `__malloc_hook` 的地址(我们之前已经暴力破解过这个)。 > [!CAUTION] > 请注意,这个攻击会破坏未排序的 bin(因此小和大也会受到影响)。所以我们现在只能**使用快速 bin 的分配**(一个更复杂的程序可能会进行其他分配并崩溃),并且为了触发这一点,我们必须**分配相同的大小,否则程序将崩溃。** 因此,为了触发 `__malloc_hook` 中 `main_arena + 0x68` 的写入,在将 `__malloc_hook` 设置在 `unsorted_bin_ptr->bk` 后,我们只需要执行:**`malloc(0x80)`** ### 第 3 步:将 \_\_malloc_hook 设置为 system 在第一步中,我们控制了一个包含 `__malloc_hook` 的块(在变量 `malloc_hook_chunk` 中),在第二步中,我们成功地在这里写入了 `main_arena + 0x68`。 现在,我们利用 `malloc_hook_chunk` 中的部分覆盖,使用我们在这里写入的 libc 地址(`main_arena + 0x68`)来**指向一个 `one_gadget` 地址**。 在这里需要**暴力破解 12 位随机数**(更多信息请参见 [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ 示例](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c))。 最后,一旦正确的地址被覆盖,**调用 `malloc` 并触发 `one_gadget`**。 ## 参考文献 - [https://github.com/shellphish/how2heap](https://github.com/shellphish/how2heap) - [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c) - [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/) {{#include ../../banners/hacktricks-training.md}}