
Linux-Privilege-Escalation-Exploit über snapd (CVE-2019-7304)
Im Januar 2019 wurde festgestellt, dass aktuelle Versionen von Ubuntu Linux anfällig für lokale Rechteausweitung sind, verursacht durch einen Bug in der snapd-API. Dieses Repository enthält den ursprünglichen Exploit-POC, der zu Forschungs- und Bildungszwecken bereitgestellt wird. Eine detaillierte Erläuterung der Schwachstelle und des Exploits findest du im Blogbeitrag hier.
Ubuntu wird standardmäßig mit snapd ausgeliefert, aber jede Distribution sollte angreifbar sein, wenn dieses Paket installiert ist. Du kannst leicht überprüfen, ob dein System verwundbar ist. Führe den folgenden Befehl aus. Wenn dein snapd die Version 2.37.1 oder neuer hat, bist du sicher.
$ snap version
...
snapd 2.37.1
...
Beachte, dass einige Systeme beim Ausführen dieses Befehls die von der Distribution bereitgestellte Paketversion von snapd zurückgeben, im Gegensatz zur Upstream-Version im obigen Beispiel. Wenn an deine snapd-Version so etwas wie eine Ubuntu-Versionsnummer angehängt ist (Beispiel: 2.34.2ubuntu0.1 oder 2.35.5+18.10.1 dann konsultiere bitte diesen Link, um festzustellen, ob du eine gepatchte Version ausführst.
Dieser Exploit umgeht Zugriffskontrollprüfungen, um eine eingeschränkte API-Funktion (POST /v2/create-user) des lokalen snapd-Dienstes zu nutzen. Diese fragt die Ubuntu SSO nach einem Benutzernamen und dem öffentlichen SSH-Schlüssel einer angegebenen E-Mail-Adresse ab und erstellt dann einen lokalen Benutzer auf Grundlage dieser Werte.
Für eine erfolgreiche Ausnutzung dieser Version sind eine ausgehende Internetverbindung und ein über localhost erreichbarer SSH-Dienst erforderlich.
Um den Exploit auszuführen, erstelle zunächst ein Konto bei der Ubuntu SSO. Nach der Bestätigung bearbeite dein Profil und lade einen öffentlichen SSH-Schlüssel hoch. Führe den Exploit dann wie folgt aus (mit dem SSH-Privatschlüssel, der zu dem von dir hochgeladenen öffentlichen Schlüssel gehört):
python3 ./dirty_sockv1.py -u "[email protected]" -k "id_rsa"
[+] Slipped dirty sock on random socket file: /tmp/ktgolhtvdk;uid=0;
[+] Binding to socket file...
[+] Connecting to snapd API...
[+] Sending payload...
[+] Success! Enjoy your new account with sudo rights!
[Script will automatically ssh to localhost with the SSH key here]
Dieser Exploit umgeht Zugriffskontrollprüfungen, um eine eingeschränkte API-Funktion (POST /v2/snaps) des lokalen snapd-Dienstes zu nutzen. Dies ermöglicht die Installation beliebiger Snaps. Snaps im „devmode“ umgehen die Sandbox und können einen „Installations-Hook“ enthalten, der bei der Installation im Kontext von root ausgeführt wird.
dirty_sockv2 nutzt die Schwachstelle aus, um einen leeren „devmode“-Snap zu installieren, der einen Hook enthält, der dem lokalen System einen neuen Benutzer hinzufügt. Dieser Benutzer hat die Berechtigung, sudo-Befehle auszuführen.
Im Gegensatz zu Version Eins erfordert dies keinen laufenden SSH-Dienst. Es funktioniert auch auf neueren Ubuntu-Versionen ganz ohne Internetverbindung, was es widerstandsfähig gegenüber Änderungen und effektiv in eingeschränkten Umgebungen macht.
Zur Klarstellung: Diese Version des Exploits versteckt sich nicht in einem bösartigen Snap. Stattdessen nutzt sie einen bösartigen Snap als Übermittlungsmechanismus für die Nutzlast zur Benutzererstellung. Dies ist dank desselben uid=0-Bugs wie in Version 1 möglich
Dieser Exploit sollte auch auf Nicht-Ubuntu-Systemen wirksam sein, die snapd installiert haben, die „create-user“-API aufgrund inkompatibler Linux-Shell-Syntax jedoch nicht unterstützen.
Einige ältere Ubuntu-Systeme (wie 16.04) verfügen möglicherweise nicht über die für das Sideloading erforderlichen snapd-Komponenten. In diesem Fall kann diese Version des Exploits deren Installation auslösen. Während dieser Installation kann sich snapd selbst auf eine nicht verwundbare Version aktualisieren. Tests zeigen, dass der Exploit in diesem Szenario trotzdem erfolgreich ist. Weitere Details findest du im Abschnitt zur Fehlerbehebung.
Um den Exploit auszuführen, genügt es, das Skript ohne Argumente auf einem verwundbaren System zu starten.
python3 ./dirty_sockv2.py
[+] Slipped dirty sock on random socket file: /tmp/gytwczalgx;uid=0;
[+] Binding to socket file...
[+] Connecting to snapd API...
[+] Deleting trojan snap (and sleeping 5 seconds)...
[+] Installing the trojan snap (and sleeping 8 seconds)...
[+] Deleting trojan snap (and sleeping 5 seconds)...
********************
Success! You can now `su` to the following account and use sudo:
username: dirty_sock
password: dirty_sock
********************
Wenn du Version Zwei verwendest und der Exploit abgeschlossen ist, aber dein neues Konto nicht angezeigt wird, kann dies an einigen Snap-Updates im Hintergrund liegen. Du kannst diese anzeigen, indem du snap changes und dann snap change # ausführst, wobei du die Zeile referenzierst, die die Installation des dirty_sock-Snaps anzeigt. Irgendwann sollten diese abgeschlossen sein und dein Konto nutzbar sein.
Version 1 scheint die einfachste und schnellste zu sein, wenn deine Umgebung sie unterstützt (SSH-Dienst läuft und ist über localhost erreichbar).
Nicht verwundbare Systeme geben etwa Folgendes aus:
[!] System may not be vulnerable, here is the API reply:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
Date: Mon, 18 Feb 2019 07:07:12 GMT
Content-Length: 119
{"type":"error","status-code":401,"status":"Unauthorized",
"result":{"message":"access denied","kind":"login-required"}}
Bitte eröffne bei allem Ungewöhnlichen ein Issue.
Das Problem wurde dem snapd-Team direkt über Ubuntus Bug-Tracker gemeldet. Den vollständigen Thread kannst du hier lesen.
Ich war sehr beeindruckt von Canonicals Reaktion auf dieses Problem. Das Team war großartig in der Zusammenarbeit, und insgesamt gibt mir die Erfahrung ein sehr gutes Gefühl, selbst Ubuntu-Nutzer zu sein.
Öffentliche Sicherheitshinweise:
Hinweis: Ich veröffentliche Informationen nur in diesem GitHub-Repo, auf meinem Blog unter initblog.com und im Blog meines Teams unter shenaniganslabs.io. Jede Website, die sich als offizielle Quelle ausgibt, liegt leider außerhalb meiner Kontrolle.