Docker Breakout / Privilege Escalation
Last updated
Last updated
Lernen Sie und üben Sie AWS-Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lernen Sie und üben Sie GCP-Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Verwenden Sie Trickest, um einfach Workflows zu erstellen und zu automatisieren, die von den weltweit fortschrittlichsten Community-Tools unterstützt werden. Heute Zugriff erhalten:
linpeas: Es kann auch Container aufzählen
CDK: Dieses Tool ist ziemlich nützlich, um den Container zu aufzählen, in dem Sie sich befinden, und sogar automatisch zu versuchen zu entkommen
amicontained: Nützliches Tool, um die Berechtigungen des Containers zu erhalten, um Wege zu finden, um daraus zu entkommen
deepce: Tool zum Aufzählen und Entkommen aus Containern
grype: Erhalten Sie die CVEs, die in der installierten Software im Image enthalten sind
Wenn Sie irgendwie feststellen, dass der Docker-Socket im Docker-Container gemountet ist, können Sie daraus entkommen. Dies geschieht normalerweise in Docker-Containern, die aus irgendeinem Grund eine Verbindung zum Docker-Daemon herstellen müssen, um Aktionen auszuführen.
In diesem Fall können Sie reguläre Docker-Befehle verwenden, um mit dem Docker-Daemon zu kommunizieren:
Falls der Docker-Socket an einem unerwarteten Ort liegt, können Sie dennoch mit ihm kommunizieren, indem Sie das docker
-Befehl mit dem Parameter -H unix:///pfad/zum/docker.sock
verwenden.
Der Docker-Daemon könnte auch auf einem Port lauschen (standardmäßig 2375, 2376) oder auf Systemd-basierten Systemen kann die Kommunikation mit dem Docker-Daemon über den Systemd-Socket fd://
erfolgen.
Zusätzlich sollten Sie auf die Laufzeit-Sockets anderer High-Level-Laufzeiten achten:
dockershim: unix:///var/run/dockershim.sock
containerd: unix:///run/containerd/containerd.sock
cri-o: unix:///var/run/crio/crio.sock
frakti: unix:///var/run/frakti.sock
rktlet: unix:///var/run/rktlet.sock
...
Sie sollten die Berechtigungen des Containers überprüfen. Wenn er eine der folgenden hat, könnten Sie daraus entkommen: CAP_SYS_ADMIN
, CAP_SYS_PTRACE
, CAP_SYS_MODULE
, DAC_READ_SEARCH
, DAC_OVERRIDE, CAP_SYS_RAWIO
, CAP_SYSLOG
, CAP_NET_RAW
, CAP_NET_ADMIN
Sie können die aktuellen Container-Berechtigungen mit den zuvor genannten automatischen Tools oder überprüfen:
Ein privilegierter Container kann mit der Flagge --privileged
erstellt werden oder indem spezifische Abwehrmechanismen deaktiviert werden:
--cap-add=ALL
--security-opt apparmor=unconfined
--security-opt seccomp=unconfined
--security-opt label:disable
--pid=host
--userns=host
--uts=host
--cgroupns=host
/dev
einbinden
Die --privileged
-Flagge senkt die Sicherheit des Containers erheblich, bietet uneingeschränkten Gerätezugriff und umgeht mehrere Schutzmechanismen. Für eine detaillierte Aufschlüsselung siehe die Dokumentation zu den vollständigen Auswirkungen von --privileged
.
Mit diesen Berechtigungen können Sie einfach in den Namensraum eines als Root ausgeführten Prozesses im Host wechseln, wie z.B. init (pid:1), indem Sie einfach ausführen: nsenter --target 1 --mount --uts --ipc --net --pid -- bash
Testen Sie dies in einem Container durch Ausführen:
Nur mit der privilegierten Flagge können Sie versuchen, auf die Festplatte des Hosts zuzugreifen oder versuchen, den release_agent oder andere Escapes zu missbrauchen.
Testen Sie die folgenden Umgehungen in einem Container, der ausgeführt wird:
Gut konfigurierte Docker-Container werden den Befehl fdisk -l nicht zulassen. Auf einem falsch konfigurierten Docker-Befehl, bei dem die Option --privileged
oder --device=/dev/sda1
mit Caps angegeben ist, ist es jedoch möglich, die Berechtigungen zu erhalten, um das Host-Laufwerk zu sehen.
Um also die Kontrolle über die Host-Maschine zu übernehmen, ist es trivial:
Und voilà! Sie können jetzt auf das Dateisystem des Hosts zugreifen, da es im Ordner /mnt/hola
eingebunden ist.
Innerhalb des Containers kann ein Angreifer versuchen, über ein beschreibbares hostPath-Volume, das vom Cluster erstellt wurde, weiteren Zugriff auf das zugrunde liegende Host-Betriebssystem zu erlangen. Im Folgenden sind einige übliche Dinge aufgeführt, die Sie im Container überprüfen können, um zu sehen, ob Sie diesen Angriffsvektor nutzen können:
Finde eine Erklärung der Technik in:
Docker release_agent cgroups escapeIn den vorherigen Exploits wird der absolute Pfad des Containers im Dateisystem des Hosts offengelegt. Dies ist jedoch nicht immer der Fall. In Fällen, in denen Sie den absoluten Pfad des Containers im Host nicht kennen, können Sie diese Technik verwenden:
release_agent exploit - Relative Paths to PIDsDie Ausführung des PoC innerhalb eines privilegierten Containers sollte eine ähnliche Ausgabe wie folgt liefern:
Es gibt mehrere Dateien, die möglicherweise eingebunden sind und Informationen über den zugrunde liegenden Host preisgeben. Einige von ihnen können sogar etwas anzeigen, das vom Host ausgeführt werden soll, wenn etwas passiert (was einem Angreifer ermöglichen würde, aus dem Container auszubrechen). Der Missbrauch dieser Dateien kann dazu führen, dass:
release_agent (bereits zuvor behandelt)
Sie können jedoch andere sensible Dateien auf dieser Seite überprüfen:
Sensitive MountsIn mehreren Fällen werden Sie feststellen, dass der Container ein Volume vom Host eingebunden hat. Wenn dieses Volume nicht korrekt konfiguriert wurde, könnten Sie möglicherweise auf sensible Daten zugreifen/ sie ändern: Geheime Informationen lesen, ssh authorized_keys ändern...
Wenn Sie als root innerhalb eines Containers Zugriff haben, der einen Ordner vom Host gemountet hat, und Sie als nicht privilegierter Benutzer auf den Host entkommen sind und Lesezugriff auf den gemounteten Ordner haben. Sie können eine bash suid-Datei im gemounteten Ordner innerhalb des Containers erstellen und sie vom Host ausführen, um eine Privilege Escalation durchzuführen.
Wenn Sie als root innerhalb eines Containers Zugriff haben und als nicht privilegierter Benutzer auf den Host entkommen sind, können Sie beide Shells missbrauchen, um Privilegien auf dem Host zu eskalieren, wenn Sie die Fähigkeit MKNOD innerhalb des Containers haben (standardmäßig vorhanden), wie in diesem Beitrag erklärt. Mit dieser Fähigkeit darf der Root-Benutzer innerhalb des Containers Blockgerätedateien erstellen. Gerätedateien sind spezielle Dateien, die verwendet werden, um auf die zugrunde liegende Hardware und Kernelmodule zuzugreifen. Zum Beispiel ermöglicht die Blockgerätedatei /dev/sda den Zugriff, um die Rohdaten auf der Systemsfestplatte zu lesen.
Docker schützt vor dem Missbrauch von Blockgeräten in Containern, indem es eine cgroup-Richtlinie durchsetzt, die Blockgeräte-Lese-/Schreiboperationen blockiert. Wenn jedoch ein Blockgerät innerhalb des Containers erstellt wird, ist es über das Verzeichnis /proc/PID/root/ von außerhalb des Containers aus zugänglich. Dieser Zugriff erfordert, dass der Prozessbesitzer sowohl innerhalb als auch außerhalb des Containers gleich ist.
Exploitation Beispiel aus diesem Bericht:
Wenn Sie auf die Prozesse des Hosts zugreifen können, werden Sie in der Lage sein, auf viele sensible Informationen zuzugreifen, die in diesen Prozessen gespeichert sind. Führen Sie den Test-Labor durch:
Zum Beispiel können Sie die Prozesse auflisten, indem Sie etwas wie ps auxn
verwenden und nach sensiblen Details in den Befehlen suchen.
Dann können Sie, da Sie auf jeden Prozess des Hosts in /proc/ zugreifen können, einfach ihre Umgebungsgeheimnisse stehlen, indem Sie ausführen:
Du kannst auch auf die Dateideskriptoren anderer Prozesse zugreifen und deren geöffnete Dateien lesen:
Du kannst auch Prozesse beenden und einen DoS verursachen.
Wenn du irgendwie privilegierten Zugriff auf einen Prozess außerhalb des Containers hast, könntest du etwas wie nsenter --target <pid> --all
oder nsenter --target <pid> --mount --net --pid --cgroup
ausführen, um eine Shell mit denselben ns-Beschränkungen (hoffentlich keine) wie dieser Prozess zu starten.
Wenn ein Container mit dem Docker Host-Netzwerktreiber (--network=host
) konfiguriert wurde, ist der Netzwerkstack dieses Containers nicht vom Docker-Host isoliert (der Container teilt den Netzwerk-Namensraum des Hosts) und der Container erhält keine eigene IP-Adresse zugewiesen. Mit anderen Worten, der Container bindet alle Dienste direkt an die IP-Adresse des Hosts. Darüber hinaus kann der Container ALLE Netzwerkdatenverkehr abfangen, den der Host über das gemeinsame Interface sendet und empfängt tcpdump -i eth0
.
Beispielsweise können Sie dies verwenden, um den Datenverkehr zwischen Host und Metadateninstanz abzufangen und sogar zu fälschen.
Wie in den folgenden Beispielen:
Sie können auch auf Netzwerkdienste zugreifen, die an localhost gebunden sind innerhalb des Hosts oder sogar auf die Metadatenberechtigungen des Knotens zugreifen (die möglicherweise von denen abweichen, auf die ein Container zugreifen kann).
Mit hostIPC=true
erhalten Sie Zugriff auf die Inter-Process Communication (IPC)-Ressourcen des Hosts, wie z.B. Shared Memory in /dev/shm
. Dies ermöglicht das Lesen/Schreiben, wenn die gleichen IPC-Ressourcen von anderen Host- oder Pod-Prozessen verwendet werden. Verwenden Sie ipcs
, um diese IPC-Mechanismen genauer zu inspizieren.
Inspektion von /dev/shm - Suchen Sie nach Dateien an diesem Speicherort für Shared Memory: ls -la /dev/shm
Inspektion vorhandener IPC-Einrichtungen - Sie können überprüfen, ob IPC-Einrichtungen mit /usr/bin/ipcs
verwendet werden. Überprüfen Sie dies mit: ipcs -a
Wenn der Systemaufruf unshare
nicht verboten ist, können Sie alle Berechtigungen wiederherstellen, indem Sie ausführen:
Die zweite Technik, die im Beitrag https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/ erklärt wird, zeigt, wie Sie Bind-Mounts mit Benutzernamensräumen missbrauchen können, um Dateien innerhalb des Hosts zu beeinflussen (in diesem speziellen Fall Dateien zu löschen).
Verwenden Sie Trickest, um einfach Workflows zu erstellen und zu automatisieren, die von den weltweit fortschrittlichsten Community-Tools unterstützt werden. Erhalten Sie noch heute Zugriff:
Falls Sie docker exec
als Root ausführen können (wahrscheinlich mit sudo), können Sie versuchen, Privilegien zu eskalieren, indem Sie aus einem Container ausbrechen und CVE-2019-5736 missbrauchen (Exploit hier). Diese Technik wird im Wesentlichen die /bin/sh-Binärdatei des Hosts aus einem Container heraus überschreiben, sodass jeder, der docker exec
ausführt, das Payload auslösen kann.
Passen Sie das Payload entsprechend an und erstellen Sie das main.go mit go build main.go
. Die resultierende Binärdatei sollte im Docker-Container zur Ausführung platziert werden.
Bei der Ausführung, sobald [+] Overwritten /bin/sh successfully
angezeigt wird, müssen Sie Folgendes vom Host-Rechner ausführen:
docker exec -it <container-name> /bin/sh
Dies löst das Payload aus, das in der main.go-Datei vorhanden ist.
Für weitere Informationen: https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html
Es gibt auch andere CVEs, für die der Container anfällig sein kann. Eine Liste finden Sie unter https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list
Namensräume: Der Prozess sollte über Namensräume vollständig von anderen Prozessen getrennt sein, sodass wir nicht mit anderen Prozessen interagieren können, die aufgrund von Namensräumen (standardmäßig nicht über IPCs, Unix-Sockets, Netzwerkdienste, D-Bus, /proc
anderer Prozesse kommunizieren können).
Root-Benutzer: Standardmäßig ist der Benutzer, der den Prozess ausführt, der Root-Benutzer (jedoch sind seine Berechtigungen begrenzt).
Berechtigungen: Docker lässt die folgenden Berechtigungen: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep
Syscalls: Dies sind die Syscalls, die der Root-Benutzer nicht aufrufen kann (aufgrund fehlender Berechtigungen + Seccomp). Die anderen Syscalls könnten verwendet werden, um einen Ausbruch zu versuchen.
If you are in userspace (no kernel exploit involved) the way to find new escapes mainly involve the following actions (these templates usually require a container in privileged mode):
Find the path of the containers filesystem inside the host
You can do this via mount, or via brute-force PIDs as explained in the second release_agent exploit
Find some functionality where you can indicate the path of a script to be executed by a host process (helper) if something happens
You should be able to execute the trigger from inside the host
You need to know where the containers files are located inside the host to indicate a script you write inside the host
Have enough capabilities and disabled protections to be able to abuse that functionality
You might need to mount things o perform special privileged actions you cannot do in a default docker container
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools. Get Access Today:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)