Dieses Tutorial ist aus einer kleinen Hack Aktion entstanden die
hier
zu lesen ist. Ich beschreibe Anhand eines Scripts von Warrantmaster eine PHP
Code Injection.
Also der liebe Warrantmaster hat zwei einfache Fehler gemacht. Erstens hat er
uns einen Flashfilm zum hacken vorgesetzt. Was natürlich kriminelle Energien
freisetzt. Zweitens hat er sich nur darauf konzentriert den Flashfilm abzusichern
und vergessen das drumherum Sicher zu machen. Somit konnte ich nicht nur sein
Flashfilm knacken sondern auch seine beachtliche 7 GB Pornosammlung saugen.
Danke Warrantmaster
Da Anzugreifen wo es offensichtlich ist nicht immer die Beste Idee. Wie gesagt
wird gern das ganze Drumherum vergessen. Da Warrants Komponenten auch Teilweise auf
PHP aufsetzen fand ich schnell eine Lücke. Dummerweise in dem einfachsten Script,
dem Counter:
PHP-Code:
$filelocation="counter.txt";
$newfile = fopen($filelocation,"r+");
$add = "&daten=$daten";
fwrite($newfile, $add);
fclose($newfile);
include($filelocation);
Auf Sechs Zeilen verteilen sich hier zwei Schwerwiegende Fehler:
1. Fehlende Filterung der Eingabedaten
$daten wird nicht gefiltert/validiert und direkt die Datei 'counter.txt' geschrieben.
2. Anwenden von include auf ungefilterte Eingabedaten
include wird direkt auf 'counter.txt' angewendet. Prinzipiell nicht Falsch doch
in Verbindung mit dem ersten Fehler ergibt sich die Möglichkeit für einen Angriff
der unter (PHP) Code Injection bekannt ist.
Code Injection bedeutet ganz einfach das ein Angreifer seinen Code injiziert und
im Kontext des Servers ausführen kann.
Zum testen habe ich einfach über die URL die Variable $daten mit einem phpinfo()
Befehl gefüllt.
Code:
http://example.com/counter.php?daten=<?php echo phpinfo() ?>
Der String wird direkt in 'counter.txt' geschrieben, diese wird wiederrum
mittels 'include' aufgerufen. 'include' führt natürlich auch PHP Code
aus. Da $daten ungefiltert geschrieben wird, kann 'include' unseren Code
problemlos ausführen und wir bekommen eine PHP Info im Browser angezeigt.
Um Warrantmasters Passwort herauszubekommen musste ich nur die richtige
PHP Datei auslesen.
Code:
http://example.com/counter.php?daten=<?php readfile('path/to/blah.php') ?> Was lernen wir daraus?
* Eingabedaten
immer Filtern.
* Eingabedaten (egal ob gefiltert oder nicht)
niemals mit include, require
oder eval ausführen.
* Darauf achten wo Eingabedaten hin gelangen.
Lösung:
PHP-Code:
$filelocation="counter.txt";
$newfile = fopen($filelocation,"r+");
$add = (int)$_GET['daten'];
fwrite($newfile, $add);
fclose($newfile);
echo "&daten=".file_get_contents($filelocation);
In 'counter.txt' wird nun nurnoch ein Integer geschrieben und die Datei wird nicht
ausgeführt sondern als String eingelesen und dann ausgegeben.
Wie man sieht ist die Lösung genau wie der Angriff sehr simpel. Man muss sich
eigentlich nur ein wenig damit Auseinandersetzen und wissen wo mögliche
Angriffsflächen sind. Mit einfachen Mitteln könnte man so seine Scripte schon
um ein vielfaches sicherer machen.