Memory corruption bugs are the oldest and most dangerous vulnerabilities. Despite modern protections (ASLR, DEP), they remain relevant. A Buffer Overflow occurs when a program puts more data into a fixed-length buffer than the buffer can handle. The extra data eventually overwrites adjacent memory... specifically the Instruction Pointer (EIP/RIP).
The Goal: Control EIP
The EIP register (Extended Instruction Pointer) tells the CPU "Which memory address should I execute next?".
If you overwrite EIP with `0xdeadbeef`, the CPU tries to jump to address `0xdeadbeef` and execute code there. If you put your own Shellcode at that address... you own the machine.
1. The Stack Layout
Memory grows downwards (High Address to Low Address).
1. Buffer: `char buffer[64]` (Where your input goes).
2. EBP: Base Pointer.
3. EIP: Return Address (Where to go when function finishes).
If you type 70 "A"s into a 64-byte buffer:
- 64 "A"s fill the buffer.
- 4 "A"s overwrite EBP.
- 2 "A"s overwrite part of EIP.
2. A Classic Stack Overflow
The vulnerable C code:
The Exploit Python Script
We need to send: `[NOP Sled] + [Shellcode] + [Return Address pointing to NOPs]`.
3. Heap Overflow
The Heap is memory allocated dynamically (`malloc()`). It grows UP.
Heap exploits are harder. You don't directly overwrite a Return Address.
Instead, you overwrite heap metadata (chunk headers). When `free()` is called, the allocator processes the corrupted metadata, allowing you to "unlink" a chunk and write to arbitrary memory ("Write-What-Where").
4. Modern Protections & Bypasses
| Protection | Mechanism | Bypass |
|---|---|---|
| DEP / NX | Mark the Stack as "Non-Executable". CPU refuses to run shellcode there. | ROP (Return Oriented Programming). Don't inject code; reuse existing code (gadgets) already in libc. |
| ASLR | Randomize memory addresses every reboot. You can't hardcode `0xdeadbeef`. | Info Leak. Find a bug that prints a memory address. Calculate the offset. |
| Canary | A random secret value placed before EIP. If it changes, crash safely. | Info Leak (read the canary) or Brute Force (if forking server). |
5. ROP Chains
With DEP enabled, we can't run our shellcode. But `system()` exists in libc.
We build a ROP chain:
1. Put string "/bin/sh" on stack.
2. Jump to `pop rdi; ret` (Gadget 1).
3. Jump to `system()` address.
The CPU executes these tiny existing snippets to achieve the goal.