# Exploit Memory Corruption

> Turn a memory-corruption bug in a native binary into code execution — stack overflows, format strings, and ROP against modern mitigations. Load when you control input to a compiled program and it crashes or misbehaves: a network daemon, a thick client, a setuid/SUID helper, or extracted firmware. Signals: segfault on long/`%n` input, a crash with control of a register, no source, checksec output, "exploit this binary/service".

- Skill: `noorqureshi/exploit-memory-corruption` (Agent Skill)
- Install (CLI): `npx skillmds@latest add noorqureshi/exploit-memory-corruption`
- Raw SKILL.md: https://api.skillmd.com/api/skills/noorqureshi/exploit-memory-corruption/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: NoorQureshi (https://skillmd.com/u/noorqureshi)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/noorqureshi/exploit-memory-corruption

---


# Memory-corruption exploitation

## When it applies
You have a native binary or service on an authorized target that mishandles your input — a
network-facing daemon, a thick-client, a setuid helper found during `privesc`, or a binary carved
from firmware (`reverse-eng-firmware`). `reverse-eng-binary-triage` located the bug; this skill turns
that crash into controlled execution. Pentest-only — this is destructive and can crash the service.

## Why it works
C/C++ has no memory safety: writing past a buffer overwrites saved return addresses and pointers, and
a user-controlled format string reads/writes arbitrary memory. Redirect execution to your code or to
existing code (ROP) and the process does your bidding. Modern mitigations (NX, ASLR, PIE, stack
canaries) don't remove the bug — they shape the technique.

## Method
1. **Check protections first** — `checksec ./bin` (or `pwntools`): NX, PIE, RELRO, canary. This
   decides everything. No canary + NX → ROP; PIE → you need a leak; no PIE, no NX → maybe shellcode.
2. **Find the offset** — send a cyclic pattern (`cyclic 200` / pattern_create), crash it under
   `gdb`+GEF/pwndbg, read the value in `$rip`/`$eip`, and `cyclic -l <value>` for the exact offset to
   the saved return address.
3. **Pick the primitive by protections:**
   - **ret2win** — a target function already in the binary; overwrite the return address with it.
   - **ret2libc / ROP** — with NX, chain gadgets: leak a libc address (call `puts(puts@got)` via the
     PLT), compute the libc base, return to `system("/bin/sh")` or a `one_gadget`. Build gadgets with
     `ROPgadget`/`ropper`, the chain with `pwntools` `ROP()`.
   - **Format string** (`printf(user)`) — leak stack/canary/PIE base with `%p`, then do arbitrary
     writes with `%n` (GOT overwrite → redirect a call to `system`). `fmtstr_payload` automates it.
4. **Defeat mitigations with leaks** — ASLR/PIE need a leaked address (from a format string or an
   info-leak bug) to rebase; a stack canary must be leaked (or brute-forced byte-by-byte on a forking
   server) and replayed in your overflow so the check passes.
5. **Build it with pwntools** — a repeatable script: `process()`/`remote()`, `recvuntil`, pack with
   `p64()`, stage the leak, then send the final chain; iterate locally, then fire at the target.
6. **Land a shell** — reuse `payloads-reverse-shells` for what to run once you have execution.

## Gotchas
- **Match the exact libc** — remote exploitation fails on the wrong libc version/offsets; identify it
  (leaked addresses → a libc-database lookup) before computing `system`/`one_gadget`.
- **Bad bytes** — `\x00`, `\x0a`, `\x20` can truncate input depending on the read function; check and
  avoid them in addresses/payload.
- **Local works, remote doesn't** — environment/stack alignment differs; the `movaps` alignment crash
  before `system` is fixed by an extra `ret` gadget.
- **This crashes the target** — it's inherently disruptive; only on authorized pentest targets, never
  a live bug-bounty production service, and note the risk in the RoE.

## Verify success
Reliable control of execution demonstrated on the target — a returned shell, a run command, or a
controlled `$rip` with a working ROP chain — reproducible from your pwntools script.

## References
pwntools docs & tutorials; `checksec`; GEF/pwndbg; ROPgadget/ropper; `one_gadget`; libc-database.
Find the bug with `reverse-eng-binary-triage`; shell payloads in `payloads-reverse-shells`.

