转载

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

补丁 主要针对 location 位置增加了一个检查。

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

这个洞和之前的 CVE-2019-3799 路由一样,这里不多赘述,选择其中一种路由方式, @RequestMapping("/{name}/{profile}/{label}/**") 来往下走。

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

跟进这个 retrieve 方法,关注这几个方法 resolveNameresolveLabelfindOne

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

先看看 resolveNameresolveLabel ,简单理解这两个方法的作用就是我们假设传入 ..(_)..(_) 经过这部分函数的处理,会变成 ../../ ,所以自然不言而喻这部分函数的作用了吧。

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

跟进 findone 之后,我们之前漏洞点是在 path 这个位置,这次我们再细看一下,1是通过 applicationprofilelabel 获取 locations 数组,而我们都知道这些参数实际上我们都是可控的,2部分通过循环遍历从 locations 数组中取出 location ,最后读取文件时候与这个有关系。

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

0x03 漏洞复现

配置环境配置。

server.port=8122
spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo.git

按照上面的分析尝试使用poc直接进行攻击,发现了500报错,查看异常信息。

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

实际上在这步的时候,如果配置的是远程git形式,会调用内置 git client 进行远程的 git 拉取,由于我们修改的是 label 位置,所以这里在 checkout 的时候抛出了 Branch name xxx is not allowed

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

回头细看一下 commit ,发现自带的Test在 setSearchLocations 是调用 file 协议读取本地相对文件。

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

所以这时候就需要修改 application.properties 中的 spring.profiles.active 的值为本地文件系统 native ,并且通过 file:// 进行文件加载。

server.port=8122
#spring.cloud.config.server.git.uri=https://github.com/spring-cloud-samples/config-repo.git
spring.cloud.config.server.native.search-locations=file:///Users/l1nk3r/Desktop/l1nk3r/src/test/resources/test/local/
spring.profiles.active=native

确实可以。

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

但是读取 /etc/passwd 不行,原因在于 /etc/passwd 不带后缀名,在这步获取 getFilenameExtension 的时候会抛出异常,导致500报错退出。

spring-cloud-config-server 路径穿越漏洞分析【CVE-2020-5405】

0x04 漏洞修复

新增 isInvalidEncodedLocation 方法检查 Location

private boolean isInvalidEncodedLocation(String location) {
	if (location.contains("%")) {
		try {
			// Use URLDecoder (vs UriUtils) to preserve potentially decoded UTF-8
			// chars
			String decodedPath = URLDecoder.decode(location, "UTF-8");
			if (isInvalidLocation(decodedPath)) {
				return true;
			}
			decodedPath = processPath(decodedPath);
			if (isInvalidLocation(decodedPath)) {
				return true;
			}
		}
		catch (IllegalArgumentException | UnsupportedEncodingException ex) {
			// Should never happen...
		}
	}
	return isInvalidLocation(location);
}

private boolean isInvalidLocation(String location) {
	boolean isInvalid = location.contains("..");

	if (isInvalid && logger.isWarnEnabled()) {
		logger.warn("Location contains /"../"");
	}
	return isInvalid;
}

漏洞修复的话建议升级至下列版本。

  • 2.2.2
  • 2.1.7
原文  http://www.lmxspace.com/2020/03/09/spring-cloud-config-server-路径穿越漏洞分析【CVE-2020-5405】/
正文到此结束
Loading...