| name | binary-exploitation-technique |
| description | Auth/lab: binary/memory-corruption exploitation methodology — turn a confirmed corruption primitive (stack/heap overflow, UAF, double-free, type confusion, OOB, format string) into reproducible controlled impact. Use when deciding exploitability, qualifying a crash or primitive, selecting a mitigation-aware strategy (NX, ASLR/PIE, canary, RELRO, CET/CFG, safe-linking), planning a staged leak/control/impact chain, or choosing between control-flow (ROP/JOP/SROP/ret2dlresolve) and data-only paths. Routes to concrete pwn recipes and exploit-development skills. Not for CVE/PoC initial access (vuln-exploit-technique), static/dynamic analysis (reversing-technique), or writing primitives at code depth (offensive-coding/*-dev). |
| license | MIT |
| compatibility | Linux/Windows/macOS user-mode primary; kernel and exotic arch referenced with handoff; authorized engagements and labs only. |
| metadata | {"author":"AeonDave","version":"1.0","category":"offensive-techniques","language":"c,cpp,asm,python"} |
Binary Exploitation Technique
Decision engine for converting a confirmed memory-corruption primitive into reproducible, mitigation-aware controlled impact. Finding the bug is upstream (reversing-technique, fuzzing-technique, source-review-technique); this technique decides how to weaponize it, which strategy fits the mitigation set, and what proves it. Concrete per-technique recipes live in offensive-ctf/pwn-ctf/references; primitive-construction depth lives in offensive-coding/*-dev. This skill is the methodology that routes between them.
When this technique applies
- You control PC/return target/indirect call target, or can corrupt heap metadata, an object/vtable pointer, or an allocator-linked structure.
- You have an attacker-influenced crash and must separate "crash only" from "exploitable under constraints".
- You need a mitigation-aware plan before investing in a chain.
If you do not yet have a repeatable, attacker-influenced primitive, stay in bug discovery and improve primitive quality first.
Boundary
- Input: a confirmed primitive from
reversing-technique (crash/RE), fuzzing-technique (repro), or source-review-technique.
- Output: a reproducible impact proof; hand a stable session to
post-exploit-technique.
- Not here: CVE/PoC initial access on services/web ->
vuln-exploit-technique; static/dynamic analysis and crash discovery -> reversing-technique; writing the primitive at code depth (allocator internals, gadget policy, FILE structs, shellcode bytes) -> offensive-coding/*-dev; CTF-scoped triage/time-boxing -> offensive-ctf/pwn-ctf.
Primitive qualification
Classify the best proven primitive before selecting a technique.
| Primitive | Typical source | Immediate value |
|---|
| PC control | stack overwrite, function pointer, handler confusion | direct control-flow steering |
| Stack pivot | constrained return overwrite | enables chain execution |
| Arbitrary read | OOB read, type confusion | leak base addresses/secrets |
| Arbitrary write | heap poisoning, UAF, index bug | overwrite function/hook/state |
| Partial overwrite | off-by-one, truncation | targeted corruption under constraints |
| Data-only corruption | auth/config flags, object fields | privilege/logic impact, no code exec |
Prove one primitive fully before chaining two uncertain ones. Model repeatability: read every branch of a state guard (is_set, initialized, done, idx == fav) — the already-set/else branch often still performs the gated read/write/free, so an apparently one-shot primitive is a repeatable R/W loop. Confirm which branch runs on the second invocation before declaring a path dead.
Reproduction discipline
Fix and record for every stage: binary hash, loader path, dependency/libc versions, argv/input/protocol framing, relevant env vars and cwd, mitigation state, debugger settings. Run a reliability loop before escalation: ~10 runs to validate a candidate primitive, 30+ for final proof. An input-only reproduction is the only proof a primitive works — a gdb set/hand-painted register or memory value is not a delivered primitive, and a cooked-mode PTY mangles 0x0a/0x7f/0x11/0x13 in pointer payloads, so drive local dev over a pipe or the live socket.
Mitigation-aware strategy selection
Inventory protections first (checksec, module headers, loader settings): NX/DEP, ASLR/PIE, stack canary, RELRO, CFG/CET (Windows/hardware), allocator hardening (safe-linking/tcache guards). Then choose a compatible path:
- No executable-memory path -> control-flow reuse (ROP/JOP/SROP/call chain).
- No stable control-flow path -> data-only impact if the objective permits.
- ASLR/PIE unresolved -> prioritize a leak/oracle stage before the final chain.
- Hardware CET/IBT or Windows CFG active -> prefer valid call targets or data-only state corruption; do NOT confuse hardware CET with compiler-emitted userland SafeStack/CFI/software-shadow-stack, which come apart leak-free (route to
safestack-cfi-shadowstack.md).
- Full RELRO + strict CFI -> non-GOT writable targets, loader-assisted resolution, or bounded data-only impact.
- Arbitrary write + libc leak, weak gadget surface -> check an FSOP path (does
exit/fclose/flush run on a path you control?).
Reproduce the remote, not your dev box: kernel, RLIMIT_STACK, and libc differences move mmap adjacencies and mitigation reachability. Do not issue an impossibility/"dead vector" verdict from a dev-box or WSL layout — prove it with a failing live test or a length-sweep against the target.
Leak -> control -> impact ladder
Build in stages; each stage depends only on prior validated primitives.
- Stage A (disclosure/oracle): obtain one dependable anchor (module/libc/PIE base, canary, pointer class, token). Skip only when addresses are already deterministic.
- Stage B (control upgrade): constrained primitive -> robust primitive (constrained write -> arbitrary write; PC control -> pivot -> chain).
- Stage C (impact): minimal, lowest-noise, reversible proof tied to authorized scope.
Per-stage evidence packet: trigger input; observed register/memory transition; expected vs observed; failure mode and fallback. Drive to end-to-end execution early, then fix the latest fault (x/i $pc, rsp & 0xf, faulting field) — alignment (movaps), resolver-vs-call stack parity, and controlled bytes overlapping a lock/pointer/terminator surface only in a full run.
Crash-triage to exploitation handoff
From a raw crash: (1) identify the faulting instruction and operand semantics; (2) verify attacker influence over the operand/target pointer; (3) classify the bug family (overflow/UAF/type confusion/index/format string); (4) confirm the crash is deterministic under the same input; (5) isolate the candidate path and discard non-deterministic branches. If determinism fails, return to primitive improvement before payload engineering.
Route to the right depth
Match the dominant primitive to its canonical concrete recipe and exploit-development home. Load the narrowest that fits; do not re-derive what these already document.
| Family / signal | Concrete recipes (offensive-ctf/pwn-ctf/references/) | Exploit-dev design (offensive-coding/) |
|---|
| Stack overflow, saved-RIP, partial return, ROP assembly | overflow.md, rop.md | stack-exploitation-dev, rop-development-dev |
| Heap: UAF/double-free/overlap, tcache/bins, House-family | heap.md | heap-exploitation-dev |
| FILE/FSOP stream corruption, libio dispatch | heap-fsop.md | fsop-dev |
| Format-string leak + staged write | format-string.md | (target dictates: stack/heap-dev) |
| Shellcode, ORW, seccomp, byte blacklists | shellcode-filtering.md, sandbox.md | shellcode-dev |
| RELRO/GOT/PLT, relocations, leakless partial overwrite | relro-aslr-relocations.md | — |
| SafeStack + CFI + shadow-stack + canary (composed, leak-free) | safestack-cfi-shadowstack.md | stack-exploitation-dev |
Loader _dl_fixup/forged symbols/lazy resolution | dynamic-linker-resolver-pivots.md | — |
| Kernel primitives and escalation | kernel.md | linux-internals-dev |
| Windows user-mode: SEH/DEP/CFG, PEB-walk | windows-pwn.md | stack-exploitation-dev, shellcode-dev, windows-internals-dev |
| Exotic arch (ARM32/ARM64/MIPS/RISC-V) | exotic-arch.md | asm-offensive-patterns |
| Same-process multi-stage / allocator drift | stateful-exploit-campaigns.md | — |
Quality gates
Mark a capability exploitation-ready only when all hold: the primitive is reproducible input-only; mitigation constraints are documented and accounted for; the chain relies on no hidden manual timing; the impact proof is within authorized scope; required assumptions (versions, flags, services, RLIMIT_STACK) are explicit. Separate exploitability from severity: prove control first, then business impact. Keep a chain ledger and re-apply every proven runtime fact (live offsets, register snapshots, alignment quirks, deterministic pointers) to each later sub-chain.
Anti-patterns
- Treating one lucky run as a stable exploit path, or mixing environment settings between runs and drawing wrong conclusions.
- Declaring a vector "impossible/dead" by deduction — reachability and impossibility are decided by a failing live test, not an argument. If you write "nothing reaches Y" or "X can't work leaklessly", hook Y and every candidate call site and fuzz adversarial inputs first.
- Jumping to payload engineering before a stable primitive; ignoring ABI/alignment; ignoring CFG/CET when choosing chain style.
- Reporting impact without showing primitive evolution, reliability, and boundary conditions.
Resources
Tooling belongs in the tool skills; load them for syntax:
offensive-tools/exploits/pwntools — remote/process interaction, packing, ELF/libc symbols, ROP helper, shellcraft.
offensive-tools/rev/gdb (pwndbg/gef) — register/stack/heap validation, checksec, live snapshots.
offensive-tools/rev/ropgadget, offensive-tools/rev/one-gadget — gadget and constraint-based shell-gadget discovery.
offensive-tools/rev/checksec, offensive-tools/rev/patchelf — mitigation inventory and target-libc reproduction.
Methodology neighbors: reversing-technique (bug discovery/handoff in), fuzzing-technique (repro), vuln-exploit-technique (CVE/service initial access), post-exploit-technique (after impact). For CTF-scoped triage, time-boxing, and the full recipe index, use offensive-ctf/pwn-ctf.