Mittwoch, 8. Februar 2012 |
Nach dem in About Security #184, #185 und #186 beschriebenen Einschleusen von Shellbefehlen in Systemaufrufe geht es ab dieser Folge um das Einschleusen von Schadcode in Skriptsprachen und die Suche danach.
Gelingt es einem Angreifer, eigenen Code in den Code der Webanwendung einzuschleusen, kann er damit die Kontrolle über den angegriffenen Server übernehmen. Derartige Angriffe sind im wesentlichen in zwei Situationen möglich:
Der zweite Fall wurde bereits im Rahmen der Suche nach Directory-Traversal-Schwachstellen (About Security #177 - #182) und Remote File Inclusion (About Security #183) behandelt, so das im folgenden nur die Ausführung von Code mit vom Benutzer manipulierbaren Daten darin behandelt werden muss.
Die meisten Skriptsprachen unterstützen die dynamische Ausführung während der Laufzeit generierten (neuen) Codes. Dies ermöglicht die Entwicklung von Anwendungen, die ihren Code als Reaktion auf eingegebene Daten und aktuelle Bedingungen dynamisch anpassen. Werden dabei vom Benutzer manipulierbare Daten verwendet, kann ein Angreifer unter Umständen eigenen Code bzw. eigene Befehle einschleusen.
In ASP wird die Funktion Execute() für die dynamische
Ausführung von Code verwendet. Zum Beispiel könnte eine
Suchfunktion vom Benutzer erzeugte, gespeicherte Suchanfragen
unterstützen, die dann als dynamisch erzeugte Links in der
Benutzeroberfläche integriert werden. Die Benutzer rufen die
Suchfunktion dann über einen Link wie z.B.
http://www.server.example/suchen.asp?suche=\$meinesuche%3dsuchwort
auf. In der Webanwendung wird die Suchfunktion durch dynamisch erzeugte
Variablen mit den im Parameter suche übergebenen
Name/Wert-Paar realisiert, im Beispiel mit der Variable
meinesuche und deren Wert suchwort:
Dim neuesuche
neuesuche = Request("suche")
Execute(neuesuche)
Ein Angreifer kann diese Situation ausnutzen, um eigenen ASP-Code in den
Execute()-Aufruf einzuschleusen. Normalerweise werden in ASP
Befehle durch Newline-Zeichen getrennt, für den Aufruf der Funktion
Execute() können sie aber auch durch den Doppelpunkt
: zu einem Batch verbunden werden, z.B. so:
http://www.server.example/suchen.asp?suche=\$meinesuche%3dsuchwort:neuerBefehl
Um den Inhalt der Datei c:\boot.ini in eine Datei unterhalb
des Web-Wurzelverzeichnis schreiben zu lassen, kann das ASP-Skript aus
About Security
#184
angepasst werden:
Dim angriff
Set angriff = Server.CreateObject("WSCRIPT.SHELL")
Call angriff.Run("cmd.exe /c type c:\boot.ini > c:\inetpub\wwwroot\ini.txt", 0, True)
Alle Befehle können dann, durch : zu einem Batch
verbunden, an die ursprüngliche URL angehängt werden:
http://www.server.example/suchen.asp?suche=\$meinesuche%3dsuchwort:Dim+
angriff:Set+angriff+=+Server.CreateObject("WSCRIPT.SHELL"):Call+angriff
.Run("cmd.exe+/c+type+c:\boot.ini+>+c:\inetpub\wwwroot\ini.txt",+0,+Tru
e)
Sämtliche Leerzeichen werden dabei durch +-Zeichen
ersetzt.
Die Ausgabe von boot.ini oder auch /etc/passwd
unter Unix/Linux sind beliebte Standardbeispiele zum Ausspähen von
Informationen. Für einen Angreifer gibt es natürlich viel
interessantere Möglichkeiten, z.B. das Ausführen beliebiger
Shellbefehle oder das Installieren einer Hintertür. Auch das ist durch
das Einschleusen entsprechenden ASP-Codes möglich.
In PHP erfüllt die Funktion eval() den gleichen Zweck wie
Execute() in ASP. Das ASP-Beispiel könnte in PHP
folgendermaßen aussehen:
http://www.server.example/suchen.php?suche=\$meinesuche%3dsuchwort
und
$neuesuche = $_GET['suche'];
eval("$neuesuche");
Wie im ASP-Beispiel kann ein Angreifer auch hier eigenen Code einschleusen,
nur eben PHP- statt ASP-Code. Wie beim Einschleusen von Shellbefehlen kann
das Semikolon ; verwendet werden, um mehrere Befehle zu einem
Batch zusammen zu fassen. Um z.B. die Datei /etc/passwd
anzuzeigen, können z.B. die Befehle file_get_contents()
oder system() verwendet werden:
http://www.server.example/suchen.php?suche=\$meinesuche%3dsuchwort;%20echo
%20file_get_contents('/etc/passwd')
oder
http://www.server.example/suchen.php?suche=\$meinesuche%3dsuchwort;%20syst
em('cat%20/etc/passwd')
Die Leerzeichen werden URL-kodiert als %20 eingegeben.
Perl kennt ebenfalls eine eval()-Funktion, die in genau der
gleichen Weise ausgenutzt werden kann. Evtl. muss das Semikolon URL-kodiert
werden (; = %3b), damit es nicht vom CGI-Parser als
Trennzeichen zwischen Parametern interpretiert wird.
Wie Sie Schwachstellen, die das Einschleusen von Skriptcode ermöglichen, finden und wie Sie derartige Angriffe verhindern können, erfahren Sie in der nächsten Folge.
Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!