--- name: write-exploit description: 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. user-invocable: true argument-hint: "[target info and vulnerability description]" allowed-tools: ["Bash", "Read", "Write", "Edit", "Glob", "Grep", "Task", "WebFetch", "WebSearch"] --- # 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