Arbitrary Read via Pointer Overwrite
- •
What it is
- •
Corrupt a pointer that the program later dereferences, redirecting a legitimate read or print to another address without changing the program's control flow.
- •
- •
How it works
- •
Find the offset from the input buffer to the pointer variable's location (often disclosed directly by a teaching harness, or via disassembly otherwise).
- •
Overflow up to that offset, then write the target address in place of whatever pointer was originally there.
- •
The program continues normally and, at some later point, calls something like
printf("...%s...", ptr)— sinceptrnow holds the attacker's chosen address, that's what gets read and printed. - •
High addresses [ char *ptr ] ← overwritten with target address (e.g. flag's address) [ padding ] [ input buffer ] ← attacker input starts here Low addresses
- •
- •
When to use it
- •
Use when an overflow reaches a pointer that a later print or read dereferences; verify the target address and string termination.
- •
- •
- •
pwntools
- •
payload = b'A' * pointer_offset + p64(target_addr) p.send(payload)
- •
- •
Debugging
- •
disas challenge x/gx <pointer_slot_address>
- •
- •
Variants
- •
Partial pointer overwrite: preserve valid upper bytes while changing the lower bytes. The unknown address bits and required guesses depend on the actual layout.
- •
Prefer a derived offset when possible. Repeated guesses against newly randomized processes are probabilistic, not a guaranteed sweep of one stable address.
- •
- •
- •
Cards
- •
What makes overwriting a stack pointer variable different from overwriting the return address?
- •
It doesn't hijack control flow at all — the program runs its normal code path, but a later legitimate call ends up operating on attacker-chosen data (the new pointer value) instead of what it was supposed to point to.
- •
- •
Why must a freshly leaked address be re-parsed every run in a PIE-enabled challenge like this?
- •
PIE randomizes the relevant addresses on every execution, so an address captured from a previous run (or hardcoded) won't be valid for the current one — the exploit has to read and use that run's own disclosed values.
- •
- •