Hacktricks-skills house-of-lore-exploit
How to perform a House of Lore (small bin attack) heap exploitation. Use this skill whenever the user mentions heap exploitation, small bin attacks, fake chunks, glibc heap vulnerabilities, or needs to insert fake chunks into small bins for arbitrary read/write. Trigger for CTF challenges involving heap corruption, glibc 2.31+ exploitation, or when the user needs to bypass malloc sanity checks using fake chunk linking.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/binary-exploitation/libc-heap/house-of-lore/SKILL.MDHouse of Lore Exploit (Small Bin Attack)
A heap exploitation technique that inserts fake small chunks into the small bin to gain arbitrary read/write capabilities.
What This Attack Does
Inserts a fake small chunk into the small bin so it can be allocated, allowing you to read/write pointers inside it. The fake chunk is attacker-controlled, not a legitimate freed chunk.
Requirements
You need:
- A small chunk vulnerability - ability to free and reallocate small chunks
- A pointer write primitive - to modify
to point to your fake chunklegit.fd - glibc 2.31+ - this attack targets the small bin management
- Two fake chunks - properly linked together and with the legitimate chunk
The Chunk Linking Structure
You must create this exact linking pattern:
fake0.bk -> fake1 fake1.fd -> fake0 fake0.fd -> legit (requires pointer write primitive) legit.bk -> fake0
Step-by-Step Attack
Phase 1: Setup the Legitimate Chunk
- Allocate a small chunk (
)legit - Allocate another chunk to prevent consolidation with top chunk
- Free
(moves to unsorted bin)legit - Allocate a larger chunk (moves
to small bin)legit
Phase 2: Create Fake Chunks
Generate two fake chunks with proper metadata:
# Example fake chunk structure (little-endian) fake0 = struct.pack('<QQ', size0, fake1_addr) # size, fd fake0 += struct.pack('<QQ', fake1_addr, 0) # bk, fd_nextsize fake0 += struct.pack('<QQ', 0, 0) # bk_nextsize, padding fake1 = struct.pack('<QQ', size1, fake0_addr) # size, fd fake1 += struct.pack('<QQ', fake0_addr, 0) # bk, fd_nextsize fake1 += struct.pack('<QQ', 0, 0) # bk_nextsize, padding
Key requirements for fake chunks:
must be valid small bin size (typically 0x20-0x100)size
bit must be set (bit 0 of size)PREV_INUSE
andfd
must point to valid heap addressesbk- Chunks must be properly aligned (8-byte on 64-bit)
Phase 3: Link the Chunks
- Write
andfake0
to heap memory (via overflow or other primitive)fake1 - Use your pointer write primitive to set
legit.fd = fake0_addr - Ensure
(may need another write)legit.bk = fake0_addr
Phase 4: Trigger the Exploit
- Allocate a small chunk → gets
, makinglegit
the new head of small binfake0 - Allocate another small chunk → gets
(your fake chunk!)fake0 - Now you can read/write through
to control heap metadatafake0
Common Pitfalls
| Issue | Solution |
|---|---|
| Ensure 8-byte alignment on 64-bit systems |
| Verify size field has PREV_INUSE bit set |
| Don't free chunks that are already in bins |
| Sanity check failures | Double-check all fd/bk pointers are valid heap addresses |
Working Examples
Use these as reference implementations:
- GuyInATuxedo: https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html
- CTF Wiki: https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/
- Heap Exploitation Guide: https://heap-exploitation.dhavalkapil.com/attacks/house_of_lore
Helper Scripts
Use the bundled scripts to generate and verify fake chunks:
# Generate fake chunk metadata python scripts/generate_fake_chunks.py --size 0x20 --addr1 0x555555556000 --addr2 0x555555556100 # Verify linking structure python scripts/verify_linking.py --fake0 0x555555556000 --fake1 0x555555556100 --legit 0x555555556200
When to Use This Attack
- You have a heap overflow that can write to chunk metadata
- You need arbitrary read/write but don't have a direct write primitive
- The target uses glibc 2.31+ with small bins
- Other heap attacks (House of Force, etc.) are blocked by sanity checks
Next Steps After Exploitation
Once you control
fake0:
- Overwrite
/fd
pointers to redirect allocationsbk - Create fake chunks pointing to GOT entries for arbitrary write
- Use
style attacks for code executionunlink() - Combine with other primitives for full RCE