Ret2win
基本信息
Ret2win 挑战是 Capture The Flag (CTF) 竞赛中的一个热门类别,特别是在涉及 二进制利用 的任务中。目标是利用给定二进制文件中的漏洞,执行一个特定的、未被调用的函数,通常命名为 win
、flag
等。当这个函数被执行时,通常会打印出一个标志或成功消息。挑战通常涉及覆盖栈上的 返回地址,以将执行流转向所需的函数。以下是更详细的解释和示例:
C 示例
考虑一个简单的 C 程序,其中存在一个漏洞和一个我们打算调用的 win
函数:
要在没有栈保护和禁用ASLR的情况下编译此程序,可以使用以下命令:
-m32
: 将程序编译为32位二进制文件(这不是必需的,但在CTF挑战中很常见)。-fno-stack-protector
: 禁用对栈溢出的保护。-z execstack
: 允许在栈上执行代码。-no-pie
: 禁用位置无关可执行文件,以确保win
函数的地址不变。-o vulnerable
: 将输出文件命名为vulnerable
。
使用Pwntools的Python利用
对于利用,我们将使用pwntools,这是一个强大的CTF框架,用于编写利用脚本。利用脚本将创建一个有效载荷,以溢出缓冲区并用win
函数的地址覆盖返回地址。
要找到 win
函数的地址,您可以使用 gdb、objdump 或任何其他允许您检查二进制文件的工具。例如,使用 objdump
,您可以使用:
该命令将显示 win
函数的汇编代码,包括其起始地址。
Python 脚本发送一个精心构造的消息,当 vulnerable_function
处理时,会溢出缓冲区并用 win
的地址覆盖栈上的返回地址。当 vulnerable_function
返回时,它不会返回到 main
或退出,而是跳转到 win
,并打印消息。
保护措施
PIE 应禁用,以确保地址在执行之间是可靠的,否则函数存储的地址可能并不总是相同,您需要一些 leak 来确定
win
函数加载的位置。在某些情况下,当导致溢出的函数是read
或类似函数时,您可以进行 部分覆盖 1 或 2 字节,以将返回地址更改为win
函数。由于 ASLR 的工作方式,最后三个十六进制半字节不会随机化,因此有 1/16 的机会(1 个半字节)获得正确的返回地址。栈金丝雀 也应禁用,否则被破坏的 EIP 返回地址将永远不会被跟随。
其他示例与参考
32位,无 ASLR
64 位,带 ASLR,带 bin 地址的 leak
64 位,无 ASLR
32 位,无 ASLR,双小溢出,第一次溢出栈并增大第二次溢出的大小
32 位,relro,无金丝雀,nx,无 pie,格式字符串覆盖地址
fflush
为win
函数(ret2win)32 位,nx,其他无,部分覆盖 EIP(1Byte)以调用
win
函数32 位,nx,其他无,部分覆盖 EIP(1Byte)以调用
win
函数该程序仅验证数字的最后一个字节以检查输入的大小,因此只要最后一个字节在允许范围内,就可以添加任何大小。然后,输入创建一个缓冲区溢出,通过 ret2win 进行利用。
64 位,relro,无金丝雀,nx,pie。部分覆盖以调用
win
函数(ret2win)arm64,PIE,给出一个 PIE leak,
win
函数实际上是两个函数,因此 ROP gadget 调用两个函数ARM64,off-by-one 调用
win
函数
ARM64 示例
Ret2win - arm64Last updated