Sicherheitsforscher von Qualys haben Details zu zwei Schwachstellen im Linux-Kernel und dem Systemmanager systemd veröffentlicht. Die Schwachstelle im Kernel (CVE-2021-33909) ermöglicht es einem lokalen Benutzer, durch Manipulationen an tiefen Verzeichnissen Code mit Root-Rechten auszuführen.
Die Gefahr der Schwachstelle wird dadurch verstärkt, dass es den Forschern gelungen ist, funktionierende Exploits für die Standardkonfiguration von Ubuntu 20.04/20.10/21.04, Debian 11 und Fedora 34 zu erstellen. Es wird darauf hingewiesen, dass andere Distributionen nicht überprüft wurden, theoretisch jedoch ebenfalls betroffen sein könnten und angegriffen werden können. Den vollständigen Code der Exploits wollen sie nach der umfassenden Behebung des Problems veröffentlichen; derzeit ist nur ein funktionslimitierter Prototyp verfügbar, der einen Systemabsturz verursacht. Das Problem besteht seit Juli 2014 und betrifft Kernel-Versionen ab 3.16. Die Behebung der Schwachstelle wurde mit der Community abgestimmt und am 19. Juli in den Kernel integriert. Die Hauptdistributionen haben bereits Paket-Updates für den Kernel erstellt (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).
Die Schwachstelle entsteht durch das Fehlen einer Überprüfung des Ergebnisses der Konvertierung von size_t in int, bevor im seq_file-Code Operationen ausgeführt werden, die Dateien aus einer Sequenz von Datensätzen erstellen. Das Fehlen dieser Überprüfung kann zu einem Schreibvorgang außerhalb der Puffergrenzen führen, wenn Verzeichnisse mit sehr hoher Verschachtelung (Pfadlänge von mehr als 1 GB) erstellt, gemountet oder entfernt werden. Infolgedessen kann ein Angreifer eine 10-Byte-Zeichenkette "\/\/deleted" mit einer Offset von "- 2 GB — 10 Byte" schreiben, die auf den Bereich verweist, der unmittelbar vor dem zugewiesenen Puffer liegt.
Der vorbereitete Exploit benötigt 5 GB RAM und 1 Million freie Inodes, um zu funktionieren. Der Ablauf des Exploits besteht darin, eine Hierarchie aus etwa einer Million verschachtelter Verzeichnisse durch den Aufruf mkdir() zu schaffen, um eine Dateipfadgröße von über 1 GB zu erreichen. Dieses Verzeichnis wird über einen Bind-Mount in einem separaten Benutzer-Namensraum montiert, und anschließend wird die Funktion rmdir() zum Löschen des Verzeichnisses aufgerufen. Parallel dazu wird ein Thread erstellt, der ein kleines eBPF-Programm lädt und an dem Punkt blockiert, an dem der Pseudocode eBPF überprüft wird, jedoch bevor die JIT-Kompilierung erfolgt.
Im nicht privilegierten Benutzer-Namensraum wird die Datei /proc/self/mountinfo geöffnet und der lange Pfad des mit Bind-Mount montierten Verzeichnisses wird gelesen, was dazu führt, dass die Zeile "//deleted" in den Bereich vor dem Anfang des Puffers geschrieben wird. Die Position, an der die Zeile geschrieben wird, ist so gewählt, dass sie eine Anweisung in einem bereits überprüften, aber noch nicht kompilierten eBPF-Programm überschreibt.
Auf der Ebene des eBPF-Programms wird ein unkontrollierter Buffer-Overflow in eine verwaltbare Lese- und Schreibmöglichkeit für andere Kernel-Strukturen umgewandelt, indem mit den btf- und map_push_elem-Strukturen gearbeitet wird. Infolgedessen bestimmt der Exploit den Standort des Buffers modprobe_path[] im Kernel-Speicher und überschreibt diesen mit dem Pfad „/sbin/modprobe“. Dies ermöglicht es, jede ausführbare Datei mit Root-Rechten zu starten, wenn der Aufruf request_module() erfolgt, der beispielsweise beim Erstellen eines netlink-Sockets ausgeführt wird.
Die Forscher geben mehrere Umgehungsmethoden zum Schutz an, die nur für spezifische Exploits wirksam sind, aber das zugrunde liegende Problem nicht lösen. Es wird empfohlen, den Parameter „/proc/sys/kernel/unprivileged_userns_clone“ auf 0 zu setzen, um die Montage von Verzeichnissen in einem separaten Namensraum für Benutzer-IDs zu verhindern, und „/proc/sys/kernel/unprivileged_bpf_disabled“ auf 1 zu setzen, um das Laden von eBPF-Programmen in den Kernel zu unterbinden.
Bemerkenswert ist, dass die Forscher bei der Analyse einer alternativen Angriffsvariante, die den Einsatz des FUSE-Mechanismus anstelle von bind-mount zur Einbindung eines großen Verzeichnisses beinhaltet, auf eine weitere Schwachstelle (CVE-2021-33910) gestoßen sind, die den Systemmanager systemd betrifft. Es stellte sich heraus, dass beim Versuch, ein Verzeichnis über FUSE zu mounten, dessen Pfadlänge 8 MB überschreitet, ein Stack-Speicherüberlauf im Initialisierungsprozess (PID1) auftritt, der zu einem Absturz führt und das System in einen "Panic"-Zustand versetzt.
Das Problem liegt darin, dass systemd den Inhalt von /proc/self/mountinfo überwacht und das Mount-Point in der Funktion unit_name_path_escape() verarbeitet, in der die Operation strdupa() ausgeführt wird, die die Daten im Stack und nicht im dynamisch zugewiesenen Speicher platziert. Da die maximale Größe des Stacks über RLIMIT_STACK begrenzt ist, führt die Verarbeitung eines zu langen Pfades zum Mount-Point zum Absturz des Prozesses PID1 und zum Stillstand des Systems. Für den Angriff kann ein einfacher FUSE-Modul in Kombination mit der Verwendung eines Verzeichnisses mit einer hohen Verschachtelung, dessen Pfadlänge 8 MB überschreitet, genutzt werden.
Das Problem tritt ab systemd 220 (April 2015) auf, wurde jedoch bereits im Hauptrepository von systemd behoben und in Distributionen wie Debian, Ubuntu, Fedora, RHEL, SUSE und Arch korrigiert. Interessanterweise funktioniert im systemd 248 der Exploit nicht aufgrund eines Fehlers im code von systemd, der beim Verarbeiten von /proc/self/mountinfo zu einem Absturz führt. Zudem gab es 2018 eine ähnliche Situation: beim Versuch, einen Exploit für die Sicherheitsanfälligkeit CVE-2018-14634 im Linux-Kernel zu schreiben, stießen Forscher von Qualys auf drei kritische Sicherheitsanfälligkeiten in systemd.
Quelle: opennet.ru
