一、环境搭建

源码:https://github.com/alibaba/Sentinel/releases/tag/v1.8.0

下载源码,修改src/main/resources/application.properties配置文件,添加端口配置

启动src/main/java/com/alibaba/csp/sentinel/dashboard/DashboardApplication.java

访问localhost:9090,密码sentinel/sentinel

二、漏洞分析

漏洞触发点在com.alibaba.csp.sentinel.dashboard.metric.MetricFetcher#fetchOnce方法中

第213行会执行httpGet请求,而其中的url参数会拼接获取的machineip和machineport。machineport的值为integer类型,无法进行利用。

而machineip的值类型为string,可以由用户控制输入从而产生ssrf漏洞

将输入的ip末尾添加一个#则httpGet请求就会忽略代码中设置的后缀参数,只访问用户提交的恶意ip。

例如传入的ip是?machineip=www.baidu.com%23

漏洞的触发点找到接下来就需要找参数的获取方式。该方法中machine的参数是通过appInfo.getMachines()方法获得

跟进

AppInfo类的machines值是ConcurrentHashMap.newKeySet()方法获得,在类中通过addMachine方法填充值

查找com.alibaba.csp.sentinel.dashboard.discovery.AppInfo#addMachine方法的用法

方法在com.alibaba.csp.sentinel.dashboard.discovery.SimpleMachineDiscovery类中进行了重写

查找com.alibaba.csp.sentinel.dashboard.discovery.SimpleMachineDiscovery#addMachine方法的引用

发现了controller层的调用,跟进

可以发现其实调用的是appManagement.addMachine方法,而该方法也是委托了SimpleMachineDiscovery.addMachine,所以本质上都一样,可以直接跟到controller中。

调用该方法的路由是/registry/machine,传入参数是appType,version,v,hostname,ip,port。

观察整个调用过程,其中只对app、ip、port、machines做了非空判断,所以只要保证这几个参数不为空即可

所以最后的payload如下:

http://localhost:9090/registry/machine?appType=0&version=1&v=1&hostname=1&ip=127.0.0.1:7777%23&port=7777

又因为该接口不需要auth登录

所以可以无需登录触发ssrf