Athena Wiki

House of Series

pwnadvanced

Overview of classic and modern heap exploitation techniques - House of Force, Spirit, Apple, and more.

pwnheaphouse-of-forcehouse-of-spirithouse-of-appleglibcexploitation

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:

Mermaid diagram

Version Compatibility

Techniqueglibc VersionWhat It Does
House of Force< 2.29Overflow top chunk size → allocate at any address
House of SpiritAnyFree a fake chunk → get it back via bin
House of Botcake2.27+Double-free via unsorted bin + tcache interaction
House of Orange< 2.26Unsorted bin attack → trigger FSOP
House of Roman2.23–2.27Partial overwrite without full leaks
House of Lore< 2.26Corrupt smallbin fd/bk
House of Apple (1/2/3)2.34+FSOP without hooks (modern glibc)
House of Tangerine2.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_gadget

On 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 + 0x10

Useful 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:

  1. Fill tcache (7 chunks)
  2. Free chunk A → unsorted bin (tcache full)
  3. Free chunk B → tcache (1 slot opens)
  4. Allocate 1 from tcache
  5. 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:

  1. An arbitrary write primitive
  2. A heap or libc leak
  3. Building a fake _IO_FILE struct with specific fields set

For implementation, refer to established writeups and PoC scripts. The key references:

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:

  1. Get arbitrary write (tcache poisoning)
  2. Overwrite __free_hook with system
  3. 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


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

On this page