Dev News Daily ENDE

Eine Registrierung ist eine Angriffsfläche, auch ohne etwas dahinter

Der nützlichste Fehler der Woche hatte nichts dahinter. Die Windows-Rechteausweitung aus dem Project-Zero-Bericht war ein systemweit registriertes COM-Objekt, dessen Server-DLL nicht existierte — sie zeigte auf einen Pfad in C:\ProgramData, wo jeder Nutzer Dateien anlegen darf. Der Exploit bestand darin, die Datei zu erzeugen, deren Vorhandensein das System zugesichert hatte.

Diese Form lohnt sich, von COM zu lösen, denn sie kehrt überall wieder, wo ein System einen Namen auf einen Ort auflöst:

Ein verwaister Verweis auf einen beschreibbaren Pfad ist ein latenter Fehler — mit oder ohne Server. Die Registrierung ist die Angriffsfläche. Ob je ausgeliefert wurde, worauf sie zeigt, ist dem Angreifer gleich, der es liefern kann. PATH-Einträge auf weltweit beschreibbare Verzeichnisse, LD_LIBRARY_PATH im setuid-Kontext, eine Service-Unit mit einem Skript unter /tmp, ein Container-Image, das aus einem Build-Argument COPYt — dieselbe Klasse: ein Auflöser, der lädt, was an einem von dir kontrollierten Ort liegt.

Eine Registrierung ist eine Angriffsfläche, auch ohne etwas dahinter
Eine Registrierung ist eine Angriffsfläche, auch ohne etwas dahinter — Dev News Daily

„Unvollständiger Fix" ist das normale Ergebnis, wenn man den Lader statt den Verweis behebt. Diese CVE entstand, weil ein früherer Fix einen Weg schloss, das verwaiste Objekt zu laden, und das Objekt verwaist ließ; ein zweiter Lader erreichte es. Liegt die Ursache in einem schlechten Verweis, lässt das Beheben des diesmaligen Pfades den nächsten offen. Der dauerhafte Fix entfernt den Verweis oder macht den Ort unbeschreibbar.

Das Audit ist mechanisch — das ist die gute Nachricht. Man muss den Exploit nicht finden, um die Exposition zu finden. Zähle die Auflöser auf, denen ein privilegierter Prozess vertraut — Registry-CLSIDs, Bibliothekssuchpfade, Unit-Dateien, Plugin-Verzeichnisse — und frage bei jedem, ob ein Eintrag auf einen Ort zeigt, an dem ein weniger privilegierter Nutzer schreiben kann. Jedes „ja" ist ein Fehler, ob schon jemand die Nutzlast geschrieben hat oder nicht.

Die Ingenieursfassung der Regel ist kurz: Ein Name ist nur so vertrauenswürdig wie der am stärksten beschreibbare Ort, auf den er sich auflösen lässt. Dem COM-Objekt vertraute jeder Dienst der Maschine; dem Ort, auf den es zeigte, vertraute niemand. Diese Lücke ist die Schwachstelle — und sie braucht keine DLL, um real zu sein.