Offengelegter Docker-Daemon
A Docker daemon answering on the network without TLS is remote root on the host. Take a machine through the exposed API, then lock it down with TLS, client certificates, and a scoped socket proxy.
Was ist Offengelegter Docker-Daemon?
Die Docker-API ist root-äquivalent und wird ohne Authentifizierung ausgeliefert. Ein Daemon, der ohne TLS an einen Netzwerk-Port gebunden ist, erlaubt jedem, der ihn erreichen kann, Container zu starten, den Host einzubinden und alles auf der Maschine zu lesen. Das Einbinden des Daemon-Sockets in einen Container verschafft diesem Container dieselbe Macht. Diese Übung deckt beides ab: Beobachte, wie ein Angreifer über einen offengelegten Daemon einen Host übernimmt, und sichere ihn anschließend mit TLS, Client-Zertifikaten und einem eingeschränkten Socket-Proxy ab.
Was Sie lernen in Offengelegter Docker-Daemon
- Jeder, der die API erreichen kann, kann einen Container starten, der das Host-Dateisystem einbindet, was vollen Lese- und Schreibzugriff auf die Maschine gewährt.
- Nein. Der Socket ist dieselbe root-äquivalente API, sodass jede Kompromittierung dieses Containers zur Kompromittierung des Hosts wird.
- TLS mit gegenseitiger Client-Zertifikat-Authentifizierung, oder ein eingeschränkter Proxy, der nur die spezifischen API-Aufrufe zulässt, die der Aufrufer benötigt.
- Dieser Angriff benötigt zuerst Codeausführung innerhalb eines Containers. Dieser hier ist remote und unauthentifiziert, sodass der Angreifer überhaupt keinen Einstiegspunkt benötigt.
Offengelegter Docker-Daemon — Trainingsschritte
-
Die öffentliche Statusseite lesen
Bob ist in nichts eingedrungen. Er sitzt an seinem eigenen Laptop und liest Pallistons öffentliche Betriebsseite. Sie soll Kunden versichern, dass die Plattform funktionsfähig ist, und nennt dabei die Produktions-Knoten, deren öffentliche IPs und die Docker-Engine, die jeder von ihnen ausführt. Sieh dir an, was sie preisgibt, bevor Bob es sich zunutze macht.
-
Die Zeile, die zu viel verrät
Es braucht nur eine Zeile. Die öffentliche IP eines Produktions-Knotens und die Tatsache, dass er Docker ausführt, sind alles, was Bob für den billigsten Angriff überhaupt braucht.
-
Beim Daemon anklopfen
Der Docker-Daemon kann so konfiguriert werden, dass er an einem Netzwerk-Port lauscht statt nur am lokalen Socket. Ist das der Fall und TLS ist deaktiviert, antwortet er jedem. Bob richtet seine eigene Docker-CLI auf Port 2375 dieses Knotens und stellt ihm die harmloseste Frage überhaupt: welche Version bist du. Wenn er antwortet, ist das Spiel bereits vorbei.
-
Die Produktionsflotte auslesen
Die Docker-API ist keine schmale Sache. Sie listet, startet, stoppt und baut Container, und all das als root. Bobs erster Zug damit ist einfach hinzusehen: Was läuft auf diesem Host eigentlich.
-
Den Host einbinden, die Secrets stehlen
Bob muss nicht in die laufenden Container einbrechen. Der Daemon startet ihm einen brandneuen, und der bindet ein, was auch immer Bob verlangt. Er fordert das gesamte Root-Dateisystem des Hosts unter /host an und liest dann die Produktions-Umgebungsdatei direkt durch den Mount. Der Container gehört ihm. Der Host liegt darunter. Es gab nie eine Wand zwischen den beiden.
-
Was das möglich gemacht hat
Ein kurzer Moment beim Mechanismus, bevor die Reaktion beginnt.
-
Der Daemon protokolliert einen Fremden
Palliston versendet seine Docker-Daemon-Logs an einen zentralen Collector. Es braucht kein Intrusion-Detection-Produkt, um zu bemerken, was da auftauchte: API-Aufrufe an den Daemon auf ops-node-01, von einer IP, die niemandem bei Palliston gehört.
-
Bestätigen, dass die Tür offen ist
Bevor sie etwas ändert, reproduziert Alice, was die Logs beschreiben. Wenn eine nicht authentifizierte Versionsabfrage von ihrer eigenen Maschine aus beantwortet wird, ist der Daemon genau so offengelegt, wie Priya befürchtet hat.
-
Die Daemon-Konfiguration öffnen
Das Verhalten des Daemons wird in einer einzigen Datei festgelegt, /etc/docker/daemon.json. Was auch immer ihn angewiesen hat, ohne TLS am Netzwerk zu lauschen, ist eine Zeile hier drin.
-
Finde heraus, was den Port geöffnet hat
Zwei Einstellungen, direkt nebeneinander, sind die gesamte Offenlegung. Die eine bringt die API ans Netzwerk; die andere weist sie an, nicht zu prüfen, wer anruft.