Tools / Pwntools Forge
Pwntools Forge: pwntools Script Generator
Compose any pwntools script from typed step blocks, type a phrase in the natural-language bar to add a step, or load a preset starting point and edit from there. Every block has its own form, and the script regenerates as you go. Copy or download the .py file when you're ready.
Connection
Run with python3 solve.py for local,REMOTE=1 for remote,GDB=1 for gdb.
Preset starting points
Loading a preset replaces the current step list. Edit/reorder/delete the resulting blocks freely. (Set a libc path to enable the post-leak stage of ret2libc.)
Natural-language step
describe a step, or paste a phrasePhrase examples (click to expand)
wait for >/recv until "Enter your name:"recv line as response/recv 32 bytes as bufsend AAAA/sendline payloadoverflow at offset 40 to win/overflow 72 with rop.chain()cyclic 200/cyclic_find 0x6161616161616168rop chain to system/rop chain to winfmtstr offset 6/format string at offset 8 target exe.got["printf"] with exe.symbols["win"]shellcode/spawn shellleak as puts_leak/u64 from response as leaklibc base from leak via putslog success: pwned!/set OFFSET = 40interactive/close/sleep 1.5section: stage 2 ret2system/# this is a comment/py: io.recv(timeout=1)
Steps (7)
Why this step?
Visual divider with a title comment.
Generated Python (3 lines)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ # Ret2win # โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Why this step?
name = expression
Generated Python (1 line)
OFFSET = 40
Why this step?
name = expression
Generated Python (1 line)
WIN = exe.symbols["win"]
Why this step?
name = expression
Generated Python (1 line)
RET = next(exe.search(asm("ret"), executable=True))Why this step?
flat({offset: [...]}) with offset rows pwntools docs โ
Generated Python (3 lines)
payload = flat({
OFFSET: [RET, WIN], # 16-byte aligned
})Why this step?
io.sendafter / io.sendlineafter pwntools docs โ
Generated Python (1 line)
io.sendlineafter(b"> ", payload)
Why this step?
io.interactive()
No options.
Generated Python (1 line)
io.interactive()
Step blocks
A script is a list of typed blocks emitted in order under a fixed connection header. Reorder, duplicate, or delete blocks. Each block shows its generated Python below the form so you can see the diff as you edit.
Structure
section heading, comment, raw Python (escape hatch), log.info / success / warning / error / debug, set variable.
I/O
recv until needle, recv line (with .strip()), recv N bytes, send / sendline, sendafter / sendlineafter.
Payloads
cyclic(N), cyclic_find offset, flat({...}) row builder, ROP chain (call / raw / find_gadget / dump), fmtstr_payload, shellcode (shellcraft / asm / raw hex).
Post-leak
parse u32 / u64 leak from a recv'd expression, set libc.address from a known symbol leak.
Control
time.sleep, io.interactive(), io.close().
How it works
Everything runs in your browser. Each step block is a typed object; pure functions emit Python lines from the block's form values. The natural-language bar accepts phrases like wait for >, overflow at offset 40 to win, rop chain to system, leak as puts_leak, and interactive map to the right block automatically. Anything that doesn't match a matcher is added as a comment so you never lose the phrase.
Presets aren't exclusive templates: they populate the canvas with a starter list of blocks for ret2win, shellcode, ret2libc, ROP, format string, or cyclic offset finding. Edit, reorder, or mix and match freely.
The script is in sync with the canvas until you edit the textarea directly: an edited tag appears and the canvas stops overwriting your work until you click Reset to generated.
Run the saved file with python3 solve.py for local. Add REMOTE=1 to hit the deployed instance, or GDB=1 to drop into gdb at the breakpoint inside GDBSCRIPT.