Skip to content

Latest commit

 

History

History
170 lines (123 loc) · 6.73 KB

File metadata and controls

170 lines (123 loc) · 6.73 KB

pwntools

A CTF and exploit-development framework that streamlines binary interaction, remote connections, shellcode, and payload construction into a concise scripting API.

Overview

pwntools (from pwn import *) collapses the repetitive plumbing of exploit development — connecting to a service, packing addresses, building cyclic patterns, assembling shellcode, spawning processes — into terse, readable helpers. It is the standard toolkit for binary-exploitation CTF challenges and for prototyping proof-of-concept exploits against software you are authorized to test. Its tube abstraction gives a uniform interface over local processes, remote sockets, and SSH.

Installation

pip install pwntools

Basic Usage

from pwn import context, process, remote

context.log_level = "info"
context.arch = "amd64"

# Local process
io = process("./vuln")
io.recvuntil(b"name: ")
io.sendline(b"A" * 32)
print(io.recvall(timeout=2))
io.close()

# Or a remote service on an authorized lab target
# io = remote("127.0.0.1", 9999)

process and remote both return a tube with the same interface, so an exploit developed locally works unchanged against a lab service.

Important APIs

API Purpose
process(argv) Spawn a local process as a tube
remote(host, port) Connect to a network service as a tube
io.send(data) / io.sendline(data) Write bytes
io.recv(n) / io.recvline() / io.recvuntil(delim) Read bytes
io.interactive() Hand the tube to your terminal
io.close() Release the tube
context.arch/os/log_level Global settings that affect packing and assembly
p32/p64(value) / u32/u64(data) Pack and unpack integers
cyclic(n) / cyclic_find(value) Generate and locate an offset pattern
ELF(path) Parse a binary — .symbols, .got, .plt, .address
ROP(elf) Build ROP chains
asm(code) / disasm(data) Assemble and disassemble
shellcraft Shellcode templates

Tubes work as context managers: with remote(host, port) as io:.

Example

Connect to a remote service and interact (authorized CTF/lab target):

from pwn import remote

io = remote("challenge.lab.local", 1337)
io.recvuntil(b"name: ")
io.sendline(b"tester")
print(io.recvline().decode().strip())
io.close()

Output

Hello, tester!

Packing, cyclic patterns, and offset discovery for a buffer overflow:

from pwn import p64, cyclic, cyclic_find

# Build a De Bruijn pattern to locate the overflow offset.
pattern = cyclic(200)

# Suppose the crash shows RSP contained b"kaaa"; find its offset.
offset = cyclic_find(b"kaaa")
print("offset:", offset)

# Craft a payload: padding + return address.
payload = b"A" * offset + p64(0x401156)
print("payload len:", len(payload))

Output

offset: 40
payload len: 48

Assemble shellcode and inspect an ELF with the bundled helpers:

from pwn import asm, context, ELF

context.arch = "amd64"
shellcode = asm(shellcraft.sh()) if False else asm("xor rdi, rdi; mov rax, 60; syscall")
print("shellcode bytes:", shellcode.hex())

elf = ELF("/bin/ls")
print("PIE:", elf.pie, " NX:", elf.nx)

Output

shellcode bytes: 4831ff48c7c03c000000 0f05
PIE: True  NX: True

Security Use Cases

  • Exploit development — script buffer-overflow, ROP, and format-string PoCs with clean address packing and I/O.
  • CTF binary exploitation — the standard framework for pwn challenges; remote()/process() tubes and cyclic patterns speed the whole workflow.
  • Shellcode assembly — build and test architecture-specific shellcode via asm() and shellcraft.
  • Binary triage — inspect ELF protections (NX, PIE, RELRO, canary) with the ELF and checksec helpers.
  • Service interaction — automate protocol exchanges with network services during authorized testing.

Warning

Use only against binaries and services you own or are explicitly authorized to exploit (CTF, personal labs, sanctioned engagements).

Common Mistakes

  • Sending str instead of bytes — pwntools works in bytes throughout; use b"...".
  • Forgetting to set context.arch, so p64() and asm() produce output for the wrong architecture.
  • Hardcoding offsets or addresses copied from a write-up — they are specific to one binary, libc, and environment. Derive them with cyclic/cyclic_find in your own lab.
  • Ignoring ASLR, PIE, NX, and stack canaries — check with checksec before assuming an approach will work.
  • Omitting timeout= on receive calls, hanging the exploit.
  • Using recv() when you need recvuntil(), producing race-dependent behaviour.
  • Leaving io.interactive() in an automated script.

Security Considerations

[!warning] Lab and CTF use only pwntools is exploit-development tooling. Use it only against binaries and services you own, intentionally vulnerable targets, or CTF challenges you are authorized to solve.

  • Never point an exploit at a system you do not own or lack written authorization to test. Successful exploitation is unauthorized access, which is a criminal offence in most jurisdictions regardless of intent.
  • Offsets and addresses are environment-specific. Any address in a tutorial — including in this course — is illustrative. Derive your own with cyclic, ELF, and a debugger against your own target.
  • Work in an isolated VM. Exploit development crashes processes and can corrupt state; keep it off any machine that matters and off any network with production systems.
  • Disable protections only inside your lab (setarch -R, ulimit -c), never on a shared or production host.
  • Exploit code is dual-use. Handle it, and any target binary, as sensitive material; do not publish working exploits against unpatched third-party software.
  • The educational goal is understanding memory-safety failures so they can be found and fixed — not deployment.

Best Practices

  • Set context.arch/context.os (or context.binary = ELF(...)) early so packing and shellcode match the target.
  • Develop against a local process() first, then swap to remote() — the tube API is identical.
  • Use context.log_level = "debug" to see raw bytes on the wire while debugging.
  • Prefer cyclic()/cyclic_find() over manual offset counting.
  • Keep exploit scripts, target binaries, and authorization notes together for reproducibility.

References

Related Topics

  • [[Scapy]] — lower-level packet control for network-facing exploits
  • [[Paramiko]] — SSH automation alongside pwntools' ssh tubes
  • [[Readme|Python for Security Professionals]] — course home