Apache Dubbo 反序列化漏洞
早在2019年开发者社区就有谈到这个 http 协议漏洞问题,近期360灵腾安全实验室判断漏洞等级为高,利用难度低,威胁程度高。建议升级 dubbo 版本,避免遭受黑客攻击。
Unsafe deserialization occurs within a Dubbo application which has HTTP remoting enabled. An attacker may submit a POST request with a Java object in it to completely compromise a Provider instance of Apache Dubbo, if this instance enables HTTP.
简单的说,就是HTTP remoting 开启的时候,存在反序列化漏洞。Apache Dubbo在接受来自消费者的远程调用请求的时候存在一个不安全的反序列化行为,最终导致了远程任意代码执行。
影响版本:
创建一个 Dubbo 服务提供者代码。暴出的漏洞是 http 协议的,故使用 http 的 demo 来重现
注:可自己简单写一个,也可官网下载 demo
https://github.com/apache/dubbo-samples/tree/master/java/dubbo-samples-http
dubbo 版本改成 2.7.5 之前的版本,比如:2.7.3. 在项目 pom 中添加 commons-collections4 依赖(测试漏洞用,主要用于反序列化)
启动服务,可以看大 dubboadmin上有个服务注册了
image
下载反序列化工具 ysoserial 利用漏洞执行 相关服务器上的命令,例如这里是启动计算器, ysoserial可以随意生成一个序列化文件,如下:
https://repository.mulesoft.org/nexus/content/repositories/public/com/github/frohoff/ysoserial/0.0.5/ysoserial-0.0.5.jar
生成漏洞代码保存到 payload.ser 中:(可以调用 windows 的计算器程序)
调用 provider
这里使用的是 postman 发包,也可使用 burp 发包。
https://www.postman.com/downloads/
发数据包的时候选择上一步生成的进制文件 payload.ser,会发现
demo 执行报错如下:
dubbo 在进行 HTTP 协议进行数据传输时,使用的时 Java 序列化。使用 wireshark 抓包可以看到 ,从 ContentType: application/x-java-serialized-object 和报文 Body 部分的 ASCII 码可以看出,使用的是 Java Serialize 序列化。如果伪造了一个序列号的对象进入请求数据报文,然后伪造对象被反序列化出来后执行了,就造成了侵入,形成漏洞。
看 2.5.10 HttpProtocol 的 handle 方法实现
原因是使用的是 spring httpinvoker 功能 HttpInvokerServiceExporter
https://docs.spring.io/spring/docs/5.0.4.RELEASE/spring-framework-reference/integration.html#remoting-httpinvoker
spring httpinvoker 做了风险提示:
大致意思是,由于不安全的 Java 反序列化而导致的漏洞:操纵输入流可能会在反序列化步骤中导致服务器上不必须的代码执行。
继续查看 skeleton.handleRequest(request, response); 的实现。
ois.readObject(); 读取数据全程过程中没有做任何的检查和过滤,直接使用的是readObject 方法直接反序列化 ,这个过程在如果没有校验和过滤,导致如果传入了序列化对象可以被反序列对象创建,漏洞就触发了。
避免实现反序列化,对请求报文不进行反序列化处理。
看下 dubbo 2.7.7 之后的 HttpPrptocol 实现。
看下 handle 怎么处理的 使用的是 JsonRpcServer 的 handle 方法
JsonRpcServer 类的 handle 方法处理之后,request.getInputStream() 没有再被反序列化,被篡改的序列化对象,无法被反序列化,这样漏洞就失效了。
https://mp.weixin.qq.com/s/4IE2aQ_3QWiS4O7Wohc51w