# BROP - Blind Return Oriented Programming

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[NFT](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

## 基本信息

此攻击的目标是能够**利用ROP通过缓冲区溢出而无需有关易受攻击的二进制文件的任何信息**。\
此攻击基于以下情景：

* 存在堆栈漏洞并且知道如何触发它。
* 一个在崩溃后重新启动的服务器应用程序。

## 攻击

### **1. 查找易受攻击的偏移量**，发送一个额外字符直到检测到服务器发生故障

### **2. 暴力破解canary** 以泄漏它

### **3. 暴力破解存储的RBP和RIP**地址以泄漏它们

您可以在[这里（BF分叉和线程化堆栈Canaries）](/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md)和[这里（BF地址在堆栈中）](/binary-exploitation/common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md)找到有关这些过程的更多信息。

### **4. 查找停止gadget**

这个gadget基本上允许确认通过ROP gadget执行了一些有趣的操作，因为执行没有崩溃。通常，这个gadget将是一些**停止执行**的内容，并且当寻找ROP gadget以确认特定ROP gadget已执行时，它将位于ROP链的末尾。

### **5. 查找BROP gadget**

此技术使用[**ret2csu**](/binary-exploitation/rop-return-oriented-programing/ret2csu.md) gadget。这是因为如果在一些指令中访问此gadget，则可以获得控制\*\*`rsi`**和**`rdi`\*\*的gadgets：

<figure><img src="/files/14onVS4yiC5ngKbfdNtF" alt="" width="278"><figcaption><p><a href="https://www.scs.stanford.edu/brop/bittau-brop.pdf">https://www.scs.stanford.edu/brop/bittau-brop.pdf</a></p></figcaption></figure>

这些将是gadgets：

* `pop rsi; pop r15; ret`
* `pop rdi; ret`

请注意，使用这些gadgets可以**控制函数的2个参数**。

还要注意，ret2csu gadget具有**非常独特的签名**，因为它将从堆栈中弹出6个寄存器。因此，发送如下链：

`'A' * 偏移量 + canary + rbp + ADDR + 0xdead * 6 + STOP`

如果**执行STOP**，这基本上意味着使用了一个从堆栈中弹出6个寄存器的地址。或者使用的地址也是一个STOP地址。

为了**排除这种可能性**，执行一个新链如下，它不应执行STOP gadget以确认先前的链确实弹出了6个寄存器：

`'A' * 偏移量 + canary + rbp + ADDR`

知道ret2csu gadget的地址后，就可以**推断出控制`rsi`和`rdi`的gadgets的地址**。

### 6. 查找PLT

PLT表可以从0x400000或从堆栈中的**泄漏的RIP地址**（如果使用**PIE**）开始搜索。表的**条目**以16B（0x10B）分隔，当调用一个函数时，即使参数不正确，服务器也不会崩溃。此外，检查**PLT + 6B中的条目地址也不会崩溃**，因为这是第一个执行的代码。

因此，可以通过检查以下行为来找到PLT表：

* `'A' * 偏移量 + canary + rbp + ADDR + STOP` -> 无崩溃
* `'A' * 偏移量 + canary + rbp + (ADDR + 0x6) + STOP` -> 无崩溃
* `'A' * 偏移量 + canary + rbp + (ADDR + 0x10) + STOP` -> 无崩溃

### 7. 查找strcmp

**`strcmp`函数将寄存器`rdx`设置为要比较的字符串的长度。请注意，`rdx`是第三个参数，我们需要它大于0**，以便稍后使用`write`泄漏程序。

可以根据其行为在PLT中找到\*\*`strcmp`\*\*的位置，利用我们现在可以控制函数的前两个参数的事实：

* strcmp(<非读取地址>, <非读取地址>) -> 崩溃
* strcmp(<非读取地址>, <读取地址>) -> 崩溃
* strcmp(<读取地址>, <非读取地址>) -> 崩溃
* strcmp(<读取地址>, <读取地址>) -> 无崩溃

可以通过调用PLT表的每个条目或使用**PLT慢路径**来检查这一点，该慢路径基本上包括调用PLT表中的一个条目 + 0xb（调用\*\*`dlresolve`**），然后在堆栈中跟随希望探测的**条目编号\*\*（从零开始）以扫描所有PLT条目：

* strcmp(<非读取地址>, <读取地址>) -> 崩溃
* `b'A' * 偏移量 + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> 将崩溃
* strcmp(<读取地址>, <非读取地址>) -> 崩溃
* `b'A' * 偏移量 + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
* strcmp(<读取地址>, <读取地址>) -> 无崩溃
* `b'A' * 偏移量 + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`

请记住：

* BROP + 0x7指向\*\*`pop RSI; pop R15; ret;`\*\*
* BROP + 0x9指向\*\*`pop RDI; ret;`\*\*
* PLT + 0xb指向调用**dl\_resolve**。

找到`strcmp`后，就可以将\*\*`rdx`\*\*设置为大于0的值。

{% hint style="success" %}
请注意，通常`rdx`将已经包含大于0的值，因此此步骤可能不是必需的。
{% endhint %}

\### 8. 寻找Write函数或等效函数

最后，需要一个用于外泄数据的gadget，以便外泄二进制文件。此时可以**控制2个参数并设置`rdx`大于0**。

有3个常见的函数可以被滥用：

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

然而，原始论文只提到了\*\*`write`\*\*函数，所以让我们来讨论一下：

当前问题是我们不知道**write函数在PLT中的位置**，也不知道**要发送数据到我们的套接字的fd号码**。

但是，我们知道**PLT表的位置**，可以根据其**行为**找到write。我们可以与服务器创建**多个连接**，并使用**高FD**，希望它与我们的某个连接匹配。

查找这些函数的行为特征：

* `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> 如果有数据打印出来，则找到了puts
* `'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> 如果有数据打印出来，则找到了dprintf
* `'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` -> 如果有数据打印出来，则找到了write

## 自动化利用

* <https://github.com/Hakumarachi/Bropper>

## 参考资料

* 原始论文: <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>


---

# 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://hacktricks.xsx.tw/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.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.
