Piggy-Backing bei PHP CGI-Skripten

Datum: 17.03.2014
Betriebssystem: CentOS

Problemstellung: Weißer Bildschirm beim Laden der Startseite einer Domain. Betroffen war ein Plesk-Server mit CentOS als Betriebssystem und Apache als Webserver. Die Webseite läuft auf zugekaufter, IonCube-verschlüsselter PHP-Software. Aus diesem Grund und der Tatsache, dass der Code für PHP vor Version 5.3 geschrieben wurde, musste für diese Domain eine eigene PHP-Version kompiliert und bei Apache als CGI registriert werden.

Schon der erste Blick in index.php liefert die Ursache: am Dateianfang wurde Schad-Code eingefügt. Die verschlüsselte Software (oder auch IonCube) hat die Manipulation gemerkt und die Ausführung gleich gestoppt, daher die weiße Seite.

Der Zeitstempel der Datei liefert einen recht genauen Hinweis auf den Zeitpunkt der Manipulation. Da Angriffe erfahrungsgemäß über den Webserver erfolgen (und nur in seltenen Fällen über komprimittierte FTP-Accounts), werfen wir als nächstes einen Blick ins Access-Log und sehen uns die Einträge zu ungefähr dieser Zeit an. Der fragliche Aufruf sticht auch sofort ins Auge:

46.165.222.228 - - [17/Mar/2014:16:37:39 +0100] "POST /?%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C%75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F%73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F%66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%6E HTTP/1.1" 200 836 "" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

Decodiert man die URL-codierte Wurst erhält man:

-d allow_url_include=on -d safe_mode=off -d suhosin.simulation=on -d disable_functions="" -d auto_prepend_file=php://input -n

Offenbar versucht der Angreifer, dem Script Kommandozeilen-Parameter unterzujubeln.
Ein kurzer Test mit einem selbstgebastelten Skript, das die fraglichen Einstellungen ausgibt (einmal ohne und einmal mit der Hacker-Wurst aufgerufen) zeigt, dass das auch funktioniert.

Nach kurzer Googlerei finden wir im Newsarchiv von php.net selbst die Antwort: PHP 5.3.12 and PHP 5.4.2 Released!.

Demnach handelt es sich um eine Schwachstelle in Apaches CGI-Modul und betrifft PHP-Versionen vor Version 5.3.12. Betroffen sind URL-Parameter, die mit einem Bindestrich (bzw. URL-codiert %2D) beginnen und danach kein Gleichheitszeichen (=) enthalten. Diese werden nicht als String sondern als Array interpretiert.

Zur Überprüfung der Verwundbarkeit einer Seite empfiehlt der Artikel als simplen Test den Aufruf eines beliebigen PHP-Skripts auf der zu testenden Seite mit dem Parameter ?-s, also zB.:

http://flashcom.at/index.php?-s
# oder url-codiert:
http://flashcom.at/index.php?%2Ds

Bekommt man bei diesem Aufruf den Quellcode des Skripts zu sehen ist die Seite angreifbar. Tut sich nichts, ist sie es nicht.

Glücklicherweise wird in dem Artikel nicht nur vorgeschlagen, auf eine aktuelle PHP-Version zu wechseln (was in unserem Fall unmöglich ist), sondern auch eine Lösung für bestehende Systeme vorgeschlagen: das Umschreiben von URLs, deren Querystring mit einem Bindestrich (bzw. %2D) beginnt und kein Gleichheitszeichen enthält:

<ifmodule mod_rewrite.c>
RewriteEngine on
RewriteCond %{QUERY_STRING} ^(%2d|-)[^=]+$ [NC]
RewriteRule ^(.*) $1? [L]
</ifmodule>

In Plesk müssen dazu die folgenden Konfigurationsdateien angepasst werden:

/var/www/vhosts/domain-name.tld/conf/vhost_ssl.conf
/var/www/vhosts/domain-name.tld/conf/vhost.conf

Allerdings muss danach Apache erst dazu gebracht werden die Änderungen zu übernehmen. Im konkreten Fall hat es gereicht im Plesk-Admintool das Formular unter Websites & Domains / Erweiterte Operationen / Website-Skripting ohne Änderungen zu speichern.

Verweise & weiterführende Links

Fragen, Anmerkungen, Korrekturen zu diesem Artikel »