Overview
PwnSmith is an advanced GDB plugin built for binary exploitation CTF challenges. It combines pwndbg-style debugging (register display, stack telescope, heap visualization) with pwntools-style automation (payload generation, ROP chain building, remote exploit delivery) — all without leaving GDB.
Run analyze on a binary and PwnSmith will identify security properties, dangerous functions, win functions, ROP gadgets, and suggest an attack plan. Then generate and deliver a payload in two commands.
Table of contents
Open Table of contents
Key Features
- Auto-analysis — checksec, vulnerability scanning, win function detection, ROP gadget search, and attack plan suggestion in one command
- Payload generation — ret2win, ROP chains (
system("/bin/sh")), shellcode injection, and cyclic patterns with automatic offset detection - Payload execution — run exploits against local or remote targets directly from the GDB prompt
- ROP chain building — automatic
system("/bin/sh"),execve, andmprotectchains with libc gadget search and one_gadget support - Format string helpers — offset discovery, arbitrary read/write payload generation, and pwntools
fmtstr_payload()output - Heap visualization — chunk walking, tcache bin display (with glibc 2.32+ safe-linking deobfuscation), and corruption detection
- Enhanced debugging — register display with change highlighting, stack telescope with frame detection, and configurable auto-context
- pwntools integration — connect to remote/local targets, send/recv data, leak addresses, and drop to interactive mode
- Multi-step exploit scripting — define exploit steps in Python with shared state and run them sequentially
- Exploit script generation — output ready-to-run pwntools Python scripts with local/remote support
Installation
curl -sL https://raw.githubusercontent.com/imattas/pwnsmith/main/install.sh | bash
This installs system dependencies (gdb, python3, binutils), Python packages (pwntools, pyelftools, capstone), clones the repo, installs the binary, and configures ~/.gdbinit.
To update:
pwnsmith update
Usage
Getting Started
pwnsmith ./binary # debug a binary
pwnsmith -p 1234 # attach to a process
pwnsmith ./binary core # load a core dump
Typical Workflow
pwnsmith> analyze
--- Security -------------------------------------------------
NX: Enabled
PIE: DISABLED
Canary: DISABLED
--- Win Functions --------------------------------------------
win @ 0x4011a6
[+] ret2win target found!
--- Attack Summary -------------------------------------------
1. ret2win -- Try: payload gen ret2win
pwnsmith> payload gen ret2win
[+] Found win function: win() @ 0x4011a6
Offset: 64 | Size: 80 bytes
pwnsmith> payload run
[+] Payload delivered
FLAG: flag{you_got_it}
pwnsmith> payload run pwn.ctf.com 9001
[+] Payload delivered (remote)
FLAG: flag{remote_pwned}
Command Reference
| Command | Alias | Description |
|---|---|---|
analyze | aa | Auto-scan: checksec, vulns, win funcs, gadgets, attack plan |
payload gen <type> | pl | Generate ret2win, rop, shellcode, or cyclic payloads |
payload run [host port] | Execute payload locally or against a remote target | |
payload script [file] | Generate a pwntools exploit script | |
regs | rg | Register display with change highlighting |
stack [n] | st | Stack telescope with pointer dereferencing |
heap | hp | Walk and display heap chunks, tcache bins, corruption |
rop [pattern] | gadgets | Find ROP gadgets and auto-build chains |
fmtstr | fmt | Format string offset discovery and write payloads |
bp <loc> | Enhanced breakpoints with automation (-c "cmd") | |
ctx | Configure auto-context display | |
pwn-connect | Manage pwntools remote/local connections | |
pwn-send / pwn-recv | Send and receive data through pwntools connections | |
pwn-libc | Show libc base, symbols, /bin/sh, and gadgets | |
pwn-script | pws | Multi-step exploit scripting with shared state |
Remote CTF Workflow
# Set the remote target once
pwnsmith> payload remote pwn.ctf.com 9001
# Generate and send
pwnsmith> payload gen ret2win
pwnsmith> payload run
# Or generate a standalone script
pwnsmith> payload script solve.py pwn.ctf.com 9001
# Then: python3 solve.py REMOTE
Custom Commands
Drop a .py file in pwnsmith/commands/ — it is auto-discovered on next load:
import gdb
from pwnsmith.commands import register_command
@register_command("mycmd", "My custom command", aliases=["mc"])
class MyCommand(gdb.Command):
def __init__(self):
super().__init__("mycmd", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
gdb.write("Hello from my command!\n")