# BROP - Blind Return Oriented Programming
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
The goal of this attack is to be able to **abuse a ROP via a buffer overflow without any information about the vulnerable binary**.\
This attack is based on the following scenario:
- A stack vulnerability and knowledge of how to trigger it.
- A server application that restarts after a crash.
## Attack
### **1. Find vulnerable offset** sending one more character until a malfunction of the server is detected
### **2. Brute-force canary** to leak it
### **3. Brute-force stored RBP and RIP** addresses in the stack to leak them
You can find more information about these processes [here (BF Forked & Threaded Stack Canaries)](../common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md) and [here (BF Addresses in the Stack)](../common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md).
### **4. Find the stop gadget**
This gadget basically allows to confirm that something interesting was executed by the ROP gadget because the execution didn't crash. Usually, this gadget is going to be something that **stops the execution** and it's positioned at the end of the ROP chain when looking for ROP gadgets to confirm a specific ROP gadget was executed
### **5. Find BROP gadget**
This technique uses the [**ret2csu**](ret2csu.md) gadget. And this is because if you access this gadget in the middle of some instructions you get gadgets to control **`rsi`** and **`rdi`**:
These would be the gadgets:
- `pop rsi; pop r15; ret`
- `pop rdi; ret`
Notice how with those gadgets it's possible to **control 2 arguments** of a function to call.
Also, notice that the ret2csu gadget has a **very unique signature** because it's going to be poping 6 registers from the stack. SO sending a chain like:
`'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP`
If the **STOP is executed**, this basically means an **address that is popping 6 registers** from the stack was used. Or that the address used was also a STOP address.
In order to **remove this last option** a new chain like the following is executed and it must not execute the STOP gadget to confirm the previous one did pop 6 registers:
`'A' * offset + canary + rbp + ADDR`
Knowing the address of the ret2csu gadget, it's possible to **infer the address of the gadgets to control `rsi` and `rdi`**.
### 6. Find PLT
The PLT table can be searched from 0x400000 or from the **leaked RIP address** from the stack (if **PIE** is being used). The **entries** of the table are **separated by 16B** (0x10B), and when one function is called the server doesn't crash even if the arguments aren't correct. Also, checking the address of a entry in the **PLT + 6B also doesn't crash** as it's the first code executed.
Therefore, it's possible to find the PLT table checking the following behaviours:
- `'A' * offset + canary + rbp + ADDR + STOP` -> no crash
- `'A' * offset + canary + rbp + (ADDR + 0x6) + STOP` -> no crash
- `'A' * offset + canary + rbp + (ADDR + 0x10) + STOP` -> no crash
### 7. Finding strcmp
The **`strcmp`** function sets the register **`rdx`** to the length of the string being compared. Note that **`rdx`** is the **third argument** and we need it to be **bigger than 0** in order to later use `write` to leak the program.
It's possible to find the location of **`strcmp`** in the PLT based on its behaviour using the fact that we can now control the 2 first arguments of functions:
- strcmp(\, \) -> crash
- strcmp(\, \) -> crash
- strcmp(\, \) -> crash
- strcmp(\, \) -> no crash
It's possible to check for this by calling each entry of the PLT table or by using the **PLT slow path** which basically consist on **calling an entry in the PLT table + 0xb** (which calls to **`dlresolve`**) followed in the stack by the **entry number one wishes to probe** (starting at zero) to scan all PLT entries from the first one:
- strcmp(\, \) -> crash
- `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> Will crash
- strcmp(\, \) -> crash
- `b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
- strcmp(\, \) -> no crash
- `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
Remember that:
- 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**.
Having found `strcmp` it's possible to set **`rdx`** to a value bigger than 0.
> [!TIP]
> Note that usually `rdx` will host already a value bigger than 0, so this step might not be necesary.
### 8. Finding Write or equivalent
Finally, it's needed a gadget that exfiltrates data in order to exfiltrate the binary. And at this moment it's possible to **control 2 arguments and set `rdx` bigger than 0.**
There are 3 common funtions taht could be abused for this:
- `puts(data)`
- `dprintf(fd, data)`
- `write(fd, data, len(data)`
However, the original paper only mentions the **`write`** one, so lets talk about it:
The current problem is that we don't know **where the write function is inside the PLT** and we don't know **a fd number to send the data to our socket**.
However, we know **where the PLT table is** and it's possible to find write based on its **behaviour**. And we can create **several connections** with the server an d use a **high FD** hoping that it matches some of our connections.
Behaviour signatures to find those functions:
- `'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
- `'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
- `'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
## Automatic Exploitation
- [https://github.com/Hakumarachi/Bropper](https://github.com/Hakumarachi/Bropper)
## References
- Original paper: [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf)
- [https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop)
{{#include ../../banners/hacktricks-training.md}}