[CVE-2020-5405]spring-cloud-config路径穿越导致的信息泄露

环境:
https://github.com/shadowsock5/spring-cloud-config-starter
详细分析参考:
https://blog.riskivy.com/cve-2020-5405-spring-cloud-config-server-%e7%9b%ae%e5%bd%95%e7%a9%bf%e8%b6%8a/
启动完成:
在这里插入图片描述

curl -u root:root http://192.168.170.139:8888/cqq-config/test

在这里插入图片描述

修复的commit是这个:
https://github.com/spring-cloud/spring-cloud-config/commit/651f458919c40ef9a5e93e7d76bf98575910fad0

根据log里的报错,在org/springframework/cloud/config/server/resource/ResourceController#retrieve下断点:
在这里插入图片描述
结合源码调试:
https://github.com/spring-cloud/spring-cloud-config

总结

1、/etc/hosts无法读取;/etc/hosts.allow可以读取;/etc/ca-certificates.conf还可通过拼接读取。
2、路径穿越可以被利用的条件是:
在配置文件application.properties/application.yml中配置spring.profiles.active的值为本地文件系统native(默认是git的url?);
3、没有后缀的文件(比如/etc/passwd)无法读取,因为有一个获取文件后缀名的逻辑,即便已经读到了文件内容但是由于没有后缀名出现异常然后响应500。
在这里插入图片描述

调试

在org/springframework/cloud/config/server/resource/ResourceController#retrieve
下断点就行了。
在这里插入图片描述
贴一下代码:

	synchronized String retrieve(ServletWebRequest request, String name, String profile,
			String label, String path, boolean resolvePlaceholders) throws IOException {
		name = resolveName(name);
		label = resolveLabel(label);
		Resource resource = this.resourceRepository.findOne(name, profile, label, path);
		if (checkNotModified(request, resource)) {
			// Content was not modified. Just return.
			return null;
		}
		// ensure InputStream will be closed to prevent file locks on Windows
		try (InputStream is = resource.getInputStream()) {
			String text = StreamUtils.copyToString(is, Charset.forName("UTF-8"));
			String ext = StringUtils.getFilenameExtension(resource.getFilename())
					.toLowerCase();
			Environment environment = this.environmentRepository.findOne(name, profile,
					label, false);
			if (resolvePlaceholders) {
				text = resolvePlaceholders(prepareEnvironment(environment), text);
			}
			if (encryptEnabled && plainTextEncryptEnabled) {
				ResourceEncryptor re = this.resourceEncryptorMap.get(ext);
				if (re == null) {
					logger.warn("Cannot decrypt for extension " + ext);
				}
				else {
					text = re.decrypt(text, environment);
				}
			}
			return text;
		}
	}

在这里插入图片描述

org/springframework/cloud/config/server/resource/GenericResourceRepository#findOne
在这里插入图片描述

关键的判断文件后缀点逻辑:
在这里插入图片描述
(_)
->
/转换:
org/springframework/cloud/config/server/resource/ResourceController.java
转换前:
在这里插入图片描述
转换后:
在这里插入图片描述

Demo

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

参考:

发布了601 篇原创文章 · 获赞 101 · 访问量 100万+

猜你喜欢

转载自blog.csdn.net/caiqiiqi/article/details/104729207