mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
76 lines
5.9 KiB
Markdown
76 lines
5.9 KiB
Markdown
# House of Orange
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## 基本信息
|
||
|
||
### 代码
|
||
|
||
- 在 [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c) 找到一个示例
|
||
- 该利用技术在这个 [补丁](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) 中被修复,因此现在不再有效(在 2.26 之前有效)
|
||
- 同样的示例 **带有更多注释** 在 [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
|
||
|
||
### 目标
|
||
|
||
- 滥用 `malloc_printerr` 函数
|
||
|
||
### 要求
|
||
|
||
- 覆盖顶部块大小
|
||
- Libc 和堆泄漏
|
||
|
||
### 背景
|
||
|
||
一些来自 [**这个示例**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)** 的必要背景:**
|
||
|
||
问题是,在旧版本的 libc 中,当调用 `malloc_printerr` 函数时,它会 **遍历存储在 `_IO_list_all` 中的 `_IO_FILE` 结构的列表**,并实际 **执行** 该结构中的指令指针。\
|
||
这个攻击将伪造一个 **假的 `_IO_FILE` 结构**,我们将写入 **`_IO_list_all`**,并导致 `malloc_printerr` 运行。\
|
||
然后它将 **执行我们在 `_IO_FILE` 结构跳转表中存储的任何地址**,我们将获得代码执行。
|
||
|
||
### 攻击
|
||
|
||
攻击开始于成功获取 **未排序的块** 中的 **顶部块**。这是通过调用 `malloc`,其大小大于当前顶部块大小但小于 **`mmp_.mmap_threshold`**(默认是 128K)来实现的,否则会触发 `mmap` 分配。每当顶部块大小被修改时,确保 **顶部块 + 其大小** 是页面对齐的,并且顶部块的 **prev_inuse** 位始终被设置是很重要的。
|
||
|
||
为了获取未排序块中的顶部块,分配一个块以创建顶部块,改变顶部块大小(通过分配的块中的溢出),使得 **顶部块 + 大小** 与 **prev_inuse** 位设置为页面对齐。然后分配一个大于新顶部块大小的块。请注意,`free` 从未被调用以将顶部块放入未排序块中。
|
||
|
||
旧的顶部块现在在未排序块中。假设我们可以读取其中的数据(可能是由于导致溢出的漏洞),可以从中泄漏 libc 地址并获取 **\_IO_list_all** 的地址。
|
||
|
||
通过滥用溢出写入 `topChunk->bk->fwd = _IO_list_all - 0x10` 来执行未排序块攻击。当分配一个新块时,旧的顶部块将被拆分,并且指向未排序块的指针将被写入 **`_IO_list_all`**。
|
||
|
||
下一步是将旧顶部块的大小缩小以适应小块,特别是将其大小设置为 **0x61**。这有两个目的:
|
||
|
||
1. **插入到小块 4**:当 `malloc` 扫描未排序块并看到这个块时,由于其小尺寸,它将尝试将其插入到小块 4。这使得该块最终位于小块 4 列表的头部,这是我们通过未排序块攻击在 **`_IO_list_all`** 中写入的块的 FD 指针的位置。
|
||
2. **触发 malloc 检查**:这个块大小的操作将导致 `malloc` 执行内部检查。当它检查虚假前向块的大小时,该大小将为零,触发错误并调用 `malloc_printerr`。
|
||
|
||
小块的操作将允许你控制块的前向指针。与 **\_IO_list_all** 的重叠用于伪造一个假的 **\_IO_FILE** 结构。该结构经过精心设计,以包含关键字段,如 `_IO_write_base` 和 `_IO_write_ptr`,设置为通过 libc 内部检查的值。此外,在假结构中创建一个跳转表,其中指令指针设置为可以执行任意代码的地址(例如,`system` 函数)。
|
||
|
||
总结该技术的其余部分:
|
||
|
||
- **缩小旧顶部块**:将旧顶部块的大小调整为 **0x61** 以适应小块。
|
||
- **设置假的 `_IO_FILE` 结构**:将旧顶部块与假的 **\_IO_FILE** 结构重叠,并适当地设置字段以劫持执行流。
|
||
|
||
下一步涉及伪造一个与当前在未排序块中的旧顶部块重叠的假 **\_IO_FILE** 结构。该结构的前几个字节经过精心设计,以包含指向将被执行的命令(例如,"/bin/sh")的指针。
|
||
|
||
假 **\_IO_FILE** 结构中的关键字段,如 `_IO_write_base` 和 `_IO_write_ptr`,被设置为通过 libc 内部检查的值。此外,在假结构中创建一个跳转表,其中指令指针设置为可以执行任意代码的地址。通常,这将是 `system` 函数的地址或其他可以执行 shell 命令的函数。
|
||
|
||
当调用 `malloc` 触发通过操控的 **\_IO_FILE** 结构执行代码时,攻击达到高潮。这有效地允许任意代码执行,通常导致生成一个 shell 或执行其他恶意负载。
|
||
|
||
**攻击总结:**
|
||
|
||
1. **设置顶部块**:分配一个块并修改顶部块大小。
|
||
2. **强制顶部块进入未排序块**:分配一个更大的块。
|
||
3. **泄漏 libc 地址**:利用漏洞从未排序块读取。
|
||
4. **执行未排序块攻击**:使用溢出写入 **\_IO_list_all**。
|
||
5. **缩小旧顶部块**:调整其大小以适应小块。
|
||
6. **设置假 \_IO_FILE 结构**:伪造假文件结构以劫持控制流。
|
||
7. **触发代码执行**:分配一个块以执行攻击并运行任意代码。
|
||
|
||
这种方法利用堆管理机制、libc 信息泄漏和堆溢出来实现代码执行,而无需直接调用 `free`。通过精心构造假 **\_IO_FILE** 结构并将其放置在正确的位置,攻击可以在标准内存分配操作期间劫持控制流。这使得执行任意代码成为可能,可能导致生成 shell 或其他恶意活动。
|
||
|
||
## 参考
|
||
|
||
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/)
|
||
- [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|