Spring Cloud Config目录穿越漏洞(CVE-2020-5045)代码审计
漏洞简介
Spring Cloud Config为分布式系统的外部配置提供客户端的服务端的支持。使用它,开发人员就可以在一个中心仓库管理应用程序在所有环境中的外部配置。
Spring Cloud Config,2.2.3之前的2.2.x版本,2.1.9之前的2.1.x版本以及较旧的不受支持的版本允许应用程序通过spring-cloud-config-server模块提供任意配置文件。恶意用户或攻击者可以使用特制URL发送请求,这可能导致目录遍历攻击(在配置仓库为本地native的情况下,攻击者可以获取config-server服务器上的任意带后缀文件。)
Spring cloud Config有三次目录穿越漏洞,分别是CVE-2019-3799,CVE-2020-5405和CVE-2020-5410,可参考文章:https://xz.aliyun.com/t/7558
和https://xz.aliyun.com/t/7877
利用条件:
- 修改配置文件src/main/resources/configserver.yml
- 主要是设置profiles.active为native,设置search-locations为任意文件夹
影响版本:
- 2.2.x prior to 2.2.2
- 2.1.x prior to 2.1.7
漏洞复现
环境搭建:
1.从github下载spring-cloud-config模块:https://github.com/spring-cloud/spring-cloud-config/archive/v2.1.5.RELEASE.zip
2.将文件夹中的spring-cloud-config-server模块导入IDEA中(这是一个Maven+SpringBoot项目)
3.修改配置文件src/main/resources/configserver.yml
设置profiles.active为native,并设置search-locations为任意文件夹
|
|
4.启动项目:启动ConfigServerApplication
类,然后访问127.0.0.1:8888
5.测试payload:
|
|
成功跨越目录读取文件
漏洞分析:
Config Server通过路径/{name}/{profile}/{label}/{path}
对外提供配置文件,POC会通过路由到这个接口
所以我们先看下org\springframework\cloud\config\server\resource\ResourceController.java
并打上断点
|
|
可以看到name、profile、label的值:
path
通过getFilePath
获取,跟进:
可以看到getFilePath方法中将解析我们传入的文件名给path
,然后返回
返回到原来断点位置,可以看到getFilePath方法返回的path值会传入retrieve方法,跟进retrieve
方法:
可以看到,分别将name和label传入了resolveName
和resolveLabel
跟进resolveName
:
作用是将(_)
替换成/
,但是我们name是不含这个的,不满足,直接返回
跟进resolveLabel
:
作用跟resolveName是同样的,不过这里label中包含(_)
,所以满足,进行替换
所以我们的数据被替换成了 ../../../../../../../../../
继续回到retrieve
往下跟,程序执行到findOne
方法,跟进:
可以看到这个方法中this.service.getLocations
是调用配置文件(也就是我们之前配置文件中配置的search-locations
):
然后跟我们传入的参数重新拼接,得到两个路径:
getProfilePaths
方法是根据profile构造文件路径:
然后在下边使用isInvalidPath
进行非法路径的判断,但是这个判断是针对path
的,而我们的payload是在label
中,所以可以绕过: