Montag, 11. Juni 2012


Topthema

Donnerstag, 4. Dezember 2008 | Topthema

About Security #184: Schwachstellen-Suche: OS Command Injection

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

Das Einschleusen von Shell-Befehlen, die sog. OS Command Injection, ist das Thema dieser Folge. Derartige Schwachstellen können in jeder Webanwendung vorkommen, die Benutzereingaben ungeprüft für Betriebssystem-Aufrufe verwendet.

Einführung

Im allgemeinen stellen die vorhandenen APIs der Webserver-Plattformen alle nötigen Funktionen für die Interaktion mit dem Betriebssystem des Servers zur Verfügung. Egal ob Zugriffe auf das Dateisystem, die Kommunikation mit anderen Prozessen, die Kommunikation über das Netzwerk oder sonstige Funktionalitäten des Betriebssystems, für fast alle Zwecke gibt es passende Funktionen in den APIs. Trotzdem gibt es immer wieder Situationen, in denen der direkte Aufruf von Befehlen des Betriebssystems dem indirekten Aufruf über die APIs vorgezogen wird. Zum Beispiel, weil der direkte Aufruf schneller oder flexibler ist, oder weil er für einen bestimmten Zweck einfacher als ein API-Aufruf zu realisieren ist. Werden dabei Benutzereingaben an den Shell-Befehl durchgereicht, kann ein Angreifer dadurch unter Umständen eigene Befehle einschleusen.

Die für den Aufruf der Systembefehle verwendeten Funktionen, z.B. exec in PHP oder wscript.shell in ASP, enthalten keinerlei Einschränkungen für die aufzurufenden Befehle und/oder die verwendeten Parameter. Sie reichen die Daten lediglich an das Betriebssystem weiter.

Command Injection mit Perl

Ein klassisches Beispiel für eine Command-Injection-Schwachstelle ist das CGI-Programm finger.cgi, z.B. in folgender Form:

#!/usr/local/bin/perl
# finger.cgi - an unsafe finger gateway
require 'cgi-lib.pl';
print &PrintHeader;
if (&ReadParse(*in)) {
  print "<pre>\n";
  print `/usr/bin/finger $in{'username'}`;
  print "</pre>\n";
}
else {
  print "<html> <head>\n";
  print "<title>Finger Gateway</title>\n";
  print "</head>\n<body>\n";
  print "<h1>Finger Gateway</h1>\n";
  print "<form method=POST>\n";
  print "<p>User@Host: <input type=text name=\"username\">\n";
  print "<p><input type=submit>\n";
  print "</form>\n";
  print "</body> </html>\n";
}

Das sieht erst mal ganz harmlos aus. Wird als username ein Benutzername eingegeben, ist es das auch: Das Skript ruft /usr/bin/finger mit dem Benutzernamen als Parameter auf und gibt das Ergebnis aus. Aber was passiert, wenn statt eines Benutzernamens z.B.

foo; /bin/rm -r /

eingegeben wird? Das Skript ruft

/usr/bin/finger foo; /bin/rm -rf /

auf, und da ein ; zwei Befehlsaufrufe trennt, wird erst

/usr/bin/finger foo

ausgeführt und das Ergebnis ausgegeben und danach

/bin/rm -rf /

ausgeführt und damit alles gelöscht, was der Benutzer, mit dessen Rechten das Skript läuft, löschen darf. Statt eines ; können auch andere Metazeichen zur Manipulation des Parameters verwendet werden, z.B. das Pipe-Symbol ¦ zur Verknüpfung zweier Befehle.

Diese Schwachstelle ist uralt, sie stammt noch aus den Anfangszeiten des WWW, doch aktuelle Entsprechungen gibt es immer wieder, oft im Zusammenhang mit Kontaktformularen, die für den Versand einer E-Mail ein externes Programm aufrufen.

Command Injection mit ASP

Das folgende Skript gibt den Inhalt eines ausgewählten Logfiles aus:

<%
Set oScript  = Server.CreateObject("WSCRIPT.SHELL")
Set oFileSys = Server.CreateObject("Scripting.FileSystemObject")

myCMD      = "type c:\inetpub\wwwroot\log\" & Request.Form("FileName")
myTempFile = "c:\" & oFileSys.GetTempName()

Call oScript.Run("cmd.exe /c" & myCMD & ">" & myTempFile, 0, True)
Set oFile = oFileSys.OpenTextFile(myTempFile, 1, False, 0)
%>

Korrekt verwendet, wird der von Benutzer gelieferte Parameter FileName in den Befehlsaufruf eingesetzt, der Befehl aufgerufen und das Ergebnis ausgegeben. Wie im Perl-Beispiel kann ein Angreifer auch hier Shell-Metazeichen verwenden, um den vorgegebenen Befehl zu manipulieren und eigene Befehle einzufügen. Das &-Zeichen verkettet mehrere Befehle miteinander. Bei der Eingabe von z.B.

last5.log & dir c:\

wird auch das Verzeichnis von Laufwerk c: ausgegeben.

Schwachstellen finden
About Security: Die komplette Serie

Bereits beim Sammeln der Informationen über die Webanwendung wurden die Parameter ermittelt, mit denen erkennbar auf das Betriebssystem zugegriffen wird, z.B. bei Zugriffen auf das Dateisystem oder dem Aufruf externer Programme. Diese Parameter werden nun daraufhin untersucht, ob darüber zusätzliche Befehle eingeschleust werden können. Generell kommt jeder Parameter in jeder Funktion der Webanwendung als möglicher Angriffspunkt in Frage, und bei einer gründlichen Untersuchung der Webanwendung sollten alle geprüft werden. Für den Anfang reicht aber eine Prüfung der Parameter, die eindeutig für Aufrufe von Systembefehlen verwendet werden.

Shell-Metazeichen

Die verschiedenen Kommandointerpreter verwenden die Shell-Metazeichen nicht einheitlich, und da nicht mit Sicherheit bekannt ist, welcher Kommandointerpreter am Ende den Befehl ausführt, müssen beim Test generell alle Möglichkeiten betrachtet werden. Wie schon bei Dateisystemzugriffen ist es durchaus möglich, das z.B. der Webserver unter Linux läuft, aber ein Programm auf einem Windows-Server aufgerufen wird (siehe About Security #180).

In der nächsten Folge geht es weiter um die Suche nach Command-Injection-Schwachstellen.

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

Kommentare

Folgende Links könnten Sie auch interessieren