„Dirty Pipe“-Linux-Schwachstelle und Ihre containerisierten Anwendungen (CVE-2022-0847)
9. März 2022
0 Min. LesezeitWas ist die „Dirty Pipe“-Schwachstelle? (CVE-2022-0847)
Kürzlich wurde CVE-2022-0847 veröffentlicht. Der Eintrag beschreibt eine Schwachstelle im Linux-Kernel, durch die jeder Prozess Dateien unabhängig von Berechtigungen oder Eigentumsverhältnissen ändern kann. Die Sicherheits-Community hat die Schwachstelle aufgrund ihrer Ähnlichkeit mit „Dirty COW“, einer in CVE-2016-5195 gemeldeten Rechteausweitungs-Schwachstelle, und wegen ihres Auftretens in der Kernel-Pipeline-Implementierung „Dirty Pipe“ genannt. In der Snyk Intel Vulnerability Database sind mehrere Referenzen zu dieser Schwachstelle dokumentiert, falls Sie tiefer in das Thema einsteigen möchten.
In diesem Artikel besprechen wir die Risiken für Ihre containerisierten Workloads und sehen uns genauer an, wie Inhalte von Container-Images und anderen Dateien, die normalerweise schreibgeschützt sind, von Angreifern unabhängig von UID und Dateisystemberechtigungen geändert werden können.
Sehen wir uns zunächst an, was Sie jetzt tun können, um Ihre Systeme vor Dirty Pipe zu schützen.
Kurz gesagt: Aktualisieren Sie Ihre Linux-Hosts
Die einzige bekannte Lösung für diese Schwachstelle besteht darin, Ihre Linux-Hosts auf eine der folgenden Kernel-Versionen zu aktualisieren:
5.16.11
5.15.25
5.10.102
Es gibt keine weiteren Maßnahmen, die Ihre Systeme schützen können, falls ein Angreifer Zugriff auf Ihre Umgebung erhält.
Wie Dirty Pipe Ihre Container-Images beeinträchtigt
Container-Images – die Grundlagen

Ein Container-Image besteht im Wesentlichen aus mehreren übereinanderliegenden Ebenen. Beim Starten eines Containers führt die Runtime-Engine (Docker, containerD, cri-O usw.) diese Ebenen zusammen und stellt das resultierende Gesamtbild dem Prozess als Dateisystem bereit. Diese Ebenen sind immer schreibgeschützt. Änderungen werden in einer Lese-/Schreibebene vorgenommen, die für jede Containerinstanz nach dem Copy-on-Write-Prinzip (COW) erstellt wird. Diese Lese-/Schreibebene ist temporär und wird gelöscht, wenn der Container aus dem System entfernt wird. Sie können sie auch weglassen, indem Sie den Container im schreibgeschützten Modus starten. Dadurch wird der Container unveränderlich.
Es empfiehlt sich, Container-Prozesse als nicht privilegierte Benutzer auszuführen und ihre Root-Dateisysteme schreibgeschützt zu machen. Dadurch wird es für Angreifer deutlich schwieriger, Anwendungsschwachstellen auszunutzen und ihre Angriffe auszuweiten, da sie dann nicht ohne Weiteres eigenen Code oder Skripte in das Container-Dateisystem einbringen können. Weitere Best Practices finden Sie in unserem Leitfaden zur Container-Sicherheit.
Dirty Pipe in einem Container ausgenutzt
Die Details zur Funktionsweise der Dirty-Pipe-Schwachstelle würden den Rahmen dieses Artikels sprengen – alle Einzelheiten finden Sie im Blogbeitrag zur ursprünglichen Entdeckung. Auf hoher Ebene lässt sich jedoch mit einer relativ einfachen Abfolge von Schritten der Inhalt fast jeder Datei ändern, selbst wenn Berechtigungen und/oder Eigentumsverhältnisse dies verhindern sollen. Wir erstellen beispielsweise mit dem Proof-of-Concept-Code write_anything aus dem oben verlinkten Artikel ein Image mit diesem Dockerfile:

Anschließend führen wir es im schreibgeschützten Modus aus und verwenden die ausführbare Datei write_anything, um /etc/passwd zu ändern.

Das hätte nicht möglich sein dürfen, da die Datei schreibgeschützt ist, Root gehört und sich auf einem schreibgeschützten Root-Dateisystem befindet.
Als Nächstes beenden und entfernen wir diesen Container, starten einen neuen und sehen uns dann /etc/passwd im neuen Container an.

Die Änderung blieb bestehen, weil der vorherige Container-Prozess den tatsächlichen Inhalt der Image-Ebene geändert hatte, obwohl diese auf dem Host-System schreibgeschützt ist. Die Änderung bleibt auf diesem Host bestehen, bis das Image entfernt und/oder ersetzt wird.
Image-Ebene auf niedriger Ebene vor dem Hack

Image-Ebene auf niedriger Ebene nach dem Hack

Wenn mehrere Container auf demselben Host laufen, kann eine solche Änderung sofort in jedem Container sichtbar sein, der diese Basis-Image-Ebene gemeinsam nutzt – außer in Containern, die dieselbe Datei bereits in ihrer eigenen Lese-/Schreibebene geändert haben.
Drei Container überwachen ihre /etc/passwd-Dateien mit watch, während ein vierter Container den write_anywhere-Hack ausführt.

Alle Ihre eingebundenen Host-Volumes sind Dirty Pipe schutzlos ausgeliefert

Wie Sie vielleicht gehört haben, ist es grundsätzlich keine gute Idee, Host-Volumes (auch Bind-Mounts genannt) in Ihre Container einzubinden. Unter normalen Umständen wird davon abgeraten, weil eine einfache Fehlkonfiguration dem Container unbeabsichtigten Zugriff zum Ändern von Dateien auf dem Host gewähren könnte. Dirty Pipe verschärft das Problem: Host-Volumes sind durch diesen Exploit gefährdet, selbst wenn sie mit dem Flag :ro eingebunden wurden.

Rechteausweitung über Dirty Pipe
Ein Beispiel für einen Proof-of-Concept-Exploit, der derzeit die Runde macht, nutzt diese Schwachstelle, um durch Änderung einer vorhandenen SUID-fähigen Binärdatei erhöhte Berechtigungen zu erlangen und die üblichen Schutzmaßnahmen zu umgehen. Das betrifft nicht nur Container, lässt sich aber auch in ihnen ausnutzen. Ein theoretisches Beispiel: Ein Angreifer nutzt eine Schwachstelle für Remote Code Execution (RCE) in einer Anwendung aus und schleust diesen PoC-Code ein, um Root-Rechte im Container zu erlangen. Dadurch werden Einstellungen in Containern und/oder Kubernetes, die ein solches Verhalten einschränken, effektiv umgangen.
Gibt es Maßnahmen zur Risikominderung?
Wie bereits erwähnt, ist die Aktualisierung Ihrer Host-Systeme die einzige bekannte Möglichkeit, Ihre Systeme vor dieser Schwachstelle zu schützen. Maßnahmen in Container-Engines und Kubernetes sind schlicht zu hoch angesiedelt, um umfassend vor einem Kernel-Exploit wie diesem zu schützen.
Können wir nicht einfach unsere Basis-Images aktualisieren?
Leider nein. Die Schwachstelle liegt nicht im Dateisystem der Basis-Images, sondern im Kernel der Host-Server, den sich alle laufenden Container teilen. Sie können das überprüfen, indem Sie uname -a in mehreren Containern mit unterschiedlichen Basis-Images ausführen: Alle geben die Kernel-Version des Hosts aus.

Wie sieht es mit dem Kubernetes SecurityContext aus?
Einstellungen im Kubernetes SecurityContext wie readonlyRootFilesystem:true, runAsNonRoot:true, runAsUser: und AllowPrivilegeEscalation:false sind wirkungslos, da jeder Benutzer diese Schwachstelle ausnutzen und die Einstellungen umgehen kann.
Das heißt nicht, dass Sie diese Einstellungen nicht verwenden sollten. Im Gegenteil: Sie sind hervorragende Beispiele für Defense-in-Depth und schützen Ihre Cluster vor vielen anderen Angriffsarten.
Unser Kubernetes-Sicherheits-Spickzettel erläutert die SecurityContext-Einstellungen und erklärt, warum Sie sie zur Absicherung Ihrer Kubernetes-Anwendungsbereitstellungen verwenden sollten. Mit den kostenlosen IaC-Scanning-Tools von Snyk können Sie außerdem Ihre Kubernetes-Manifeste scannen und Fehlkonfigurationen wie diese finden und beheben. Klicken Sie auf den folgenden Link, um noch heute loszulegen.
Fazit
Falls Sie es noch nicht getan haben, aktualisieren Sie Ihre Hosts umgehend. Wenn eines der oben genannten Themen Ihr Interesse geweckt hat, finden Sie unter den folgenden Links weitere Informationen.
CM4All-Blog: Artikel zur Entdeckung der Dirty-Pipe-Schwachstelle
Snyk-Blog: Einblicke in Image-Erstellung, Ebenen und das Scannen von Container-Schwachstellen
Snyk-Spickzettel: 10 Kubernetes-Security-Context-Einstellungen, die Sie kennen sollten
Ars Technica: Linux ist von seiner schwerwiegendsten Schwachstelle seit Jahren betroffen
Sichern Sie Ihre Infrastruktur an der Quelle
Snyk automatisiert die IaC-Sicherheit und Compliance in Workflows und erkennt abweichende sowie fehlende Ressourcen.
