Skip to main content

Overview

Decrypt Safe-Linking is a technique to recover the original pointer value from a safe-linked (XOR-obfuscated) pointer. It exploits the mathematical properties of the safe-linking mechanism, specifically that the first 12 bits of the plaintext are known due to heap alignment, and the XOR key is derived from the pointer itself.
Glibc Compatibility: Works on glibc 2.32+ where safe-linking was introduced.

What It Achieves

This technique allows you to:
  • Recover heap addresses from obfuscated tcache/fastbin pointers
  • Bypass information leak protections added by safe-linking
  • Enable subsequent attacks like tcache poisoning that require knowing actual addresses
  • Decrypt pointers without arbitrary read in many cases

The Mathematical Foundation

Safe-linking uses this protection:
The key insight is that:
  1. First 12 bits are known: Heap chunks are page-aligned, so the lowest 12 bits are predictable
  2. Key equals high bits of plaintext: The XOR key is current_addr, which shares the same ASLR slide as next_ptr
  3. Iterative recovery: We can decrypt bit-by-bit, using each recovered section to decrypt more
Let’s denote:
  • P = plaintext pointer (what we want)
  • K = key (the address where P is stored)
  • C = ciphertext (what we observe)
We have: C = (P >> 12) ^ KSince P and K share the same ASLR base (both heap addresses), their high bits are identical:
Also, P[11:0] are known (page alignment). So:Round 1: Use known P[11:0] to get K[11:0] = P[11:0], decrypt C to get P[23:12]Round 2: Use P[23:12] to get K[23:12] = P[23:12], decrypt more of C to get P[35:24]Continue until full pointer is recovered.

Full Source Code

Step-by-Step Walkthrough

1

Allocate and Free Chunks

Set up the scenario with two tcache chunks:
After freeing, b->next points to a, but it’s obfuscated:
2

Read the Obfuscated Value

The value stored in b[0] is the ciphertext we need to decrypt:
3

Initialize Decryption

Start with what we know: the first 12 bits of the plaintext are 0 (page alignment):
4

Iterative Recovery (Round 1)

Use the known 12 bits to recover the next 12 bits:
5

Continue Iterations

Repeat for 5 rounds to fully recover the 64-bit pointer:
Each round recovers 12 more bits using previously recovered bits.
6

Verify Decryption

The final plaintext should equal the original pointer:

Example Decryption Output

When This Technique Works

✅ Works perfectly when:
  • Both pointers (current and next) are on the same heap page
  • You have arbitrary read to access the obfuscated value
  • Both addresses share the same ASLR slide
  • Standard heap alignment (16 bytes on x64)
⚠️ Requires adaptation when:
  • Pointers are on different pages (need page offset)
  • The stored pointer is not a heap address
  • Non-standard alignment is used
  • Only partial read primitive available
For these cases, see n132’s Dec-Safe-Linking for generalized solutions.

Use Cases in Exploitation

1. Heap Address Leak

Recover heap base address without direct information disclosure:

2. Enable Tcache Poisoning

Once you know real addresses, you can craft mangled pointers:

3. Bypass ASLR

Heap addresses can help calculate libc base:

Why This Is Advanced

Decrypt Safe-Linking is considered advanced because:
  1. Requires mathematical understanding: Must understand XOR properties and bit manipulation
  2. Iterative algorithm: Not a simple one-step calculation
  3. Context-dependent: Need to handle edge cases (different pages, etc.)
  4. Foundation for other attacks: Often a stepping stone to more complex exploits

Limitations

Important Limitations:
  • Requires arbitrary read primitive (or use-after-free read)
  • Assumes standard heap alignment
  • Best results when pointers are on the same page
  • Doesn’t work if the freelist is empty

Alternative Approaches

If decryption is not feasible, consider:
  • Safe-Link Double Protect: Bypass without needing to decrypt
  • Tcache Metadata Corruption: Attack the metadata structure directly
  • House of Water: Leakless exploitation approach

Safe-Link Double Protect

Learn about blind bypass techniques that don’t require decryption

Implementation Tips

CTF Applications

This technique has been useful in numerous modern CTF challenges:
  • Any challenge on glibc 2.32+ requiring heap leaks
  • Challenges with limited primitives (UAF read only)
  • Scenarios where you need to bypass safe-linking without arbitrary write
Ret2 Wargames: Practice this technique at Ret2 Wargames - Decrypt Safe-Linking

References