weblogic CVE-2020-2963、CNVD-2020-23019 反序列化漏洞分析与复现
字数 1668 2025-08-15 21:32:22

WebLogic CVE-2020-2963 和 CNVD-2020-23019 反序列化漏洞分析与复现

漏洞概述

这两个漏洞都是2020年5月发布的补丁修复的反序列化漏洞,存在于Oracle WebLogic Server中:

  1. CNVD-2020-23019 - 影响SOAPInvokeState类的反序列化过程
  2. CVE-2020-2963 - 影响WlsSSLAdapter类的反序列化过程

这两个漏洞都涉及不安全的反序列化操作,可能导致远程代码执行。

漏洞原理分析

反序列化防御机制

在WebLogic中,默认通过以下机制防御反序列化漏洞:

  • 使用FilterInputStream而非ObjectInputStream进行反序列化
  • FilterInputStream会检查反序列化的类中是否存在可利用的Gadget
  • 通过T3协议反序列化时,默认参数为FilterInputStream

漏洞产生的原因是某些类的readObjectreadExternal方法中直接使用了ObjectInputStream,绕过了安全机制。

CNVD-2020-23019 (SOAPInvokeState)

漏洞点在SOAPInvokeState类的readExternal方法中:

if ((flags & 1) != 0) {
    try {
        len = in.readInt();
        byte[] bytes = new byte[len];
        in.readFully(bytes);
        bytes = EncryptionUtil.decrypt(bytes);
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ObjectInputStream in2 = new ObjectInputStream(bais); // 漏洞点
        this.subject = (AuthenticatedSubject)in2.readObject();
    } catch (Exception var13) {
        (new NonCatalogLogger("WebServices")).warning("Couldn't completely read SOAPInvokeState object", var13);
    }
}

触发条件:

  1. 实例化的SOAPInvokeState对象中包含subject字段
  2. 通过writeExternal方法写入序列化数据时,如果subject != null,会触发上述流程
if (this.subject != null) {
    ByteArrayOutputStream var12 = new ByteArrayOutputStream();
    ObjectOutputStream var13 = new ObjectOutputStream(var12);
    var13.writeObject(this.subject);
    var13.flush();
    byte[] var5 = var12.toByteArray();
    var5 = EncryptionUtil.encrypt(var5);
    var1.writeInt(var5.length);
    var1.write(var5);
}

CVE-2020-2963 (WlsSSLAdapter)

漏洞点在WlsSSLAdapter类的readEncryptedField方法中:

private Object readEncryptedField(ObjectInputStream in) throws IOException, ClassNotFoundException {
    int length = in.readInt();
    if (length <= 0) {
        return in.readObject();
    } else {
        byte[] bytes = new byte[length];
        in.readFully(bytes);
        bytes = EncryptionUtil.decrypt(bytes);
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ObjectInputStream in2 = new ObjectInputStream(bais); // 漏洞点
        return in2.readObject();
    }
}

加密机制分析

加密过程有以下特点:

  1. EncryptionUtil.encrypt会根据Kernel.isServer()决定是否加密
    • 如果为true则加密,否则返回原数据
    • 可通过KernelStatus.setIsServer(true)设置状态
  2. 加密密钥来自SerializedSystemIni.dat文件
    • 路径:DomainDir.getRootDir() + "/security/SerializedSystemIni.dat"
    • 或:DomainDir.getRootDir() + "/SerializedSystemIni.dat"
  3. 需要读取该文件才能正确加密/解密数据

漏洞利用条件

  1. 能够构造恶意序列化数据并通过T3/IIOP等协议发送到WebLogic
  2. 对于CNVD-2020-23019:
    • 需要控制SOAPInvokeState对象的subject字段
  3. 对于CVE-2020-2963:
    • 需要触发readEncryptedField方法
  4. 如果目标使用加密:
    • 需要获取SerializedSystemIni.dat文件
    • 或绕过加密机制

漏洞复现(POC)

CNVD-2020-23019 POC示例

BadAttributeValueExpException exp = null;
try {
    exp = cve_2020_2555.getBadAttributeValueExpException();
} catch (Exception e) {
    e.printStackTrace();
}
out2.writeObject(exp);
out2.flush();
byte[] bytes = baos.toByteArray();
bytes = EncryptionUtil.encrypt(bytes);
out.writeInt(bytes.length);
out.write(bytes);

利用步骤

  1. 构造恶意SOAPInvokeStateWlsSSLAdapter对象
  2. 设置必要的字段触发反序列化流程
  3. 处理加密问题:
    • 设置KernelStatus.setIsServer(true)绕过加密
    • 或获取SerializedSystemIni.dat文件进行正确加密
  4. 通过T3/IIOP协议发送恶意序列化数据

修复方案

  1. 应用Oracle官方补丁
  2. 补丁修改内容:
    • ObjectInputStream替换为FilterInputStream
    • 增加反序列化类检查

参考链接

  1. FortiGuard分析:

总结

这两个漏洞都是由于WebLogic中特定类的不安全反序列化操作导致的,利用条件相对苛刻但危害严重。防御此类漏洞的关键是确保所有反序列化操作都使用安全的FilterInputStream并实施严格的类检查机制。

WebLogic CVE-2020-2963 和 CNVD-2020-23019 反序列化漏洞分析与复现 漏洞概述 这两个漏洞都是2020年5月发布的补丁修复的反序列化漏洞,存在于Oracle WebLogic Server中: CNVD-2020-23019 - 影响 SOAPInvokeState 类的反序列化过程 CVE-2020-2963 - 影响 WlsSSLAdapter 类的反序列化过程 这两个漏洞都涉及不安全的反序列化操作,可能导致远程代码执行。 漏洞原理分析 反序列化防御机制 在WebLogic中,默认通过以下机制防御反序列化漏洞: 使用 FilterInputStream 而非 ObjectInputStream 进行反序列化 FilterInputStream 会检查反序列化的类中是否存在可利用的Gadget 通过T3协议反序列化时,默认参数为 FilterInputStream 漏洞产生的原因是某些类的 readObject 或 readExternal 方法中直接使用了 ObjectInputStream ,绕过了安全机制。 CNVD-2020-23019 (SOAPInvokeState) 漏洞点在 SOAPInvokeState 类的 readExternal 方法中: 触发条件: 实例化的 SOAPInvokeState 对象中包含 subject 字段 通过 writeExternal 方法写入序列化数据时,如果 subject != null ,会触发上述流程 CVE-2020-2963 (WlsSSLAdapter) 漏洞点在 WlsSSLAdapter 类的 readEncryptedField 方法中: 加密机制分析 加密过程有以下特点: EncryptionUtil.encrypt 会根据 Kernel.isServer() 决定是否加密 如果为 true 则加密,否则返回原数据 可通过 KernelStatus.setIsServer(true) 设置状态 加密密钥来自 SerializedSystemIni.dat 文件 路径: DomainDir.getRootDir() + "/security/SerializedSystemIni.dat" 或: DomainDir.getRootDir() + "/SerializedSystemIni.dat" 需要读取该文件才能正确加密/解密数据 漏洞利用条件 能够构造恶意序列化数据并通过T3/IIOP等协议发送到WebLogic 对于CNVD-2020-23019: 需要控制 SOAPInvokeState 对象的 subject 字段 对于CVE-2020-2963: 需要触发 readEncryptedField 方法 如果目标使用加密: 需要获取 SerializedSystemIni.dat 文件 或绕过加密机制 漏洞复现(POC) CNVD-2020-23019 POC示例 利用步骤 构造恶意 SOAPInvokeState 或 WlsSSLAdapter 对象 设置必要的字段触发反序列化流程 处理加密问题: 设置 KernelStatus.setIsServer(true) 绕过加密 或获取 SerializedSystemIni.dat 文件进行正确加密 通过T3/IIOP协议发送恶意序列化数据 修复方案 应用Oracle官方补丁 补丁修改内容: 将 ObjectInputStream 替换为 FilterInputStream 增加反序列化类检查 参考链接 FortiGuard分析: CNVD-2020-23019 CVE-2020-2963 总结 这两个漏洞都是由于WebLogic中特定类的不安全反序列化操作导致的,利用条件相对苛刻但危害严重。防御此类漏洞的关键是确保所有反序列化操作都使用安全的 FilterInputStream 并实施严格的类检查机制。