{"id":8457,"library":"pwntools","title":"Pwntools","description":"Pwntools is a CTF (Capture The Flag) framework and exploit development library for Python. It provides a comprehensive set of tools for writing exploits, interacting with binaries and remote services, performing assembly/disassembly, ROP chain generation, and much more. The current version is 4.15.0, and it maintains an active release cadence.","status":"active","version":"4.15.0","language":"en","source_language":"en","source_url":"https://github.com/Gallopsled/pwntools","tags":["security","ctf","exploit-development","binary-exploitation","reverse-engineering","pwn","pentesting"],"install":[{"cmd":"pip install pwntools","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Often used for symbolic execution and more advanced binary analysis alongside pwntools; a heavy, optional dependency.","package":"angr","optional":true}],"imports":[{"note":"The main API is exposed via the 'pwn' module, not 'pwntools'. While wildcard import is common for quick CTF scripts, explicit imports are recommended for larger projects.","wrong":"import pwntools; from pwntools import pwn","symbol":"pwn","correct":"from pwn import *"},{"note":"Used for connecting to remote services.","symbol":"remote","correct":"from pwn import remote"},{"note":"Used for interacting with local binaries.","symbol":"process","correct":"from pwn import process"},{"note":"Used for parsing and interacting with ELF executables.","symbol":"ELF","correct":"from pwn import ELF"},{"note":"Used for building Return-Oriented Programming (ROP) chains.","symbol":"ROP","correct":"from pwn import ROP"},{"note":"Used for assembling shellcode.","symbol":"asm","correct":"from pwn import asm"},{"note":"Provides structured logging functions like `log.info`, `log.success`, `log.error`.","symbol":"log","correct":"from pwn import log"}],"quickstart":{"code":"from pwn import *\n\n# Configure global context for architecture and OS (important for assembly/disassembly, packing)\ncontext.arch = 'amd64' # Example: ARM, i386, amd64\ncontext.os = 'linux'  # Example: windows, freebsd\ncontext.log_level = 'info' # Debug, info, warn, error, critical\n\n# --- Example: Interact with a remote service ---\n# Replace with the actual challenge host and port\nHOST = 'challenge.example.com'\nPORT = 1337\n\ntry:\n    log.info(f\"Connecting to {HOST}:{PORT}...\")\n    # Establish a connection to the remote service\n    io = remote(HOST, PORT)\n    log.success(\"Connected!\")\n\n    # Receive initial data (e.g., a banner)\n    banner = io.recvline()\n    log.info(f\"Received banner: {banner.decode(errors='ignore').strip()}\")\n\n    # Send some input (e.g., a simple payload for a buffer overflow)\n    # pwntools handles bytes automatically for send/recv\n    payload = b'A' * 72 + p64(0xdeadbeef) # 72 bytes of 'A', then an 8-byte address\n    io.sendline(payload)\n    log.info(f\"Sent payload: {payload!r}\")\n\n    # Receive the response after sending data\n    response = io.recvall()\n    log.info(f\"Received full response: {response.decode(errors='ignore').strip()}\")\n\n    io.close()\n    log.success(\"Connection closed.\")\n\nexcept PwnlibException as e:\n    log.error(f\"Pwntools error: {e}\")\nexcept Exception as e:\n    log.error(f\"General error: {e}\")\n","lang":"python","description":"This quickstart demonstrates how to connect to a remote service, send data (e.g., a simple buffer overflow payload using `p64` for packing), and receive responses. It highlights setting `context.arch` and `context.os`, which are crucial for correct behavior in many pwntools operations. Replace `HOST` and `PORT` with your target challenge details."},"warnings":[{"fix":"Ensure you are running your scripts with `python3` and adapt any Python 2 specific syntax (e.g., `print` statements, string vs. bytes handling) to Python 3.","message":"Pwntools has dropped official support for Python 2. While older versions worked with Python 2, current versions (4.x and above) are Python 3 only. Many older online tutorials or code snippets might be for Python 2, leading to syntax errors or unexpected behavior in Python 3.","severity":"breaking","affected_versions":"< 4.0.0 (Python 2 supported), >= 4.0.0 (Python 3 only)"},{"fix":"Always set `context.arch` (e.g., 'amd64', 'i386', 'arm') and `context.os` (e.g., 'linux', 'windows', 'freebsd') at the beginning of your script to match the target binary/system. Example: `context.arch = 'amd64'; context.os = 'linux'`","message":"Failure to correctly set `context.arch` and `context.os` can lead to incorrect assembly/disassembly, packing/unpacking (e.g., `p64`, `u64`), ROP chain generation, or shellcode execution. Pwntools defaults to `i386` and `linux` if not specified, which may not match your target.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Prefer explicit imports for functions/classes you need, e.g., `from pwn import remote, process, ELF, ROP, flat, asm, log`. Alternatively, use `import pwn` and then access functions via `pwn.remote()`, `pwn.process()`, etc.","message":"The common practice `from pwn import *` imports all public symbols from the `pwn` module directly into your script's namespace. This can lead to name collisions with other variables or functions defined in your script or other imported modules, making debugging harder.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always ensure data sent to `io.send*` functions are `bytes` (e.g., `b'hello'` or `'hello'.encode('utf-8')`). Decode received `bytes` to `str` if needed for printing or manipulation (e.g., `io.recvline().decode('utf-8', errors='ignore')`).","message":"Python 3 differentiates strictly between `str` (unicode text) and `bytes` (sequence of bytes). IO functions like `send`, `sendline`, `recv`, `recvline` in pwntools expect and return `bytes`. Mixing `str` with `bytes` without explicit encoding/decoding will raise `TypeError`.","severity":"gotcha","affected_versions":"All Python 3 versions of pwntools"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Install pwntools using pip: `pip install pwntools`. If using virtual environments, ensure your environment is activated.","cause":"The pwntools library (specifically the 'pwn' module) is not installed or not accessible in your current Python environment.","error":"ImportError: No module named pwn"},{"fix":"Convert your string to bytes using `.encode()` or use a byte literal: `io.sendline('my string'.encode('utf-8'))` or `io.sendline(b'my string')`.","cause":"You are attempting to send a Python 3 `str` object to a pwntools function (like `io.send()`, `io.sendline()`, or `asm()`) that explicitly expects a `bytes` object.","error":"TypeError: 'str' does not support the buffer interface"},{"fix":"Set `context.arch` to a valid architecture string at the beginning of your script, e.g., `context.arch = 'amd64'` or `context.arch = 'arm'`. Consult pwntools documentation for supported architecture names.","cause":"The `context.arch` variable is either unset or set to an invalid/unsupported architecture string when an architecture-dependent function (like `asm()` or `ELF().disasm()`) is called.","error":"pwnlib.exception.PwnlibException: Unknown architecture <ARCH_NAME>"},{"fix":"Verify that the `host` string in your `remote()` call is correct and resolvable. Check for typos. Ensure you have an active network connection.","cause":"The hostname or IP address provided to `pwn.remote(host, port)` is invalid, misspelled, or cannot be resolved by your system's DNS.","error":"socket.gaierror: [Errno -2] Name or service not known"},{"fix":"Ensure the pattern you are searching for is exactly present in the input you're examining (e.g., from a crash dump). The `cyclic` pattern generated might be too short, or the offset is outside the range searched.","cause":"The `cyclic_find()` function could not locate the specific unique pattern (often used to find offsets in buffer overflows) within the provided input.","error":"IndexError: cyclic_find could not find pattern"}]}