House of Series
Overview of classic and modern heap exploitation techniques - House of Force, Spirit, Apple, and more.
House of Series
The "House of" techniques are named heap exploitation methods, each targeting a specific glibc allocator behavior. They're not a progression — each one solves a different problem or works on a different glibc version.
This page is a reference. For the fundamentals, read Heap Exploitation first. For tcache-specific attacks, see Tcache Poisoning.
Which Technique Do I Need?
The right "House" depends on your glibc version and what primitives you have:
Version Compatibility
| Technique | glibc Version | What It Does |
|---|---|---|
| House of Force | < 2.29 | Overflow top chunk size → allocate at any address |
| House of Spirit | Any | Free a fake chunk → get it back via bin |
| House of Botcake | 2.27+ | Double-free via unsorted bin + tcache interaction |
| House of Orange | < 2.26 | Unsorted bin attack → trigger FSOP |
| House of Roman | 2.23–2.27 | Partial overwrite without full leaks |
| House of Lore | < 2.26 | Corrupt smallbin fd/bk |
| House of Apple (1/2/3) | 2.34+ | FSOP without hooks (modern glibc) |
| House of Tangerine | 2.35+ | Unsorted bin attack variant |
Techniques by Goal
Goal: Arbitrary Allocation (Get malloc to return any address)
House of Force (glibc < 2.29)
Overwrite the top chunk's size to 0xffffffffffffffff, then allocate a carefully sized chunk to move the top chunk pointer to your target. The next malloc returns memory at your target.
Requirement: Overflow into the top chunk size field, heap + libc leaks.
# 1. Corrupt top chunk size
edit(vuln_chunk, b'A' * overflow_len + p64(0xffffffffffffffff))
# 2. Allocate to reposition top chunk
target = libc.sym['__malloc_hook'] - 0x20
delta = target - current_top - 0x10
delta = delta & 0xffffffffffffffff
alloc(delta)
# 3. Next alloc lands on target
alloc(0x20)
edit(new_idx, p64(one_gadget))
alloc(1) # triggers __malloc_hook → one_gadgetOn glibc 2.29+, there's a size check that prevents this. Use Tcache Poisoning instead.
Tcache Poisoning (glibc 2.26+)
The standard technique. Free a chunk, overwrite its fd pointer, allocate twice to get a pointer at your target. See Tcache Poisoning.
Goal: Free a Fake Chunk
House of Spirit
Create a fake chunk at a target address (e.g., on the stack or in .bss), then trick the allocator into freeing it. On the next malloc, you get a pointer to your fake chunk.
# Build fake chunk at target address
fake_chunk = target - 0x10 # chunk header is 0x10 before user data
# Write valid-looking metadata
write(fake_chunk, p64(0)) # prev_size
write(fake_chunk + 8, p64(0x41)) # size (0x40 + PREV_INUSE bit)
write(fake_chunk + 0x40, p64(0)) # next chunk's prev_size
write(fake_chunk + 0x48, p64(0x21)) # next chunk's size
# Free it → goes to tcache/fastbin
free(fake_chunk + 0x10)
# Next alloc of same size returns target
alloc(0x30) # returns target + 0x10Useful when you can write to a known address (stack, .bss) but need heap allocation semantics.
Goal: Double-Free (bypassing glibc checks)
House of Botcake (glibc 2.27+)
Combines tcache and unsorted bin to achieve a double-free when tcache alone blocks it:
- Fill tcache (7 chunks)
- Free chunk A → unsorted bin (tcache full)
- Free chunk B → tcache (1 slot opens)
- Allocate 1 from tcache
- Free A again → A is now in both unsorted bin AND tcache
This gives you overlapping chunks — one controls the other's data.
Goal: Code Execution (glibc 2.34+, no hooks)
In glibc 2.34+, __free_hook and __malloc_hook were removed. You can't just overwrite a hook and wait. You need FSOP (File Stream Oriented Programming).
House of Apple 2 (glibc 2.34+)
Corrupts the _IO_2_1_stderr_ file structure to call _IO_wfile_overflow with controlled arguments when abort() or __assert_fail is triggered. This gives you a controlled function call, which you can chain into system("/bin/sh").
This is complex — it requires:
- An arbitrary write primitive
- A heap or libc leak
- Building a fake
_IO_FILEstruct with specific fields set
For implementation, refer to established writeups and PoC scripts. The key references:
- IO-File-Attack — PoC collection
- how2heap — glibc 2.35 examples
House of Tangerine (glibc 2.35+)
A variant of the unsorted bin attack that works on the latest glibc. Used alongside House of Apple for full exploitation on modern systems.
Goal: Code Execution (glibc < 2.34, with hooks)
Standard approach:
- Get arbitrary write (tcache poisoning)
- Overwrite
__free_hookwithsystem - Allocate chunk, write
"/bin/sh", free it →system("/bin/sh")
This is covered in Tcache Poisoning and Heap Exploitation. No special "House" technique needed — just the basic heap primitives.
Other Techniques (Historical / Niche)
Decision Guide
I have a heap bug. What technique?
1. What glibc version?
→ strings libc.so.6 | grep "GNU C Library"
2. Do I need arbitrary allocation?
→ glibc < 2.29: House of Force (if top chunk overflowable)
→ glibc 2.26+: Tcache poisoning
3. Do I need to free a fake chunk?
→ House of Spirit (any version)
4. Do I need double-free?
→ glibc < 2.29: direct double-free
→ glibc 2.27+: House of Botcake
5. Do I need code execution?
→ glibc < 2.34: overwrite __free_hook with system
→ glibc 2.34+: House of Apple 2 (FSOP)Resources
- shellphish/how2heap — working examples for every technique and glibc version. Clone it, compile each example, and step through in GDB.
- CTF Wiki — Heap Exploitation — Chinese, but excellent diagrams and explanations.
Checklist
- Identify glibc version first
- glibc < 2.29 + top chunk overflow → House of Force
- Need fake chunk free → House of Spirit
- Double-free blocked → House of Botcake
- glibc 2.34+ → House of Apple for FSOP
- Always: get heap + libc leaks first
- Reference how2heap for working PoCs per glibc version
Last updated on