Sicherheitsforscher von Qualys haben Details zu zwei Schwachstellen veröffentlicht, die den Linux-Kernel und den Systemmanager systemd betreffen. Die Schwachstelle im Kernel (CVE-2021-33909) ermöglicht es einem lokalen Benutzer, durch Manipulationen mit tief verschachtelten 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 Ubuntu 20.04/20.10/21.04, Debian 11 und Fedora 34 in der Standardkonfiguration vorzubereiten. Es wird angemerkt, dass andere Distributionen nicht getestet wurden, theoretisch jedoch auch anfällig sind und angegriffen werden können. Der vollständige Code der Exploits soll nach der umfassenden Behebung des Problems veröffentlicht werden, bisher ist nur ein eingeschränkter Prototyp verfügbar, der zu Systemabstürzen führt. Das Problem besteht seit Juli 2014 und betrifft Kernel-Versionen ab 3.16. Der Fix für die Schwachstelle wurde in Abstimmung mit der Community am 19. Juli in den Kernel aufgenommen. Die wichtigsten Distributionen haben bereits Paketupdates mit dem Kernel bereitgestellt (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).
Die Schwachstelle wird durch das Fehlen einer Überprüfung des Ergebnisses der Typumwandlung von size_t in int vor der Durchführung von Operationen im seq_file-Code verursacht, der zur Erstellung von Dateien aus einer Sequenz von Einträgen dient. Das Fehlen der Überprüfung kann dazu führen, dass beim Erstellen, Einhängen und Löschen einer Verzeichnisstruktur mit sehr hoher Verschachtelung (Pfadlänge über 1 GB) in einen Bereich außerhalb des Puffers geschrieben wird. Infolgedessen kann ein Angreifer erreichen, dass eine 10-Byte-Zeichenkette "//deleted" mit einer Offset-„- 2 GB - 10 Byte“ geschrieben wird, die auf den Bereich zeigt, der unmittelbar dem reservierten Puffer vorausgeht.
Der vorbereitete Exploit benötigt 5 GB RAM und 1 Million freie Inodes. Die Funktionsweise des Exploits besteht darin, durch den Aufruf von mkdir() eine Hierarchie von etwa einer Million verschachtelten Verzeichnissen zu erstellen, um eine Pfadlänge von über 1 GB zu erreichen. Dieses Verzeichnis wird über ein Bind-Mount in einem separaten Benutzerraum (user namespace) eingehängt, bevor die Funktion rmdir() zum Löschen aufgerufen wird. Gleichzeitig wird ein Thread erstellt, der ein kleines eBPF-Programm lädt, das nach der Überprüfung des eBPF-Pseudocodes, aber vor der JIT-Kompilierung blockiert wird.
Im nicht privilegierten Namensraum der Benutzeridentifikatoren wird die Datei /proc/self/mountinfo geöffnet und der lange Pfad des über einen Bind-Mount gemounteten Verzeichnisses wird gelesen, was dazu führt, dass die Zeichenkette «//deleted» in den Bereich vor dem Beginn des Puffers geschrieben wird. Die Position für das Schreiben der Zeichenkette wird 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 Schreibvorgang außerhalb des Puffers in eine kontrollierte Lese- und Schreibmöglichkeit in andere Kernelstrukturen umgewandelt, indem mit den BTF- und map_push_elem-Strukturen manipuliert wird. Infolgedessen bestimmt der Exploit den Speicherort des Puffers modprobe_path[] im Kernel und überschreibt darin den Pfad «/sbin/modprobe», was es ermöglicht, beim Ausführen des Aufrufs request_module(), der zum Beispiel bei der Erstellung eines Netlink-Sockets erfolgt, jede ausführbare Datei mit Root-Rechten zu starten.
Forscher führen mehrere Umgehungsmethoden zum Schutz an, die nur für einen spezifischen Exploit wirksam sind, aber das zugrunde liegende Problem nicht beheben. Es wird empfohlen, den Parameter «/proc/sys/kernel/unprivileged_userns_clone» auf 0 zu setzen, um das Mounten von Verzeichnissen in einem separaten Namensraum für Benutzeridentifikatoren zu verhindern, sowie «/proc/sys/kernel/unprivileged_bpf_disabled» auf 1 zu setzen, um das Laden von eBPF-Programmen in den Kernel zu untersagen.
Bemerkenswert ist, dass die Forscher beim Untersuchen einer alternativen Angriffsvariante, die die FUSE-Mechanismus anstelle von Bind-Mounts zum Mounten eines großen Verzeichnisses verwendet, 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, im Initialisierungsprozess (PID1) ein Stapelspeicherüberlauf 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 analysiert und jeden Mountpunkt in der Funktion unit_name_path_escape() verarbeitet, in der die Operation strdupa() durchgeführt wird, die die Daten auf dem 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 Mountpfades zu einem Absturz des Prozesses PID1 und stoppt das System. Zum Angriff kann ein einfacher FUSE-Modul in Kombination mit einem Verzeichnis mit einer hohen Verschachtelungstiefe verwendet werden, dessen Pfadlänge 8 MB überschreitet.
Das Problem tritt seit systemd 220 (April 2015) auf, wurde jedoch im Hauptrepository von systemd behoben und in den Distributionen (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch) behoben. Bemerkenswert ist, dass der Exploit in der Version systemd 248 aufgrund eines Fehlers im systemd-Code, der zu einem Absturz bei der Verarbeitung von /proc/self/mountinfo führt, nicht funktioniert. Interessant ist auch, dass 2018 eine ähnliche Situation auftrat und Forscher von Qualys, als sie versuchten, einen Exploit für die Schwachstelle CVE-2018-14634 im Linux-Kernel zu entwickeln, auf drei kritische Schwachstellen in systemd stießen.
Quelle: opennet.ru
