A classic stack buffer overflow writes past the end of a local buffer, marching up through memory toward the saved return address that tells the CPU where to resume execution after the current function ends. Two independent server-hardening mitigations stand between that overwrite and code execution:
Layout (low → high address):
[ local buffer ][ canary ][ saved frame ptr ][ return address ]
Stack canary: a random value written at function entry,
checked just before return. If overwritten,
the process aborts — the return address is
never used.
P(blind guess matches) = 1 / 256^k
(k = canary size in bytes, e.g. k=4 → ≈ 2.3×10⁻¹⁰)
ASLR: randomizes where code/return targets actually
live in the address space by H bits of entropy.
P(hit per attempt) = 1 / 2^H
E[attempts to hit] = 2^H
- Overflow length — how many stack words the simulated payload writes. Anything beyond the buffer boundary marches into the canary, then the return address.
- Stack canary — when on and the overflow reaches it, the mismatch is caught before the corrupted return address is ever used: the attempt is blocked, not merely slowed.
- ASLR + entropy — only matters once the return address is actually reached (canary off, or overflow crafted to skip it). Higher entropy bits shrink the odds of a blind guess landing on valid, attacker-controlled code exponentially.
- Auto brute-force — repeats attempts at the chosen rate so the long-run hit rate becomes visible, the same way a real automated exploitation attempt would look from a monitoring dashboard.
This mirrors real server hardening: canaries (gcc -fstack-protector, MSVC /GS) and ASLR are both enabled by default on modern server OSes precisely because layering them makes blind memory-corruption exploitation computationally infeasible, even when a vulnerable buffer exists.