Apache Dubbo反序列化漏洞(CVE-2019-17564)复现分析

漏洞描述

Apache Dubbo是一款高性能Java RPC框架,核心功能是方便面向接口远程过程调用,集群容错和负载均衡,以及服务自动注册与发现。

Apache Dubbo支持多种协议,官方默认为 Dubbo 协议。当用户选择http协议进行通信时,Apache Dubbo 将接受来自消费者远程调用的POST请求并执行一个反序列化的操作。由于此步骤没有任何安全校验,因此可以造成反序列化执行任意代码。

漏洞影响范围:

  • 2.7.0 <= Apache Dubbo <= 2.7.4
  • 2.6.0 <= Apache Dubbo <= 2.6.7
  • Apache Dubbo = 2.5.x

环境搭建

复现环境:win10 + jdk1.8 + idea(搭建dubbo) + zookeeper 3.4.10

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,主要是用来解决分布式应用中经常遇到的一些数据管理问题。

首先先下载zookeeper的压缩包:https://archive.apache.org/dist/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz

然后在解压后的根目录下新建两个文件夹:data和logs,后面配置要用到。

接着修改 conf目录下的zoo_sample.cfg为zoo.cfg,

并添加如下内容,分别为刚刚新建的data和logs目录路径

双击bin目录下的 zkServer.cmd,启动,zookeeper会监听2181端口

zookeeper配置好后,开始搭建dubbo,这里以官方的domo为例:https://github.com/apache/dubbo-samples/tree/master/java/dubbo-samples-http

下载后修改dubbo-samples-http里面的pom.xml

先修改版本为2.7.3,然后添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>

然后导入idea,maven下载依赖构建项目即可。(如果下载时间特别长,可以考虑更换源,方法参考:https://www.cnblogs.com/zaqzzz/p/12443794.html)

最后启动dubbosampleshttpHttpProvider服务,出现dubbo service started 就说明搭建完成了。

复现分析

首先要先通过反序列化工具ysoserial生成payload,保存到calc.ser文件

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections4 "calc" > calc.ser

浏览器访问http://192.168.1.101:8080/org.apache.dubbo.samples.http.api.DemoService 并burp抓包该请求,首先先修改为post类型,接着在post的内容里导入我们刚刚生成的payload,不要直接复制,burp右键Paste from file添加payload

发包,成功弹出了计算器。

下面简单分析下该漏洞,从idea的报错调用栈可以看出,javax.servlet.http.HttpServlet.service应该就是入口

查看javax.servlet.http.HttpServlet.service,在有处理request请求的地方加个断点,如下

重新开启调试模式,burp再次发送攻击请求,来到断点处

跟入来到DispatcherServlet的service方法,通过请求中的端口去获取服务信息,如果没有则返回404 Service not found

下面继续跟入handle方法,由于我们传输的协议是http,所以就进到了HttpProtocol类中对应的handle方法。

然后先判断请求类型是不是为post,如果不是的话就直接返回500。

确定请求类型为post后,根据请求的内容生成HttpInvokerServiceExporter对象,最后再调用其handleRequest方法,跟入查看

这里发现是通过readRemoteInvocation 来处理我们的request请求,继续跟入

这里返回了readRemoteInvocation的结果,继续跟入

可以看到,这里先是获取了我们request请求的数据流,接着传入到了doReadRemoteInvocation方法,跟入查看

可以看到反序列化入口了,这里直接调用了Readobject,整个攻击请求的处理流程基本清晰了,这个漏洞其实并不复杂,修复的话可以直接升级到2.7.5以上,或者关闭http协议,其他的思路的话还可以考虑用jsonrpc的处理,而不是通过httpinvoker,这样的话就没办法处理我们的java序列化字节流从而抛出异常。

reference:

http://www.lmxspace.com/2020/02/16/Apache-Dubbo反序列化漏洞(CVE-2019-17564)

乐观的悲观主义者。
原文地址:https://www.cnblogs.com/v1ntlyn/p/13767814.html