Skip to main content

Overview

The House of Einherjar is an elegant heap exploitation technique that leverages an off-by-one overflow with a null byte to create overlapping chunks. Named after the warriors of Norse mythology, this technique uses a single null byte to achieve powerful control over heap allocations.
This technique is particularly powerful because it only requires a single null byte overflow, one of the most common vulnerability types in C programs.

Glibc Version Compatibility

Ret2 Wargames Practice: Try this technique hands-on at House of Einherjar Interactive Challenge

What This Technique Achieves

The House of Einherjar enables:
  • Chunk overlapping: Create a large chunk that overlaps existing allocations
  • Use-after-free creation: Get malloc to return already-allocated memory
  • Tcache poisoning setup: Use the overlap to corrupt tcache for arbitrary allocation
  • Control flow hijacking: Overwrite function pointers or return addresses

Prerequisites and Constraints

This technique requires:
  1. Off-by-one null byte overflow: Ability to write a single 0x00 byte past a chunk
  2. Heap leak: Must know heap addresses for fake chunk and tcache poisoning
  3. Size control: Target chunk size must have LSB of 0x00 (e.g., 0x100, 0x200)
  4. Tcache bypass: Must fill tcache (7 chunks) to reach unsorted bin
  5. Fake chunk creation: Ability to set up fake chunk metadata

How It Works

1

Create fake chunk

Allocate a chunk and set up fake chunk metadata with self-referential fd/bk pointers.
2

Allocate victim chunks

Allocate chunks ‘b’ and ‘c’ where ‘b’ will overflow into ‘c’.
3

Overflow with null byte

Write a null byte past the end of chunk ‘b’ to clear c’s PREV_INUSE bit.
4

Set fake prev_size

Write a fake prev_size in chunk ‘b’ to point back to fake chunk ‘a’.
5

Fill tcache and free

Fill tcache for size 0xf8, then free chunk ‘c’ to trigger consolidation.
6

Exploit the overlap

Allocate a large chunk covering the overlapping region, then use tcache poisoning.

Complete Source Code

Technical Deep Dive

The Off-By-One Null Byte

The null byte overflow clears the PREV_INUSE bit:
When PREV_INUSE is clear, free() attempts backward consolidation:

Why Size Must End in 0x00

The chunk size must have LSB = 0x01 before overflow:
  • 0x101 -> null byte -> 0x100 ✓
  • 0x111 -> null byte -> 0x110 (changes size, likely crashes) ✗
Size values that work:
  • 0x101 (request 0xf8)
  • 0x201 (request 0x1f8)
  • 0x301 (request 0x2f8)
When consolidating, unlink() validates the fake chunk:
Our fake chunk bypasses this:

Tcache Poisoning with Safe Linking

Glibc 2.32+ uses safe linking for tcache:
To poison tcache, we need:
  1. Heap leak (to know address)
  2. Calculate: target ^ (current_addr >> 12)
  3. Overwrite fd pointer via overlapping chunk

CTF Challenge

Challenge: Note-taking application with off-by-one overflowVulnerability:
  • strcpy() caused off-by-one null byte overflow
  • Could overflow from one note into next chunk’s metadata
Exploitation:
  1. Created fake chunk in early allocation
  2. Used off-by-one to clear PREV_INUSE of target chunk
  3. Set fake prev_size to point back to fake chunk
  4. Freed target chunk, consolidating with fake chunk
  5. Got overlapping chunk allocation
  6. Overwrote function pointer for shell
Writeup: Seccon 2016 Tinypad

Common Pitfalls

Wrong Size Selection: Choosing a chunk size that doesn’t end in 0x01 will cause the null byte to corrupt the size value itself, likely causing a crash.
Forgot to Fill Tcache: On glibc 2.26+, if tcache isn’t full, the free() will go to tcache instead of unsorted bin, and consolidation won’t occur.
Fake Chunk Too Far: If the fake prev_size is too large, it might point to unmapped memory or fail validation checks.

Exploitation Strategy

Phase 1: Setup and Overlap

  1. Leak heap address
  2. Create fake chunk with self-referential pointers
  3. Allocate overflow and victim chunks
  4. Off-by-one to clear PREV_INUSE
  5. Set fake prev_size
  6. Fill tcache and free victim
  7. Allocate large overlapping chunk

Phase 2: Tcache Poisoning

  1. Free the overlapped chunk (now covered by large chunk)
  2. Use large chunk to overwrite freed chunk’s fd pointer
  3. Set fd to: target ^ (fd_address >> 12)
  4. Drain tcache with one allocation
  5. Next allocation returns target

Mitigations

This technique remains unpatched but faces several obstacles:
  • Safe linking (glibc 2.32+): Requires heap leak for tcache poisoning
  • Unlink validation: Fake chunk must have valid fd/bk pointers
  • Bounds checking: Some implementations detect off-by-one overflows
  • Tcache key (glibc 2.34+): Tcache entries have additional validation

Poison Null Byte

Alternative null byte exploitation technique

Tcache Poisoning

Core technique used in modern House of Einherjar

Unsafe Unlink

Related technique exploiting chunk consolidation

See Also