Memory Disclosure (Info Leak)
- •
What it is
- •
A bug that exposes memory contents, including secrets, pointers, or canary values. A leak can reveal data directly or supply values needed by a separate corruption bug.
- •
- •
Leak variants
- •
Compare same-frame over-reads, Stale Stack Data Leak (Frame Reuse) from a returned call, and Cross-Frame Buffer Over-Read via Recursion (Nested Frame Leak) involving active recursive frames.
- •
- •
How it works
- •
Buffer over-read: reading past the end of a buffer's intended bounds exposes whatever adjacent memory happens to follow it — symmetric to a buffer overflow, but reading out instead of writing in.
- •
Missing terminator:
read()does not append a null. A later%sprint can continue past the input until it finds one. - •
Uninitialized memory reuse: C doesn't zero freshly-allocated stack or heap memory. A variable read before it's explicitly set may contain leftover bytes from whatever previously occupied that memory — including a prior function's secrets.
- •
Defeated memory wipes: code that explicitly
memset()s sensitive data to zero before it goes out of scope can have that wipe silently removed by the compiler, if the compiler proves the wiped buffer is never read again afterward (a legal "dead store elimination" optimization) — leaving the "erased" secret still sitting in memory.
- •
- •
When to use it
- •
A print/output function operating on attacker-influenced or partially-attacker-controlled data with no explicit length bound (
printf("%s", buf)on a buffer the attacker only partly filled) -> check whether the terminator is guaranteed or attacker-omittable. - •
Need a stack canary value or a randomized (ASLR) address to make a separate corruption exploit work -> look for any read primitive, however small, that reaches the target's memory location.
- •
Security-sensitive code explicitly zeroes a buffer right before it goes out of scope -> worth checking whether the compiler could have optimized that wipe away (relevant mainly for auditing/defensive review, not something attacker input alone triggers).
- •
A
printfprecision cap (%.Ns) can be a deliberate anti-leak measure, not just an accident of the format string — if the cap is tuned to stop a few bytes short of a sensitive target (a canary, a return address), an over-read that would otherwise reach that target is blocked entirely, even if the buffer itself is completely filled with non-null bytes. Check the precision value against the actual distance to any interesting target before assuming an over-read will reach it.
- •
- •
- •
pwntools
- •
leaked = p.recvn(8) # When the protocol supplies exactly eight raw bytes. value = u64(leaked)
- •
- •
Debugging
- •
x/40xb $rsp # Inspect neighboring bytes and null terminators.
- •
- •
- •
Cards
- •
Why is a memory disclosure bug often paired with a separate corruption bug rather than exploited alone?
- •
The leak itself usually isn't the end goal — it defeats a protection (canary, ASLR) that would otherwise block a different corruption exploit from succeeding.
- •
- •
Why can a compiler legally remove a
memset()meant to erase a secret?- •
If the compiler can prove the zeroed buffer is never read again afterward, the write is a "dead store" with no observable effect from the compiler's point of view, and optimizing it away is valid — even though it defeats the programmer's security intent.
- •
- •
Linked references 10
- Address Space Layout Randomization (ASLR)
- Arbitrary Read via Pointer Overwrite
- Backdoor-Assisted Info Leak (Recursive Self-Leak)
- Buffer Overflow
- Cross-Frame Buffer Over-Read via Recursion (Nested Frame Leak)
- Out-of-Bounds Array Access (Index Manipulation)
- pwn-college
- Signed Loop Counter Steering (Branch Selection via Negative Modulo)
- Stack Canary
- Stale Stack Data Leak (Frame Reuse)