MiniShare 1.4.1 中存在基于栈的缓冲区溢出,通过单个 HTTP PUT 请求即可触发。
此仓库是我在教授内存损坏利用时所使用的素材的一部分(除了日常工作,我还在多个网络安全课程中任教,帮助培养下一代逆向工程师)。
CVE-2020-13768 是我用来展示简单的面向网络的服务器如何通过标准协议方法暴露经典栈缓冲区溢出的案例。易受攻击的端点无需认证,溢出直接覆盖 EIP,利用路径清晰且定义明确。对于在真实的未认证远程场景中学习完整的利用方法学,这是一个理想案例。
作为一个教学练习,这个案例的有趣之处还在于,同一个二进制文件的基础根因(未经清洗的输入被复制到固定大小的栈缓冲区)出现在多个 CVE 条目中。CVE-2018-19861、CVE-2018-19862 和 CVE-2019-17601 都描述了同一类漏洞,只是由不同的研究人员通过不同的 HTTP 方法或端点报告。这教导学生要关注根本原因,而不仅仅是 CVE 编号。
此漏洞影响 MiniShare 1.4.1,这是一个已停产的轻量级 Windows HTTP 服务器,专为简单的本地文件共享而设计。该软件编写时没有采用现代安全实践。从教学角度来看,此案例特别有趣,因为它涉及多种因素的组合:
这种组合使 CVE-2020-13768 成为在真实的未认证场景中教授基于网络的缓冲区溢出利用基础知识的绝佳案例。
MiniShare 是一个最小的 Windows HTTP 服务器,最初设计用于在局域网内快速共享本地文件。它监听 TCP 端口 80,并处理包括 GET 和 PUT 在内的少量 HTTP 方法。PUT 处理程序接收传入请求,并将 URI 路径复制到固定大小的栈缓冲区中,而不验证其长度。
关键技术细节:
MiniShare 处理传入的 HTTP 请求,并根据方法将其分派到相应的处理程序。PUT 处理程序从请求中提取 URI 路径,并将其复制到固定大小的栈缓冲区中,而不检查其长度。
易受攻击逻辑的简化版本如下所示:
char path_buffer[256];
strcpy(path_buffer, uri_path);
由于目标缓冲区的大小固定,且输入长度未经验证,在 PUT 请求中发送足够长的 URI 会导致复制操作越过缓冲区末尾,最终到达并覆盖栈上的保存返回地址(EIP)。
当易受攻击的函数返回时,CPU 会从栈中加载攻击者控制的值到 EIP 并跳转到该地址。如果该地址指向包含 shellcode 的攻击者控制数据,则可以实现任意代码执行。
可以通过在 HTTP PUT 请求中发送过大的 URI 来再现崩溃。无需任何认证。使用 Python 的示例:
import socket
HOST = '127.0.0.1'
PORT = 80
payload = b"A" * 3000
request = (
b"PUT /" + payload + b" HTTP/1.1\r\n"
b"Host: 127.0.0.1\r\n"
b"Connection: close\r\n"
b"\r\n"
)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(request)
s.close()
当在调试器中执行时,崩溃会显示 EIP 被用户控制的数据覆盖:
EIP = 41414141
确认保存的返回地址已被溢出破坏。
此仓库的目标不仅是演示崩溃,还要逐步引导完成完整的利用过程,遵循开发真实基于栈的利用时所使用的方法。
为保持主 README 的整洁,详细的利用笔记、脚本和调试器步骤已放置在此仓库的 Vulnerability 📂 文件夹中。
在那里,你将找到用于利用此 CVE 的完整工作流程,包括: