服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

CVE-2023-23638 Apache Dubbo JavaNative反序列化漏洞分析

日期: 来源:零组攻防实验室收集编辑:jweny

一、漏洞简介

Apache Dubbo 是一款开源的一个高性能的 Java RPC 框架,致力于提供高性能透明化的 RPC 远程服务调用方案,常用于开发微服务和分布式架构相关的需求。

Apache Dubbo Provider 默认使用 Hession 反序列化机制与 Consumer 进行通信。本漏洞通过动态修改 Dubbo Configuration 启用 JavaNative,然后利用 Hession 反序列化触发特定 Gadget ,最终导致远程代码执行。

影响范围:

  • Apache Dubbo 2.7.x <= 2.7.21

  • Apache Dubbo 3.0.x <= 3.0.13

  • Apache Dubbo 3.1.x <= 3.1.5

二、漏洞环境搭建

漏洞环境可参考 lz2y 师傅文章 CVE-2021-3017

Step1: 启动 zookeeeper

Step2: 启动 dubbo provider。注册接口  demoService,方法为 sayHello。

三、漏洞分析

3.1 请求处理逻辑

Apache Dubbo 默认支持泛化引用由服务端 API 接口暴露的所有方法,这些调用统一由 GenericFilter 处理。GenericFilter 将根据客户端提供的接口名、方法名、方法参数类型列表,根据反射机制获取对应的方法,再根据客户端提供的反序列化方式将参数进行反序列化成 pojo 对象。

Dubbo 处理请求的完整处理过程如下:

validateClass:110, SerializeClassChecker (org.apache.dubbo.common.utils)
realize0:398, PojoUtils (org.apache.dubbo.common.utils)
realize:220, PojoUtils (org.apache.dubbo.common.utils)
realize:107, PojoUtils (org.apache.dubbo.common.utils)
invoke:96, GenericFilter (org.apache.dubbo.rpc.filter)
invoke:61, FilterNode (org.apache.dubbo.rpc.protocol)
invoke:38, ClassLoaderFilter (org.apache.dubbo.rpc.filter)
invoke:61, FilterNode (org.apache.dubbo.rpc.protocol)
invoke:41, EchoFilter (org.apache.dubbo.rpc.filter)
invoke:61, FilterNode (org.apache.dubbo.rpc.protocol)
reply:145, DubboProtocol$1 (org.apache.dubbo.rpc.protocol.dubbo)
received:152, DubboProtocol$1 (org.apache.dubbo.rpc.protocol.dubbo)
received:177, HeaderExchangeHandler (org.apache.dubbo.remoting.exchange.support.header)
received:51, DecodeHandler (org.apache.dubbo.remoting.transport)
run:57, ChannelEventRunnable (org.apache.dubbo.remoting.transport.dispatcher)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:41, InternalRunnable (org.apache.dubbo.common.threadlocal)
run:748, Thread (java.lang)

Dubbo 使用 DecodeHandler#received 方法接受来自 socket 的连接,当收到请求时会先调用 DecodeHandler#decode 处理请求。

decode 完成之后,将调用 HeaderExchangeHandler#received,若为泛型引用,经过FilterNode、ClassLoaderFilter,最终调用 GenericFilter#invoke 方法。

invoke 函数会对传入的 Invocation 对象进行校验:

  • 要求方法名等于 $invoke 或 $invoke_async

  • 要求参数长度 3

  • 要求invoker 的接口不能继承自 GenericService

校验通过后会通过 getArguments() 方法获取参数。第一个参数为方法名,第二个参数为方法名的类型,第三个参数为args。

然后通过 findMethodByMethodSignature 反射寻找服务端提供的方法(也就是章节2漏洞环境中的 sayHello 方法),如果没找到将抛出异常。

然后,通过获取请求中的 generic 参数来选择通过哪种方式将反序列化参数成 pojo 对象。一共有以下几种类型:

  • DefaultGenericSerialization(true)

  • JavaGenericSerialization(nativejava)

  • BeanGenericSerialization(bean)

  • ProtobufGenericSerialization(protobuf-json)

  • GenericReturnRawResult(raw.return)

通过 notice 可知,NativeJava 方式是默认被禁止的。如果启用了 NativeJava 反序列化,就会调用 deserialize.readObject 触发反序列化。

3.2 JavaNative

GenericFilter#invoke 函数实现了不同的 generic 相应的反序列化逻辑。最后当 generic 为 raw.return 类型时,会进入 PojoUtils.realize。

PojoUtils.realize 对参数进行反序列化操作。函数传入的是 Object 类型的对象数组,即可以传入所有类,并且是处理多组需要序列化的数据,传入的 objs 为从 inv 中获取的参数,如果三组长度不相等,即传入的参数不匹配,则抛出异常。然后对传入的对象生成一个 Object 数组,然后对 Object 数组进行遍历,以便对传入的所有项继续进行序列化操作。

进入到三个参数的重载方法,继续进行反序列化,使用 realize0 方法进行反序列化。realize0 方法中实现了通过反射调用 set 方法。

回过头来再看 GenericFilter#invoke ,判断 JavaNative 是否开启是通过判断 Configuration 的 dubbo.security.serialize.generic.native-java-enable

3.3 漏洞利用

总结一下我们现在有以下条件:

  1. 构造 generic 为 raw.return ,就能调用特定类的 set 方法

  2. 将 Configuration 的 dubbo.security.serialize.generic.native-java-enable 属性设置为 True 即可启用 JavaNative

  3. 利用 JavaNative 反序列化执行 payload

所以现在的关键在于找到一个类能够通过 set 方法修改 Configuration ,整条路就通了。

还真的有一个这样的类 org.apache.dubbo.common.utils

public class ConfigUtils {
...
public static void setProperties(Properties properties) {
    PROPERTIES = properties;
}
...
}  

所以整体利用流程为:

  1. 构造 properties 设置 dubbo.security.serialize.generic.native-java-enable 为 True

  2. 构造 generic 为 raw.return ,反射调用 org.apache.dubbo.common.utilssetProperties(properties),启用 JavaNative

  3. 利用 JavaNative 执行反序列化 payload

    private static void enableJavaNative(Hessian2ObjectOutput out) throws IOException {
      Properties properties = new Properties();
      properties.setProperty("dubbo.security.serialize.generic.native-java-enable","TRUE");
      HashMap jndi = new HashMap();
      jndi.put("class", "org.apache.dubbo.common.utils.ConfigUtils");
      jndi.put("properties", properties);
      out.writeObject(new Object[]{jndi});
      HashMap map = new HashMap();
      map.put("generic", "raw.return");
      out.writeObject(map);
  }

四、补丁分析

2.7.21-2.7.12更新链接:

https://github.com/apache/dubbo/commit/4f664f0a3d338673f4b554230345b89c580bccbb

补丁新增了一个properties 配置 CLASS_DESERIALIZE_CHECK_SERIALIZABLE 和 序列化类检查函数 SerializeClassChecker ()

String CLASS_DESERIALIZE_CHECK_SERIALIZABLE = "dubbo.application.check-serializable";

CLASS_DESERIALIZE_CHECK_SERIALIZABLE 默认值为 true

SerializeClassChecker#validateClass 函数将校验当前类是否可序列化。由于本次利用的 org.apache.dubbo.common.utils 为非序列化类,将会直接返回 error。

在 realize0() 和 JavaBeanSerializeUtil 中均调 validateClass 用当前类进行校验。

测试修复后的版本:

五、其他

本文分析了通过 generic 为 raw.return 时,通过 org.apache.dubbo.common.utils 修改 Configuration 来启用 JavaNative。根据补丁来看,generic 为 bean 时也可能利用,有兴趣的师傅可自己探索其他利用链。

六、参考

相关阅读

  • 综述 | 数据库系统参数调优方法

  • 数据库系统参数调优方法综述摘要 数据库系统具有大量的配置参数,参数配置不同会导致系统运行时很大的性能差异. 参数优化技术通过选择合适的参数配置,能够提升数据库对
  • Midjourney AI 常用命令

  • 前言目前 MidjourneyAI 训练本身没有太大的技术难度,可以作为准入门级来使用,想要玩好需要花点时间研究和整理,近期也写了很多经验与一些使用方法,感谢大家喜欢。最近发现,文章会
  • ChatGPT相关黑话,再不知道就太晚了!

  • 宋星最新线上&线下课报名中点击上方图片了解详情本来准备一篇文章搞定的,发现能讲的还挺多的。所以,先写这一篇,后面再续!都是很重要的概念!请放心,这篇文章不是ChatGPT 生成的。
  • 从源码看Flutter BuildContext的秘密

  • 点击上方蓝字关注我,知识会给你力量我们每次在写Flutter代码的时候,都会看到这个参数——BuildContext,在Android开发中,也经常看见一个类似的东西——Context,它们是不是一样的
  • 【第2897期】ECMAScript 2023 有哪些更新?

  • 前言阴雨绵绵的开始。今日前端早读课文章由 @CUGGZ 分享,公号:前端充电宝授权。正文从这开始~~ECMAScript 规范每年都会更新一次,ECMAScript 2023 预计将于 6 月左右获得批准,这将
  • Spring Boot 关于日期时间格式化处理方式总结

  • 关注我,回复关键字“spring”,免费领取Spring学习资料。来源:juejin.im/post/5e62817fe51d4526d05962a2项目中使用LocalDateTime系列作为DTO中时间的数据类型,但是SpringMVC收到

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 手术前后,为啥不让吃东西?

  • 手术前后“饿肚子”,是为了保命。麻醉过程、手术操作、特殊体位、血压的波动等都有可能引起呕吐。所以手术前禁食,主要是为了防止在麻醉或手术过程中出现呕吐反应而引起窒息或
  • 蒙藏学校旧址开放! | 朝闻北京

  • ↑点击上方“北京发布”,订阅权威信息!小布提醒您今日车辆限行尾号2和7天气晴,气温9°C~24°C1蒙藏学校旧址开放!首个“中华民族共同体体验馆”亮相昨天,位于西城区小石虎胡同的
  • 黑龙江省2023年上半年书画等级考试开始报名了

  • 3月28日,记者从黑龙江省招生考试院获悉,2023年上半年书画等级考试将于5月20日至21日举行。据了解,书画等级考试是教育部教育考试院主办的,目的在于继承中华优秀传统文化,普及书画
  • 重拳出手!严厉整治!通报曝光!

  • 28日,国务院新闻办公室举行新闻发布会,国家互联网信息办公室有关负责人介绍2023年“清朗”系列专项行动相关情况,专项行动将聚焦“自媒体”乱象等方面问题开展整治。其中包括:■
  • 启动!黑龙江将选择2至3个

  • 国家卫健委、国家发改委、财政部等七部门近日印发《紧密型城市医疗集团建设试点工作方案》今年将在每个省份选择2到3个设区的市进行试点今年上半年试点城市将完成紧密型城市