write-exploit

Original🇺🇸 English
Translated

Write, test, and iterate on CTF exploit scripts. Use when you need to develop a working exploit with a test-debug-fix loop against a live target.

5installs
Added on

NPX Install

npx skill4agent add ramzxy/ctf write-exploit

Tags

Translated version includes tags in frontmatter

Exploit Development Loop

Write exploits iteratively — run, observe, fix, repeat until the flag drops.

Workflow

  1. Understand the vulnerability — Read challenge source/binary analysis first
  2. Write initial exploit — Start simple, add complexity as needed
  3. Test against target — Run locally first, then remote
  4. Debug failures — Read output carefully, add debug prints, check assumptions
  5. Iterate — Fix and re-run until flag captured
  6. Clean up — Save working exploit as
    solve.py
    , flag to
    flag.txt

Exploit Templates

Binary Exploitation (pwntools)

python
#!/usr/bin/env python3
from pwn import *

context.binary = elf = ELF('./binary')
# context.log_level = 'debug'

def conn():
    if args.REMOTE:
        return remote('HOST', PORT)
    return process('./binary')

io = conn()

# === EXPLOIT HERE ===

io.interactive()

Web Exploitation (requests)

python
#!/usr/bin/env python3
import requests
import sys

TARGET = sys.argv[1] if len(sys.argv) > 1 else 'http://localhost:8080'
s = requests.Session()

# === EXPLOIT HERE ===

print(f"FLAG: {flag}")

Crypto Solve Script

python
#!/usr/bin/env python3
from Crypto.Util.number import *
from pwn import *

# === GIVEN VALUES ===

# === SOLVE ===

flag = long_to_bytes(m)
print(f"FLAG: {flag.decode()}")

Pwntools Remote Interaction

python
#!/usr/bin/env python3
from pwn import *

io = remote('HOST', PORT)

# Read until prompt
io.recvuntil(b'> ')

# Send payload
io.sendline(payload)

# Get response
response = io.recvline()
print(f"Response: {response}")

# Interactive mode for shell
io.interactive()

Debug Tips

  • Use
    context.log_level = 'debug'
    for full pwntools traffic
  • Add
    print(f"[*] payload: {payload.hex()}")
    before sends
  • Use
    io.recv(timeout=2)
    to see unexpected output
  • Check
    io.can_recv()
    before blocking reads
  • Use
    gdb.attach(io)
    for local debugging with breakpoints
  • For web:
    print(r.status_code, r.text[:500])
    after every request

Common Pitfalls

  • Wrong endianness: Use
    p64()
    for little-endian,
    p64(val, endian='big')
    for big
  • Newline issues:
    sendline()
    adds
    \n
    ,
    send()
    doesn't — know which the server expects
  • Timing: Add
    sleep(0.5)
    between sends if server is slow
  • Encoding: Web payloads may need URL encoding, base64, or hex
  • Stack alignment: x86-64 needs 16-byte alignment — add extra
    ret
    gadget
  • Python 2 vs 3: pwntools works with bytes in Python 3 — use
    b"string"
    not
    "string"

Iteration Pattern

1. Write exploit → run → "Connection refused"
   Fix: Check host/port, is service up?

2. Write exploit → run → "EOF in recv"
   Fix: Server closed connection — payload crashed it. Check offsets.

3. Write exploit → run → wrong output
   Fix: Add debug prints, check each step's output matches expectation.

4. Write exploit → run → "flag{...}"
   Done! Save to flag.txt

Target

$ARGUMENTS