转载

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

漏洞公告

https://pivotal.io/security/cve-2019-3799

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

漏洞复现

GET /foo/default/master/..%252F..%252F..%252F..%252Fetc%252fpasswd HTTP/1.1
Host: localhost:8888

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

漏洞分析

Spring Cloud Config是Spirng Cloud下用于分布式配置管理的组件,分为 Config-ServerConfig-Client 两个角色。 Config-Server 负责集中存储/管理配置文件, Config-Client 则可以从 Config-Server 提供的HTTP接口获取配置文件使用。2019年4月16日,Pivotal官方发布安全通告,Spring Cloud Config Server 部分版本存在目录遍历漏洞,据此可以获取Server端服务器文件。

根据 官方文档 ,可以通过如下请求 GET /{name}/{profile}/{label}/{path} 来获取配置文件, nameprofilelabel 的含义与常规环境下的endpoint相同,而 path 是指文件名。以官方示例为环境,我们请求 https://github.com/spring-cloud-samples/config-repo/blob/master/test.json 这个文件并以文本形式返回 ,则我们需要向 Spring Cloud Config Server 发出如下请求:

GET http://127.0.0.1:8888/foo/label/master/test.json

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

根据请求格式可以在 org/springframework/cloud/config/server/resource/ResourceController.java:54 中找到对应的处理 @RequestMapping("/{name}/{profile}/{label}/**")

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

其中 path 值即为payload: ..%2F..%2F..%2F..%2Fetc%2fpasswd

跟入 retrieveorg/springframework/cloud/config/server/resource/ResourceController.java:104

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);
        ...
    }

这里会根据前面所传条件获取到resource。文档中提到 only the first one to match is returned ,所以继续跟入 findOne :

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

可以看到这里 locations 的值为 file:/tmp/config-repo-7168113927339570935/ ,这是 Config-Server 从后端拉取到配置文件时临时存放,正常情况下将会在该文件夹下进行文件的查找,比如 test.json

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

不过我们传入的却是 ..%2F..%2F..%2F..%2Fetc%2fpasswd ,最终拼接出来的文件url即为:

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

返回后获取到的 resource 即为 /etc/passwd ,调用 StreamUtils.copyToString(is, Charset.forName("UTF-8") 读取到文件内容:

Spring Cloud Config Server 路径穿越与任意文件读取漏洞分析 - 【CVE-2019-3799】

漏洞补丁

https://github.com/spring-cloud/spring-cloud-config/commit/3632fc6f64e567286c42c5a2f1b8142bfde505c2

主要在获取到local后进行了判断:

if (!isInvalidPath(local) && !isInvalidEncodedPath(local)) {
    Resource file = this.resourceLoader.getResource(location)
            .createRelative(local);
    if (file.exists() && file.isReadable()) {
        return file;
    }
}

isInvalidPath 用于检测其中是否含有 :/..WEB-INF 等关键字样, isInvalidEncodedPath 中在进行编解码后仍是调用 isInvalidPath 进行检测。

原文  https://xz.aliyun.com/t/4844
正文到此结束
Loading...