报告编号:B6-2020-021401
报告来源:360-CERT
报告作者:360-CERT
更新日期:2020-02-14
0x00 漏洞背景
2020年2月12日,360CERT监测到Apache Dubbo官方发布了CVE-2019-17564漏洞通告,漏洞等级中危。
Apache Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。Apache Dubbo支持多种协议,官方默认为 Dubbo 协议,当用户选择http协议进行通信时,Apache Dubbo 在接受来自消费者的远程调用的POST请求的时候会执行一个反序列化的操作,由于没有任何安全校验,于是可以造成反序列化执行任意代码
0x01 架构
节点角色说明
节点 | 角色说明 |
---|---|
Provider | 暴露服务的服务提供方 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
Container | 服务运行容器 |
调用关系说明
- 服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
0x02 环境搭建
官方已经给我们提供了基本样例
git clone https://github.com/apache/dubbo-samples.git
cd dubbo-samples/java/dubbo-samples-http
zookeeper注册中心下载:https://zookeeper.apache.org/releases.html
简单列举服务提供者用到的文件:
公共接口:DemoService.java
package org.apache.dubbo.samples.http.api;
public interface DemoService {
String sayHello(String name);
}
配置文件: spring/http-provider.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder/>
<dubbo:application name="http-provider"/>
<dubbo:registry address="zookeeper://${zookeeper.address:127.0.0.1}:2181"/>
<dubbo:protocol name="http" id="http" port="${servlet.port:8080}" server="${servlet.container:tomcat}"/>
<bean id="demoService" class="org.apache.dubbo.samples.http.impl.DemoServiceImpl"/>
<dubbo:service interface="org.apache.dubbo.samples.http.api.DemoService" ref="demoService" protocol="http"/>
</beans>
服务提供者:HttpProvider.java
package org.apache.dubbo.samples.http;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.concurrent.CountDownLatch;
public class HttpProvider {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/http-provider.xml");
context.start();
System.out.println("dubbo service started");
new CountDownLatch(1).await();
}
}
服务消费者: HttpConsumer.java
package org.apache.dubbo.samples.http;
import org.apache.dubbo.samples.http.api.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HttpConsumer {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/http-consumer.xml");
context.start();
DemoService demoService = (DemoService) context.getBean("demoService");
String result = demoService.sayHello("world");
System.out.println(result);
}
}
- 启动
zookeeper
注册中心 - 运行服务提供者
- 运行服务消费者
0x03 漏洞验证
由于官方样例提供的版本是最新版,无法验证漏洞,于是我们需要还原漏洞版本,修改/dubbo-samples/java/dubbo-samples-http/pom.xml
的dubbo.version
为2.7.3
<properties>
<source.level>1.8</source.level>
<target.level>1.8</target.level>
<!--修改版本为2.7.3-->
<dubbo.version>2.7.3</dubbo.version>
...
exp构造
根据
https://www.mail-archive.com/dev@dubbo.apache.org/msg06225.html
发布的漏洞信息来看,造成漏洞的原因应该是在 POST
请求的时候会执行一个反序列化的操作,那么我们 POST
任意数据,并在处理分派请求的地方下断,/org/apache/dubbo/remoting/http/servlet/DispatcherServlet.java
任意发送一个POST
请求,这里击中了断点
跟进handle
这里需要注意的是,首先初始化了一个skeletonMap
,然后会判断我们请求的path
是否在Map
里,如果不在,skeleton
就会返回null
值,这样调用到skeleton.handleRequest
的时候就会报java.lang.NullPointerException
的错误
于是我们请求的path为/org.apache.dubbo.samples.http.api.DemoService
,这样就能获取到skeleton
的值
继续跟进readRemoteInvocation
这里需要从request
里得到inputStream
,否则无法进入造成漏洞的关键方法:doReadRemoteInvocation
最后看到doReadRemoteInvocation
,对我们的数据进行了反序列化,并且没有做任何安全校验
基于commons-collections-3.2
的gadgets
0x04 版本更新
对skeletonMap
进行了修改,在获取skeleton
之后就会调用JsonRpcBasicServer.hanlde
,JsonRpcBasicServer
是JsonRpcServer
的父类,在该类中没有反序列化的危险操作
0x05 修复建议
- 通用修补建议:升级到2.7.5版本,https://github.com/apache/dubbo/tree/dubbo-2.7.5
- 临时修补建议:禁用http协议
0x06 相关空间测绘数据
360安全大脑-Quake网络空间测绘系统通过对全网资产测绘
可以发现 Apache Dubbo
框架在国内得到广泛的使用。
0x07 产品侧解决方案
360城市级网络安全监测服务
360安全大脑的QUAKE资产测绘平台通过资产测绘技术手段,对该类漏洞进行监测,请用户联系相关产品区域负责人获取对应产品。
360AISA全流量威胁分析系统
360AISA基于360海量安全大数据和实战经验训练的模型,进行全流量威胁检测,实现实时精准攻击告警,还原攻击链。
目前产品具备该漏洞/攻击的实时检测能力。