Fragen? Antworten! Siehe auch: Alternativlos
Als ich "100% reliable preauth RCE VPN exploit using format strings" gelesen habe, wurde ich neugierig. Auf modernen Linux-Systemen ist das nämlich nicht ganz so einfach, also habe ich mich auf die Lektüre eines schönen Exploits gefreut. Stattdessen finde ich so ziemlich das einfachste, was so geht. Daher mal ein paar Worte dazu, damit auch Laien das etwas besser einordnen können:Dazu ein bisschen Kommentar von mir: Format String Bugs sind in der Tat vergleichsweise einfach zu finden. Wer die in seinem Code hat, hat wenig Ausreden vorzubringen. Aber ganz so trivial ist es dann doch nicht. In der Praxis findet man häufig irgendwelche Präprozessor-Makro-Höllen und Ketten von Funktionen und am besten noch nichts const deklariert. Insofern: Vergleichsweise einfach, aber nicht unbedingt trivial.Format-String-Lücken sind sehr einfach über statische Codechecker zu finden. Quasi jeder Audit hätte das finden sollen. Mit entsprechenden Compiler-Optionen gibt es da auch Warnings.
Bei modernen Linux-Systemen wird sowas auch zur Laufzeit abgefangen: da wird dann nachgeschaut, ob %n in schreibbarem Speicher liegt (= nicht fest einkompiliert, also eventuell von einem Angreifer). Falls ja, wird abgebrochen. Dadurch ist die Lücke nicht komplett weg, aber zumindest Code-Execution wird erheblich erschwert bis unmöglich gemacht, da %n das Arbeitspferd für Code-Execution-Exploits ist. Dazu muss man nicht einmal am Quellcode schrauben.
Der Exploit scheint feste Offsets zu benutzen. Also gibt es da auch keine Address Space Layout Randomization?
Zudem treibt deren Exploit Schindluder mit Global Offset Table und Procedure Linkage Table. Dagegen gibt es RELRO: entsprechende Bereiche sind zu normalen Laufzeit nicht mehr schreibbar, wodurch es nochmal etwas schwieriger wird, einen Exploit zu erstellen.
Ich habe keinen Zugang zum Produkt, daher sind das alles unverifizierte Vermutungen. Aber scheinbar sind die echt noch in der Steinzeit, unfassbar. Oh, und je nach CPU-Architektur sind diese Sachen auch gut in Binärcode zu finden. Ich würde also davon ausgehen, dass kompetente Geheimdienste das kannten.
Die printf-Implementation der dietlibc unterstützt %n schlicht gar nicht. Microsoft hatte das aus der Visual Studio Runtime auch per Default deaktiviert und man muss das von Hand anschalten.
Der Punkt mit ASLR und RELRO stimmt auch, aber das ist halt eine Mitigation-Schlacht am Ende. Da bin ich kein Fan von. Damit wird das Exploiten dann schwieriger, ja, aber der Bug ist nicht weg. Und durch die großartige Softwarequalität da draußen haben wir die User konditioniert, dass sie sich selbst nach Crashes neustartende Software nicht nur tolerieren sondern gutheißen, und dass die Leute sich an ständige Segfaults in ihren Logs gewöhnt haben und kaum noch jemand überhaupt guckt. Im Übrigen hat RELRO auch Nachteile. Die Relokationen müssen alle am Anfang gemacht werden, damit danach die Relokationstabelle read-only sein kann, und das führt bei manchen Szenarios zu merkbaren (nicht nur messbaren) Verlangsamungen, besonders bei großen C++-Programmen mit Tonnen von Shared Libraries, z.B. KDE oder so.
Insofern: Ja, der Punkt mit RELRO ist korrekt, und die Linux-Distributionen haben angefangen, komplett auf RELRO umzustellen. Die CPUs sind ja auch schnell genug. Ich erinnere mich noch, als man kleinere Programme statisch gelinkt hat, weil dynamisches Linken zu langsameren Startup-Zeiten geführt hat. Deshalb ja auch dietlibc als statische Library für kleine Programme.
Ich würde die aber viel lieber dafür kritisieren, dass ihre Software kacke ist, als dass sie auch noch die Best Practices bei den Compiler-Flags verkackt haben. Nicht dass da draußen jemand denkt, Format-String-Bugs seien nicht so schlimm, wenn man RELRO anmacht oder so. Fixt eure fucking Bugs.
Früher war der Developer für die Bugs und der Ops-Typ für das Bauen und Ausrollen zuständig, und der hat sich dann um RELRO gekümmert. Heute mit Devops oder gar Devsecops machen das dieselben Gestalten, und damit ist dann plötzlich Zeit für RELRO nicht mehr für das Fixen von Bugs da. Das ist zum Kotzen und einer der Gründe, wieso Devops und Devsecops Mist ist.