Spring Cloud Config Serve目录遍历漏洞(CVE-2020-5405)分析

根据https://www.baeldung.com/spring-cloud-configuration 搭环境。其中pom.xml的依赖改为:

  <dependencies>
	    <dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-config-server</artifactId>
	    <version>2.2.0.RELEASE</version>
	</dependency>

	<dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-web</artifactId>
	    <version>2.2.1.RELEASE</version>
	</dependency>
  </dependencies>

启动项目。根据文章的介绍,查询语句的格式为:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

label是git分支

application 是应用名字

profile 是当前正在使用应用的profile
正常的请求,可以读取git仓库下的任何文件


而问题就出在{label}

先上POC:

GET /config-client/development/master(_)..(_)..(_)..(_)..(_)..(_)..(_)/etc/resolv.conf HTTP/1.1
Host: kali-xps:8888
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Cookie: hibext_instdsigdipv2=1
Upgrade-Insecure-Requests: 1

通过补丁https://github.com/spring-cloud/spring-cloud-config/commit/651f458919c40ef9a5e93e7d76bf98575910fad0 定位到需在

spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/resource/ResourceController.java

下断点

debug

发送payload:

可以看到以uri中的/为边界,分别获取到了 application profile 和 label。
resolveLabel()方法将 label中的(_)替换为了/

跟进 resolveLabel()方法:

仅仅是判断非空且包含(_)就替换为/

所以label部分跨目录时不能出现/ ,否则/右边的部分就视为git 仓库下的文件了。

label右边出现第一个 / 符号后的内容 全放在path里。
通过application 和 profile 获取到仓库地址后 ,简单的拼上经过转换过的label的地址,后面加个/
拼接后
之后会再尝试进行多次拼接,把所有可能的组合形式都尝试一遍。比如在文件后加-development.conf判断存不存在
不过已经无关紧要了 我们构造的poc的文件是存在的

文件存在,跳出循环。

resource变量中存的文件路径
先获取文件内容
但是下面判断了文件有没有后缀名,如果文件没有后缀名
即使读到文件,也会因为获取不到文件名中的 “.” 的位置而返回空

所以这个漏洞只能读取带文件后缀的文件。

补丁的话新增了一个isInvalidEncodedLocation()方法:

判断了路径中有没有”..”

Leave a Reply

Your email address will not be published. Required fields are marked *