mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
113 lines
5.6 KiB
Markdown
113 lines
5.6 KiB
Markdown
# 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}}
|