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
You can install it with this:
python3 -m pip install pwntoolsFurther 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")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)andr.sendline(bytes): Sends bytes to the terminal. It's the equivalent of typing into the terminal.sendlinealso sends a\nbyte.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
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.
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.