Skip to content

Instantly share code, notes, and snippets.

@pawnlord
Last active September 21, 2025 21:28
Show Gist options
  • Select an option

  • Save pawnlord/69f373d9d30f7116177cb5de49a9f684 to your computer and use it in GitHub Desktop.

Select an option

Save pawnlord/69f373d9d30f7116177cb5de49a9f684 to your computer and use it in GitHub Desktop.

Intro to Pwn Syntax Helper

pwntools

Some basic syntax to get you started with using pwntools in python scripts.
Official documentation for further reading: https://docs.pwntools.com/en/stable/intro.html#tutorials

Getting started

You can install it with this:

python3 -m pip install pwntools

Further instructions if that doesn't work: https://docs.pwntools.com/en/stable/install.html

To import the entire library, run:

from pwn import *

You can connect to a remote (to run your final exploit) with:

r = remote("your.domain.name.here", <port_number>)

You can also run the local process in the same way with:

r = process("chal")

Interacting with the program

The main way you interact is by reading until your read some data, and then sending some data in return. Here's a basic list of commands:

  • r.send(bytes) and r.sendline(bytes): Sends bytes to the terminal. It's the equivalent of typing into the terminal. sendline also sends a \n byte.
  • r.recvline(): Returns a single line of output from the program.
  • r.recvuntil(bytes): Waits until the given bytes is outputted, and returns everything.
  • r.interactive(): Gives you a terminal to interact with the program with, as if you were using netcat

Sending and receiving binary

A lot of the time in CTFs, we want to send integer values instead of the normal ASCII. Say you want to change a return address to 0x401020. You could manually convert this to b'\x20\x10\x40, but doing this for everything is a hassle. Instead, we can use the p64 and u64 functions.

  • p64(0x401020) = b'\x20\x10\x40\x00\x00\x00\x00\x00'
  • u64(b'\x20\x10\x40\x00\x00\x00\x00\x00') = 0x401020

The functions also have 32-bit varieties for ints.

pwninit

Follow installation here: https://github.com/io12/pwninit?tab=readme-ov-file#install
Sometimes, you will be given a binary that uses a different libc on remote. Sometimes this is given with the challenge, sometimes you can get it from the dockerfile. When you have it, you can run this command to get the initialized binary:

pwninit --bin <binary_name> --libc <libc_name> [--ld <ld_name>]

(note: <> means to replace the argument with the filename of whats inside. [] means its optional, and can be ignored if you don't have the ld)
This will produce a file named <binary_name>_patched. Note it also creates a solve.py, but you don't need to use this.

If it is in the docker file, then the correct one is usually in a subdirectory created by nsjail or pwnjail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment