2. Introduction to PEDA and Pwntools

Introduction to PEDA and Pwntools

GDB with PEDA and Pwntools are two tools that we will be using extensively throughout the course. This section is designed to run through their basic use and to work out any possible kinks that might arise.

Throughout the section we will be using pre-built binaries in the build folder. From the base repository directory, please navigate as follows:

ubuntu@ubuntu-xenial:/vagrant$ cd lessons/3_intro_to_tools/
ubuntu@ubuntu-xenial:/vagrant/lessons/3_intro_to_tools$ cd build/

There should be a couple of binaries already in the directory. They are standard ELF files that you can run.

ubuntu@ubuntu-xenial:/vagrant/lessons/3_intro_to_tools/build$ ./1_sample
Hello, I am a sample program.

PEDA

PEDA (Python Exploit Development Assistance) is an extension to GDB that adds on a whole bunch of useful commands and quality of life improvements to the standard GDB experience. The provisioning script should have made the necessary additions to the GDB configuration so all you need to do to start it is launch GDB.

Let's walk through an example with the 1_sample binary.

ubuntu@ubuntu-xenial:/vagrant/lessons/3_intro_to_tools/build$ gdb ./1_sample
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./1_sample...(no debugging symbols found)...done.
gdb-peda$ r
Starting program: /vagrant/lessons/3_intro_to_tools/build/1_sample
Hello, I am a sample program.
[Inferior 1 (process 11030) exited normally]
Warning: not running or target is remote
gdb-peda$

The prompt should show gdb-peda. If it does not, something has gone wrong with the environment setup. To start off, let's break on main and explore what is offered by PEDA.

Notice that the default display is a made lot more informative than with the vanilla GDB. Other than making it a lot easier to step through programs and view the changes as they happen, PEDA provides a ton of other functionality as well. To view the full list of them, you can use the peda command.

We will go through a few of the interesting commands.

checksec

The checksec command lists the protections that are enabled for the binary. This is useful when figuring out how to craft your exploit.

distance

Often, calculating offsets from addresses is required when crafting your payload in an exploit. This command makes it easy to find the distance between two addresses.

elfsymbol

If you ever needed to get the address for certain symbols in a binary (if you are lucky and it is not stripped), you can use the elfsymbol command.

pattern

The pattern generator is one of the features of PEDA I most use. What it does is generate a De Brujin Sequence of a specified length. A De Brujin Sequence is a sequence that has unique n-length subsequences at any of its points. In our case, we are interested in unique 4 length subsequences since we will be dealing with 32 bit registers. This is especially useful for finding offsets at which data gets written into registers.

Let's say we create a pattern of length 64.

Imagine that we have triggered a buffer overflow and find that the instruction pointer crashes on the address 0x48414132 ('2AAH' in ASCII). We can figure out the exact offset of our data to place our address to redirect code execution to.

procinfo

This command parses information from the /proc/pid/x directory and presents it to you.

It is particularly useful to view which file descriptors are open.

vmmap

vmmap displays the memory mapping of the process. It is simple to invoke.

What is important to glean from the listing above is the permissions flags of each of the segments. Often when developing your exploit, you will need to place some data somewhere. This data can be arguments to functions expecting a string pointer or even shellcode. What is required is that the segment that is being written to is marked writable.

Additionally, if you have a pointer from a memory leak and want to figure out where exactly the pointer is pointing to, you can drill down specifically on that address.

find aka searchmem

The find command is an alias for the searchmem peda command. It searches memory for a given pattern. It is particularly useful to figure out where data is or how it flows in a process.

For example, something that is often sought for is the string "/bin/sh". Perhaps it lays in memory somewhere. We can use find to look for it.

Pwntools

Pwntools is a Python library that provides a framework for writing exploits. Typically, it is used heavily in CTFs. There are a ton of useful functions provided by Pwntools but I will briefly describe the process I personally use.

Using Pwntools

There are three ways you can use Pwntools:

  1. Interactively through the python/iPython consoles

  2. In a python script

  3. Pwntools command line tools

Interactively through the Console

Often, you want to try things out before actually writing an actual script when developing your exploit. The iPython console is a great way to explore the Pwntools API. For convenience, we will import everything in the pwn package to the global namespace.

iPython provides tab completion and a built-in system to look up documentation in docstrings. For example, if we want to look at what the p32 function does, we can look it up with the ? sigil.

In a Python Script

I like to begin with the following template when starting a new exploit.

Running the script is as simple as calling python on it. Try running this script:

Running the script:

Pwntools Command Line Tools

Pwntools installs the pwn python script in /usr/local/bin. It provides frontends to useful features of the library. To get a list of all available frontends, you can execute pwn -h.

You can investigate the available options at your own time. Take a look at the documentation for a more detailed description of each of them.

Interacting with Target Binaries

Your target might expose itself through different vectors. Today we will focus on attacking remotely running binaries that you can connect to over the network. First, let's see how we might interact with a local copy of a binary that accepts input on stdin and returns output on stdout.

Local Copy of Binary

To begin with, we will look at the 2_interactive binary:

For completeness sake, here is the source code:

The point of the program is to check the user input against a hardcoded password. If it matches, then an interactive shell is spawned.

Now that we know how to craft the input, we can write our sample exploit using Pwntools.

Take some time to go through the code and understand what it does. Take note of the process("../build/2_interactive") line. It starts a new process and allows you to treat the object like a socket. Run the script and verify it works:

Simulating a Networked Application Locally

It is very easy to turn a console-based application into a networked one and there are multiple ways to do it. The exercises that come later in the docker containers use xinetd, a server daemon, to listen for network requests and then launch the binary to serve these requests. For now, we can use socat to do the same thing.

First, we will start a new screen session so that we can background our socat terminal.

Next, we run the following command to start a listener on port 1330.

It should hang there. Now return to your original bash session by holding down the following key sequence: CTRL-A-D. If you run the command screen -ls you should see that the socat screen session is in the background.

To verify that the listener is indeed listening on port 1330, we can run netcat.

Now, here comes the magic. To modify the first script we had to work with local binaries, we may simply comment out the process() line and replace the line with remote("localhost", 1330).

Now, if we run this it should give us our shell.

Debugging with GDB

Pwntools does provide GDB functionality but we will be taking a more manual approach since that is the way I am used to doing it. If you are interested in using this functionality, you can view the documentation here.

We will be using the 3_reversing binary to walkthrough this section. First, lets run it vanilla.

To gain a deeper insight into what is going on, we can use ltrace to investigate.

Using the following script, we can print the process id before the interaction with the program happens.

First, start another ssh session and run the script. Note the process id that gets printed. Also note the use of p32() to pack integers into little endian strings.

Return to the original bash shell and run GDB as root. Now, we can attach to the process.

At this point, the program is paused somewhere in libc. We can setup our breakpoints. Let's assume that we have done some preliminary reverse engineering and have discovered that the input gets passed to the check_creds(). Here's the disassembly of the function.

Let's place some breakpoints on the function and step through the execution to discover what inputs we need to supply to pass the check.

Back on the terminal with the script running, press enter to trigger the data sending. On the gdb terminal, the debugger should have broken. Continue on with the standard gdb debugging process to obtain the values.

Exercises

Please attempt the exercises in this section on your own before looking at the solution.

Ex 3.1: Getting the Right Name and Token

Continuing on from where we left off in the guided portion, please find the right values for the name and token and modify the exploit code such that a shell is obtained.

Solution script can be found here.

Ex 3.2: Launching the Attack Against a Remote Target

Please find the flag file on an instance of the service running at 127.0.0.1:1900.

Solution script can be found here.

Last updated

Was this helpful?