Skip to content

Commit 878a505

Browse files
authored
Merge pull request #1803 from HackTricks-wiki/research_update_src_binary-exploitation_libc-heap_house-of-spirit_20260124_125257
Research Update Enhanced src/binary-exploitation/libc-heap/h...
2 parents db348a7 + d51bdb1 commit 878a505

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

src/binary-exploitation/libc-heap/house-of-spirit.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ int main() {
6464
### Requirements
6565

6666
- This attack requires an attacker to be able to create a couple of fake fast chunks indicating correctly the size value of it and then to be able to free the first fake chunk so it gets into the bin.
67+
- With **tcache (glibc ≥2.26)** the attack is even simpler: only one fake chunk is needed (no next-chunk size check is performed on the tcache path) as long as the fake chunk is 0x10-aligned and its size field falls in a valid tcache bin (0x20-0x410 on x64).
6768

6869
### Attack
6970

@@ -72,6 +73,9 @@ int main() {
7273

7374
**The code from** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) **is great to understand the attack.** Although this schema from the code summarises it pretty good:
7475

76+
<details>
77+
<summary>Fake chunk layout</summary>
78+
7579
```c
7680
/*
7781
this will be the structure of our two fake chunks:
@@ -96,9 +100,30 @@ int main() {
96100
*/
97101
```
98102

103+
</details>
104+
99105
> [!TIP]
100106
> Note that it's necessary to create the second chunk in order to bypass some sanity checks.
101107
108+
### Tcache house of spirit (glibc ≥2.26)
109+
110+
- On modern glibc the **tcache fast-path** calls `tcache_put` before validating the next chunk size/`prev_inuse`, so only the current fake chunk has to look sane.
111+
- Requirements:
112+
- Fake chunk must be **16-byte aligned** and not marked `IS_MMAPPED`/`NON_MAIN_ARENA`.
113+
- `size` must belong to a tcache bin and include the **prev_inuse bit set** (`size | 1`).
114+
- Tcache for that bin must not be full (default max 7 entries).
115+
- Minimal PoC (stack chunk):
116+
```c
117+
unsigned long long fake[6] __attribute__((aligned(0x10)));
118+
// chunk header at fake[0]; usable data starts at fake+2
119+
fake[1] = 0x41; // fake size (0x40 bin, prev_inuse=1)
120+
void *p = &fake[2]; // points inside fake chunk
121+
free(p); // goes straight into tcache
122+
void *q = malloc(0x30); // returns stack address fake+2
123+
```
124+
- **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.
125+
- This variant is handy when glibc hooks were removed (≥2.34) and you want a fast arbitrary write or to overlap a target buffer (e.g., stack/BSS) with a tcache chunk without creating additional corruptions.
126+
102127
## Examples
103128
104129
- **CTF** [**https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html**](https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html)
@@ -114,8 +139,6 @@ int main() {
114139
## References
115140
116141
- [https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit](https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit)
142+
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.34/tcache_house_of_spirit.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.34/tcache_house_of_spirit.c)
117143
118144
{{#include ../../banners/hacktricks-training.md}}
119-
120-
121-

0 commit comments

Comments
 (0)