# PwnTools

PwnTools is a Python library and includes some command-line tools as well. You can install it to your current Python version with the following command:

```bash
python3 -m pip install pwntools
```

The full documentation is available on [docs.pwntools.com](https://docs.pwntools.com/en/stable/):

{% embed url="<https://docs.pwntools.com/en/stable/>" %}
Documentation for the PwnTools library and CLI tools
{% endembed %}

## Builtin binaries

When you install PwnTools, it comes with a few small but useful binaries for binary exploitation. Here are some and how to use them.

### `checksec` - Check security protections

This tool checks a few security-related settings on a binary, which will help you visualize what attacks might work, and which ones won't. You can run it like `checksec ./binary` and see an output like the following:

![](https://3698848315-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F677wrA8ZfiPs1U4l5uR6%2Fuploads%2FzR7U2CuumEV73cynzYGO%2Fimage.png?alt=media\&token=e38f3b09-780e-4189-b417-daacf45449f4)

In this output, green is **safe,** and red is **unsafe**. Note that if these are all green, it does not mean the binary has no vulnerabilities. It just means that you will have to use some other tricks during exploitation. Let's go over what these mean:

#### RELRO (RELocation Read-Only)

RELRO decides whether or not a few sections in the binary are read-only, preventing relocation tables from being overwritten in some cases. There are 3 possible values for this setting:

1. ![](https://3698848315-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F677wrA8ZfiPs1U4l5uR6%2Fuploads%2FqY9s7izfqCMvl9G8PpJO%2Fimage.png?alt=media\&token=f94868cb-c039-49c3-872b-5e271b63f664): The relocation tables are not protected and can be modified at runtime, making the binary vulnerable to GOT and PLT overwrite attacks
2. ![](https://3698848315-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F677wrA8ZfiPs1U4l5uR6%2Fuploads%2Fvo2uamKasJNbki4KQyaW%2Fimage.png?alt=media\&token=d2476df3-fcf8-4f7b-9098-e7d98a241768): The relocation tables are made read-only, but some parts of the GOT are left writeable to allow lazy symbol binding. This still allows some attacks like [ret2dlresolve](https://book.jorianwoltjer.com/binary-exploitation/return-oriented-programming-rop/ret2dlresolve "mention") where this is abused to link arbitrary functions like `system()` in a binary without it. This protection often does not make much of a difference when writing your exploit
3. ![](https://3698848315-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F677wrA8ZfiPs1U4l5uR6%2Fuploads%2FV9LY8uSWWMAJzB2LUwSO%2Fimage.png?alt=media\&token=8362247e-4d4c-45ae-8b1f-9cb6a3ef7cb0): This makes the GOT completely read-only, making any attacks that try to write in it impossible. But it is not always enabled because there is a significant slowdown during the startup of the binary which developers might want to avoid

#### Stack canary

A stack canary is a reference to [canaries in a coal mine](https://en.wikipedia.org/wiki/Sentinel_species#Historical_examples). When a canary got sick, the miners would know it is unsafe here and stop mining. For a binary, it is the same idea: Right before the return address on the stack, a random value is placed. Then before actually returning at the `ret` instruction, it checks if this random value is still the same. If it was overwritten by a buffer overflow the value would change, and then the program would panic and exit before anything malicious can happen.

An attacker would have to guess, or more often leak this value to bypass the check. See [#stack-canaries](https://book.jorianwoltjer.com/stack-canaries#stack-canaries "mention") for more detailed exploit ideas.

#### NX (Non-eXecutable stack)

Sometimes attackers will place shellcode on the stack, within their input. This can then be jumped to if they can control the Instruction Pointer, to execute arbitrary instructions, such as a shell.&#x20;

With NX enabled, the stack is made non-executable to not allow any code to be run that came from the stack. This way, instructions are stored in the code section, and data is stored on the stack/heap.

In this case, an attacker would have to use existing instructions to execute what they want as they cannot add their own, often requiring some sort of [return-oriented-programming-rop](https://book.jorianwoltjer.com/binary-exploitation/return-oriented-programming-rop "mention").&#x20;

#### PIE (Position Independent Executable)

With PIE enabled, the code of the binary will be loaded at a random memory location. This means you cannot use hardcoded addresses for functions or other instructions, as you won't know beforehand at what address they will be.&#x20;

However, everything is offset together, meaning the **relative** addresses stay the same. So if you can leak any code address you can find all the relative addresses from that. If for some reason you can make a relative jump, this also won't stop you.&#x20;

{% hint style="info" %}
The address PwnTools shows for this when it is disabled means the base address the binary will always start from. This address is often `0x400000` by default, but it may be changed in the binary itself.&#x20;
{% endhint %}

### `cyclic` - Create cyclic patterns

This is a simple but very useful one. As explained further in [#dynamic-analysis](https://book.jorianwoltjer.com/reverse-engineering-for-pwn#dynamic-analysis "mention"), the `cyclic` command allows you to generate [de Bruijn sequences](https://en.wikipedia.org/wiki/De_Bruijn_sequence). These are very useful for finding the offset in a buffer overflow, as you can search the value that the instruction pointer is trying to jump to back in the original string to find the exact offset. You can generate a string:

<pre class="language-shell-session"><code class="lang-shell-session"><strong>$ cyclic 200
</strong>aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
</code></pre>

And when you have triggered the vulnerability, you can take the value you find as the instruction pointer and reverse look it up again to find the exact offset in one go:

<pre class="language-shell-session"><code class="lang-shell-session"><strong>$ cyclic -l 0x6161616f
</strong>56
</code></pre>

## Useful syntax

The `pwn` Python library has many useful features, some more known than others. Here is a collection of a few pieces of syntax that can drastically simplify your exploit scripts.&#x20;

Learn it once and you can never go back.

### Importing

```python
from pwn import *
```

Now all the functions and variables of pwntools are imported to the current context.&#x20;

```python
# Run a local binary
p = process("./binary")
# Connect to a remote host using TCP (same as `$ nc 10.10.10.10 1337`)
p = remote("10.10.10.10", 1337)
# Load an ELF binary
libc = ELF("./libc.so.6")
libc = ELF("./libc.so.6", checksec=False)  # Disable the default `checksec` on import

# Load a binary, and then create a process from it
context.binary = elf = ELF("./binary")
p = process()
p = process(aslr=False)  # You can also disable ASLR here
```

### Interaction

```python
# Open an interactive shell like `nc` would (useful at the end / for debugging)
p.interactive()
```

When working with interaction in PwnTools, you should almost exclusively use **bytestings**. These guarantee that your payload or text won't be misinterpreted by UTF-8 conversions, and can be easily created using the `b""` syntax.&#x20;

#### Receiving data

```python
p.recvline()  # Receive until \n
p.recvuntil(b"here it comes: ")  # Receive until custom text
p.recv(42)  # Receive a specific amount of bytes
p.clean()  # Receive all for 0.05 seconds

# In pwntools >= 4.10.0 you can use regex with capture groups to extract text
p.recvregex(rb"0x([0-9a-f]+) and more", capture=True).group(1)
```

#### Sending data

```python
p.sendline(b"Hello, world!")  # Send a line of input
p.send(b"text")  # Send raw bytes (no newline)

p.sendlineafter(b"> ", b"command")  # Send line after some data has been received
```

### Creating payloads

#### Packing

```python
# Pack an integer into bytes (little-endian)
p64(0xdeadbeef)  # b'\xef\xbe\xad\xde\x00\x00\x00\x00'
p32(0xdeadbeef)  # b'\xde\xad\xbe\xef'

# Set endianness to big
context.endian = "big"
p64(0xdeadbeef)  # b'\x00\x00\x00\x00\xde\xad\xbe\xef'
```

#### `flat()`

```python
# Simply concatenate values, and automatically pack them
flat([b"some string", 1337])  # b'some string9\x05\x00\x00\x00\x00\x00\x00'

# Easily put values at specific offsets
flat({
    12: 0xdeadbeef
})  # b'aaaabaaacaaa\xef\xbe\xad\xde'
context.bits = 64  # Based on context variable
flat({
    12: 0xdeadbeef
})  # b'aaaabaaacaaa\xef\xbe\xad\xde\x00\x00\x00\x00'

# You can even put a list of values you want to place there
flat({
    4: [b"some string", 1337],
    32: 0xdeadbeef
})  # b'aaaasome string9\x05\x00\x00\x00\x00\x00\x00agaaahaaa\xef\xbe\xad\xde\x00\x00\x00\x00'
```

{% hint style="info" %}
For more useful syntax related to [return-oriented-programming-rop](https://book.jorianwoltjer.com/binary-exploitation/return-oriented-programming-rop "mention"), see its [#pwntools](https://book.jorianwoltjer.com/return-oriented-programming-rop#pwntools "mention")
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.jorianwoltjer.com/binary-exploitation/pwntools.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
