# Blind Return Oriented Programming - BROP

{% hint style="info" %}
This technique was found by **Andrea BITTAU** from Stanford in 2014.
{% endhint %}

**B**lind **R**eturn **O**riented **P**rogramming (**BROP**) is basically a [ROP](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/return-oriented-programming-rop) attack where the attacker doesn't had access to the binary.

## How it works ?

In order to use the BROP attacks two requirements are needed :

* a [stack overflow](https://www.ctfrecipes.com/pwn/stack-exploitation/stack-buffer-overflow)
* a service that restarts after a crash

Based on whether **a service crashes or not** (i.e., connection closes or stays open), the **BROP attack is able to construct a full remote exploit** that leads to a shell **by leaking** enough **gadgets** to perform the **write system call,** after which the binary is transferred from memory to the attacker's socket. Following that, a standard [ROP](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/return-oriented-programming-rop) attack can be carried out.

In short, **BROP** attack has the following phases:

1. \*\*\*\*[**Stack reading**](https://www.ctfrecipes.com/pwn/stack-exploitation/stack-buffer-overflow/stack-reading): read the stack to **leak canaries** and a **return address** to defeat ASLR.
2. **Blind ROP**: find enough gadgets to invoke write and control its arguments.
3. **Build the exploit**: dump enough of the binary to find enough gadgets and then doing a standard [ROP ](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/return-oriented-programming-rop)exploit

{% hint style="danger" %}
If the server is compiled with the [PIE](https://www.ctfrecipes.com/pwn/protections/pie) flag or if there is a [stack canary](https://www.ctfrecipes.com/pwn/protections/stack-canaries), the server must be a **forking** daemon.
{% endhint %}

## Needed gadgets

### Stop gadget

Because of "blind" exploit, something is needed to **highlight when something useful was found.** Here take place the **stop gadget.**

Essentially, this gadget does not cause the program to crash, and either prints out something or stays in an infinite loop.

From the perspective of the testing, a service crashing or just finishing execution looks the same. By setting the **stop gadget as the return address** of an address being tested, it can be determined whether the tested instructions actually caused the service to crash or if they simply finished executing.

```bash
   Buffer   | return address | stack...
0x4141...41 | 0x40000000     | 0xdead 0xdead 0xdead ... | --> Crash
0x4141...41 | 0x40000000     | 0xstop 0xdead 0xdead ... | --> No crash
                   |              |
                   |              V
                   V            sleep
          Tested gadget address
                   
```

{% hint style="info" %}
To find a `pop X; ret;` gadget, the stop gadgets must be placed one slot further to handle the `pop` instruction:

```bash
   Buffer   | return address | stack...
0x4141...41 | 0x40000000     | 0xdead 0xdead 0xdead ... | --> Crash
0x4141...41 | 0x40000000     | 0xdead 0xstop 0xdead ... | --> No crash
                   |                     |
                   |                     V
                   V                   sleep
          Tested gadget address
                   
```

{% endhint %}

### BROP gadget

As the end of the `__libc_csu_init` function, there is a gadget that pops 6 registers from the stack. ([Ret2csu](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2csu))

To retrieve this gadget, **2 request** are executed for each tested address :

* The first request is : `b'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP`

If the binary doesn't crash the tested address is maybe the BROP gadget, because it will pop the 6 `0xdead` addresses and return into the `STOP` gadget.

But there is a chance that the tested address is a `STOP gadget` itself, so a second request had to be executed, and it must crash to confirm that the tested address isn't a `stop gadget`

* The second request is : `b'A' * offset + canary + rbp + ADDR`

```
   Buffer   | return address     | stack...
0x4141...41 | 0x???????????????? | 0xdead *6     0xSTOP ... | --> Will no Crash
0x4141...41 | 0x???????????????? | 0xdead 0xdead 0xdead ... | --> Will crash
                   |              
                   |              
                   V            
          Tested gadget address
                   
```

### PLT address

Retrieving the base address of the PLT permit to make it easier to found the followed gadgets by using the [ret2dl\_resolve](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve) technique.

In order to retrieve a PLT address, **2 requests** have to be executed to confirm that the tested address is a PLT address:

* `b'A' * offset + canary + rbp + ADDR + STOP` --> will no crash
* `b'A' * offset + canary + rbp + (ADDR + 0x6) + STOP` --> will no crash

To be certain that it's a PLT address, 2 more requests can be done to try if the next possible PLT address (+`0x10`) it's also a valid PLT address

{% hint style="info" %}
A PLT address is always a 0x10 multiple, so it's not necessary to try each possible address, just try every `0x10` addresses.
{% endhint %}

### STRCMP

Most of the time, there is no gadget `pop RDX; ret;` However, the `strcmp` function will set `RDX` to `0` or a value greater than `0` depends on the strings provided as arguments.

**This gadget can be needed to retrieve and use the Write gadget** (basicaly if the function used in the binary is write())**.**

The PLT entries can be identified by exercising each entry with different arguments and seeing how the function performs. The first two arguments can be controlled thanks to the BROP gadget.

`strcmp` has the following behavior and signature, where “bad” is an invalid memory location (e.g., 0x0) and “readable” is a readable pointer (e.g., an address in .text : RIP):

* strcmp(bad, readable): crash
* strcmp(readable, bad): crash
* strcmp(readable, readable): no crash

To retrieve \*\*\*\* `STRCMP gadget` **3 requests** are executed for each tested entry (based on [ret2dl\_resolve](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve) exploit):

* `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` --> Will crash
* `b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` --> Will crash
* `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` --> Will **no** crash

{% hint style="info" %}

* BROP + 0x7 point to **`pop RSI; pop R15; ret;`**
* BROP + 0x9 point to **`pop RDI; ret;`**
* PLT + 0xb point to a call to **dl\_resolve**.
  {% endhint %}

### Write / Puts

A gadget that permit to **write** to the output is needed in order to leak datas.

As for `strcmp` this function will be retrieve using the [ret2dl\_resolve](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve) technique.

There is several function that permit to write to the output and **the signature may differ following which function is used**.

Also, the used file descriptor had to be retrieve.

There is the 3 common signatures :

* `puts(data)`
* `dprintf(fd, data)`
* `write(fd, data, len(data)`

For each entry, it's necessary to try several file descriptor and see if the binary respond more data than before.

To retrieve the `write gadget` 3 requests are executed for each possible file descriptor for each possible entry :

* `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP` --> If there is data printed, then puts was found
* `b'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` --> If there is data printed, then dprintf was found
* `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` --> If there is data printed, then write was found

## Exploiting

At this point the attacker can leak arbitrary data from the binary. Then it's possible to try each addresses until the ELF magic bytes are printed ( `\xb1ELF\x02\x01`). Here is the binary base address.

Finally, it's possible to print each addresses from this point and if there is data printed, then add it as leaked data, if not, in fact there is a null byte ( `0x00` ) at the targeted address, so add it as leaked data and proceed with the next address.

## Resources

* [Original paper](https://www.scs.stanford.edu/brop/bittau-brop.pdf)
* [Slides](https://www.scs.stanford.edu/brop/bittau-brop-slides.pdf)

{% embed url="<https://github.com/Hakumarachi/Bropper>" %}
Automated BROP exploit tool
{% endembed %}
