Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性
Report a Sentinel Security Vulnerability about SSRF · Issue #2451 · alibaba/Sentinel (github.com)
由于该开源项目的sentinel-dashboard module中存在着接口/registry/machine无需授权即可访问,并且客户端接入时提交的注册数据无任何权限校验就存储在内存中,恶意用户无需认证登陆,即可发送恶意的应用注册数据,让sentinel-dashboard定时任务对其数据中ip指定的主机发起GET请求,进行SSRF攻击。
漏洞点在com.alibaba.csp.sentinel.dashboard.metric.MetricFetcher#fetchOnce
通过查看代码可以发现,该方法中会遍历注册AppInfo中每台机器MachineInfo的注册信息,构造对应的URL进行采集客户端限流熔断等数据,但其ip字段无任何校验,通过井号'#'等字符就可以截断后续的URL内容(RFC),进而控制管控平台sentinel-dashboard发起任意GET请求。
分析源码
触发点
这里是漏洞触发点
查看它拼接的参数 ip、port、startTime和endTime,startTime和endTime 都是 long,不存在漏洞点。
重点关注 ip、port。从machine得到的ip和port
machine是遍历machines得到的、machines是 appinfo.getMachines() 获得的
跟进去看看appinfo.getMachines() 是怎么样的,这里是返回了一个HashSet集合
src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfo.java
下面有addMachine,跟进去machineinfo 看看里面有什么数据
基本上这三个
如果我们想要触发的话,就得找哪里调用了addMachine
其中有就几个都是写好的127.0.0.1或者固定的。进入到com/alibaba/csp/sentinel/dashboard/discovery/SimpleMachineDiscovery.java
再往上找调用链
这里第一个MachineRegistryController.java 未对对ip和port进行了验证和过滤,只是对是否为空进行了判断
记住这里的路由时 /registry/machine
第二个 AppManagement.java 哦哦发现这里是 AppManagement.java中调用了 appManagement.addMachine
才有了也就是第一个
1.83已经修复版本,但是只是对ip进行了验证和过滤,未授权还是存在的
调用链
回到漏洞点fetchOnce,查找调用的地方
com/alibaba/csp/sentinel/dashboard/metric/MetricFetcher.java
doFetchAppMetric调用了fetchOnce
fetchAllApp调用了doFetchApp
start调用了fetchAllApp,通过fetchScheduleService可以看到它是一个定时任务,每10s执行一次
再去找找哪里调用了start --MetricFetcher()
第一时间没看出什么特别的,然后发现这是个构造函数
这个类的注解是 @Component 会在项目启动时自动注册为bean,调用它的构造函数,也就调用了链子 start()
未授权
这个可以从配置文件中发现
黑盒测试
运行Sentinel/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/DashboardApplication.java即可启动sentinel-dashboard后台
http://localhost:8080/#/login
默认用户名和密码都是 sentinel(不需要登录)
本地监听12345端口,nc -lvvp 12345
发起对本地localhost端口为12345的SSRF GET攻击,
curl -XGET 'http://127.0.0.1:8080/registry/machine?app=SSRF-TEST&appType=0&version=0&hostname=TEST&ip=localhost:12345%23&port=0
1.8.3已经不行了
但是未授权还是没改的