| name | exploitation-techniques |
| description | Core exploitation techniques for binary vulnerabilities |
Exploitation Techniques
Pattern Selection
| Pattern | Signals | Requirement |
|---|---|---|
| Stack BOF | No canary, unbounded input | Control return address |
| Canary Bypass | Canary present, info leak possible | Leak or avoid canary |
| GOT Overwrite | Partial RELRO, write primitive | Writable GOT |
| Format String | printf(user_input) |
User controls format |
| ret2libc | NX enabled, libc available | Libc address leak |
| ROP | NX enabled, gadgets needed | Sufficient gadgets |
1. Stack Buffer Overflow
Concept: Overflow a stack buffer to overwrite the saved return address.
Stack Layout:
[ buffer ][ saved_rbp ][ return_addr ]
↑ ↑ ↑
overflow → overwrite → control RIP
Template:
OFFSET = <bytes_to_return_address>
TARGET = <address_to_jump_to>
payload = b'A' * OFFSET
payload += p64(TARGET)
64-bit alignment: Add a ret gadget before the target if crashes occur (16-byte alignment).
2. Stack Canary Bypass
Concept: Leak or avoid corrupting the stack canary.
Approaches:
- Leak via format string or other info disclosure
- Brute force (only works with fork servers - canary constant across children)
- Off-by-one to corrupt variable above canary without touching canary
Leak template:
# Probe for canary (ends in null byte)
for i in range(1, 50):
send(f'%{i}$p')
if response.endswith(b'00'):
CANARY_OFFSET = i
Brute force template:
canary = b'\x00' # First byte always null
for position in range(7):
for byte in range(256):
payload = padding + canary + bytes([byte])
if no_crash(payload):
canary += bytes([byte])
break
3. GOT Overwrite
Concept: Overwrite a GOT entry so the next call to that function jumps to your target.
Requirements: Partial RELRO (GOT writable), write primitive
Template:
GOT_ENTRY = <address_of_got_entry>
NEW_VALUE = <address_to_redirect_to>
# Write NEW_VALUE to GOT_ENTRY using your primitive
# (format string, arbitrary write, etc.)
Common targets: Functions called after your write (puts, printf, exit, __stack_chk_fail)
4. Format String
Concept: User input used directly as printf format string enables read/write.
Read template:
# Leak stack values
payload = b'%p.' * N
# Leak specific offset
payload = b'%<offset>$p'
Write template:
# pwntools handles complexity
writes = {<target_addr>: <value>}
payload = fmtstr_payload(<stack_offset>, writes)
5. ret2libc
Concept: After leaking a libc address, calculate base and call system().
Template:
LEAKED_ADDR = <leaked_function_address>
LEAKED_OFFSET = libc.symbols['<leaked_function>']
libc.address = LEAKED_ADDR - LEAKED_OFFSET
system = libc.symbols['system']
binsh = next(libc.search(b'/bin/sh'))
payload = padding + p64(ret) + p64(pop_rdi) + p64(binsh) + p64(system)
6. ROP Chains
Concept: Chain gadgets ending in ret to perform operations when NX is enabled.
64-bit calling convention: RDI, RSI, RDX, RCX, R8, R9
Gadget types:
pop <reg>; ret- Load value into registermov [<reg>], <reg>; ret- Write to memorysyscall; ret- Make syscall
Template:
rop = ROP(elf)
rop.call('<function>', [<arg1>, <arg2>, ...])
payload = padding + rop.chain()
7. Heap Exploitation
Use-After-Free:
- Allocate chunk A
- Free chunk A
- Allocate chunk B (same size, reuses A's memory)
- Dangling pointer to A now accesses B's data
Heap Overflow:
- Corrupt adjacent chunk metadata
- Overwrite forward/backward pointers
- Achieve write primitive on next alloc/free
Composition Patterns
| Have | Combine With |
|---|---|
| BOF + NX | ret2libc or ROP |
| Format string | GOT overwrite, leak canary/libc |
| Partial RELRO + write | GOT overwrite |
| Fork server + canary | Brute force canary |