Direkt zum Inhalt
20.11.2008 - Fachbeitrag

PHP-Security auf shared Webservern

Vor den Funktionen system() und exec() haben wir schon immer gewarnt und in unseren Vorträgen und Artikeln beschrieben, wie man Webserver mit disable_functions, openbasedir und einer sauberen Firewall absichert.

Am 2. Juni 2006 mußte das das Team von Heinlein Support nun eine Warnung vor den Funktionen popen() und proc_open() herausgeben:
PHP-Sicherheit: Warnung vor popen() und proc_open()

Seit einigen Tagen stellen verschiedene Provider einen deutlichen Anstieg gehackter Kundenpräsenzen ("Defacements") und installierter Hintertüren auf vielen Webservern fest. Die offenbar sehr zielstrebig vorgehenden Angreifer nutzen dabei eine Vielzahl bekannter Sicherheitslücken aus. Diese sind größtenteils nicht neu und auf fachkundig administrierten Servern in der Regel auch abgesichert und deaktiviert.

Der Berliner Linux- und Security-Spezialist Heinlein Support warnt nun jedoch vor den Auswirkungen der PHP-Funktionen popen() und proc_open(), die bislang ein unbekanntes Schattendasein führten.

In den Angriffen der vergangenen Tage wurden diese Funktionen jedoch gezielt ausgenutzt, ermöglichen sie doch ebenfalls den Start von lokalen Shell-Kommandos auf dem Server. Sichert eine Webseite die Nutzung dieser Funktionen nicht richtig ab, kann ein Angreifer damit eigene Kommandos ausführen oder gar eigene Hintertüren installieren. Beim Einsatz sogenannter Bots verbinden sich diese mit IRC-Servern, um Kommandos des Angreifers entgegen zu nehmen. Die so infizierten Server lassen sich damit flexibel zu beliebigen Aktionen mißbrauchen.

Zugriffe auf das Dateisystem eines Webservers sind allgemein ein großes Problem und werden fachkundig mittels open_basedir abgesichert. Der Start von Shell-Kommandos in PHP-Scripten ermöglicht es Angreifern diese Beschränkungen zu umgehen, so daß sie Leserechte auf weite Teile des Dateisystems erhalten: Neben Systemdateien des /etc-Verzeichnisses, sind darüber hinaus auch temporäre Dateien mit Session-Informationen fremder Nutzer einsehbar. Von anderen Webpräsenzen auf dem gleichen Server sind die Passwörter .htpasswd-Dateien auslesbar, bzw. MySQL-Zugangsdaten einsehbar.

Pikanterweise sind die Probleme allesamt nicht neu. Anders als bei system() und exec() hat das PHP-Team es jedoch in der Vergangenheit versäumt vor popen() und proc_open() ausreichend zu warnen. Auf den Handbuchseiten der jeweiligen Funktionen finden sich keine Warnungen, auch bei der Besprechung verschiedener Sicherheitsstrategien im Manual des PHP-Projektes werden system(), exec() oder phpinfo() erwähnt -- der Verweis auf proc_open() und popen() fehlt aber in aller Regel (http://www.php.net/manual/en/ref.exec.php). Auch in den derzeit verfügbaren deutschen Büchern über PHP-Security sind diese Funktionen kaum bis gar nicht erwähnt. Eine trügerische Sicherheit für die Administratoren, die sich bislang vor dem unbefugten Starten von Systemkommandos sicher fühlten.

Aufgrund der geringen Bekanntheit haben nur wenige Hobby-Programmierer bislang diese Fuktionen benutzt, allerdings kommen sie zum Beispiel bei den weit verbreiteten Projekten mediaWiki und eGroupware zum Einsatz. Nach ersten Tests scheint eine Deaktivierung von popen() allerdings nur geringe Auswirkungen auf die Funktion dieser Programme zu haben, grundsäzlich bleiben sie lauffähig.

Sofern Programmierer saubere Eingabevalidierung betreiben und popen()-Aufrufe nur mit sicheren Parametern benutzen, droht dem Webserver keine Gefahr eines Angriffes von außen. Verarbeiten Programmierer jedoch ungefiltert Nutzereingaben in diesen Funktionsaufrufen, können Angreifer beliebige eigene Kommandos einschleusen, wie jüngst beim CMS open-medium geschehen (http://www.frsirt.com/english/advisories/2006/1977). Nicht zuletzt darf aber auch nicht vergessen werden, daß Angreifer gezielt versuchen könnten, sich einen Account bei einem Provider zu besorgen, um eigenen PHP-Code bequem selbst hochzuladen.

Administratoren sollten also versuchen, diese Funktionsaufrufe durch den Eintrag
disable_functions = show_source, system, shell_exec,
   passthru, exec, phpinfo, popen, proc_open

in der Datei php.ini zu verbieten, müssen dann jedoch kritisch beobachten, ob Funktionsstörungen bei Kundenpräsenzen auftreten.

Es scheint, als ob Programmierer und Administratoren zukünftig einen stärkeren Dialog über Serversicherheit führen müßten: Solange PHP-Anwendungen den Aufruf von externen Programmen nutzen, solange werden Administratoren Schwierigkeiten haben, den Server und seine Datein vor ungewollten Einblicken zu schützen. Auch die strikte Nutzung von Dateirechten und verschiedenen Userkennung bewirkt nur wenig Abhilfe, da der Webserver typischerweise weitreichende Leserechte in allen Webpräsenzen haben muß.

In unseren bisherigen Arbeiten dazu fehlte die Erwähnung von popen() und proc_open() -- wir werden Sie nachtragen. Trotzdem sei allen Administratoren unser vor einiger Zeit erschienene Artikel im Linux-Magazin ans Herz gelegt (den wir hier leider erst demnächst veröffentlichen dürfen), bzw. ein Besuch unserer Vorträge über PHP-Sicherheit empfohlen [Vortragsfolien].

Übrigens: An unserer Berliner Linux Akademie beschäftigen sich Kurse wie "PHP-Sicherheit", "Sicherheit für Server" oder "Apache2" unter anderem mit solchen Problematiken. Vielleicht sollte man sich weiterbilden bevor der Einbruch geschehen und der Schaden groß ist …

Einen Dank für die fachlichen Mitarbeit zur Herausgabe der popen()-Warnung geht an Peter Prochaska, unserem PHP-Security-Dozenten!

Laut Heinlein Support könnte das frei verfügbare AppArmor mit dem Apache-Modul mod_change hat eine Lösung sein: Es ermöglicht es, für einzelne Webpräsenzen verschiedene AppArmor-Profile zu übergeben, die den Dateizugriff auch bei externen Programmaufrufen kontrollieren können.