Sicher programmieren - Dateiuploads Teil 1
1. Die Abschnitte
- Einführung
- Informationen
- Desinformation
- GET-Parameter
- POST-Werte
- JavaScript-Hacks
- SQL-Injections Teil 1
- SQL-Injections Teil 2
- Dateiuploads Teil 1
- Dateiuploads Teil 2
- Brute-Force-Attacken
- Webhosting
2. Vorsicht vor fremden Daten!
Zunächst mal beschäftigen wir uns mit einem einfachen aber wirkungsvollen Hack, mit dem man einen Server abschießen kann. Da ich das bei euch aber nicht machen möchte, erkläre ich nur das Prinzip. Nehmen wir mal an, dass wir in unserem Shop einen Upload für Zip-Dateien anbieten. Um dem Benutzer dabei größtmöglichen Komfort anzubieten, sollen die automatisch entpackt werden. Natürlich bauen wir eine Größenbeschränkung ein, sagen wir mal 3 MB.
Nehmt euch nun mal die Datei hack.zip
im Ordner data
vor. Die ist läppische 437 KB groß. Also kann man die
nach dem erfolgreichen Upload sicher bedenkenlos entpacken. Oder? Macht es mal. Und das Ergebnis? Die Datei hack.txt
ist
auf einmal auf sage und schreibe 126 MB angewachsen. Wie das geht? Ganz einfach. Sie besteht aus 330.000 Zeilen zu je 200 Ü
s.
Also schlappe 66 Millionen Zeichen und obendrein UFT8-kodiert.
Diese riesige Menge kann man durch moderne Kompressionsalgorithmen extrem verkleinern. Als Rar-Datei wäre sie sogar nur 320 KB groß. Jetzt rechnet das mal um den Faktor 7 (3 MB Begrenzung) hoch, so läge das Ergebnis bei fast 900 MB für eine Datei. Das macht man dann ein paar Mal und irgendwann ist die Platte voll und der Server verabschiedet sich in die ewigen Jagdgründe. Ach ja, falls ihr die Textdatei in einem Editor öffnen wollt, so ereilt den mit Sicherheit dasselbe Schicksal.
Mein Tipp
Um so etwas zu verhindern, sollte auf jeden Fall ein Virenscanner auf dem Server installiert sein. Und meiner Meinung nach sollte man den Upload solcher Dateien eh nicht erlauben. Da können gewiefte Hacker noch ganz andere Dinge machen.
3. Bilder
Man glaubt es kaum, aber auch damit kann man Schindluder treiben. Vor allem, wenn der Programmierer nicht aufmerksam ist. Geht jetzt
mal mit eurem Browser in den Unterordner upload
. Dort gibt es ein kleines Formular, mit dem man Bilder hochladen kann.
Und dafür wählt ihr die Datei hack.gif
im Ordner data
. Übrigens, das funktioniert nur, wenn sich der Oberordner
sicher_programmieren
im Root-Verzeichnis des Webservers befindet. Ansonsten müsst ihr in der index.php
im
Order upload
den Pfad entsprechend anpassen.
Die index.php
im Ordner upload
Wie ein Dateiupload funktioniert, habe ich euch schon hier gezeigt, darum nur
mal die Feinheiten. Zunächst mal legen wir ein Array mit den Endungen der erlaubten Dateitypen fest. Das geschieht mit $filetype
= array('.gif','.jpg');
. Danach prüfen wir, ob unser Bild die Endung .gif
hat (if ('.gif' == substr
($name, - 4))
).Wenn dem so ist, verschieben wir die Datei in den Unterordner pics
und wenn das geklappt hat, leiten
wir auf die Seite list_gif.php
inklusive eines Parameters (link=bla.php
) weiter.
Und dort macht unser Programmierer einen entscheidenden Fehler. Er überprüft den übergebenen GET
-Parameter nicht! Schaut
mal ruhig in die bla.php
. Auch wenn die Vorgehensweise eher suboptimal ist. Aber darum geht es hier nicht.
require ('../db.inc.php');
if (!empty($_GET['link']))
{
include ($_GET['link']);
}
Der Hack
Das Prinzip habe ich schon hier erläutert. Ändert nun den Parameter link=bla.php
zu
link=pics/hack.gif
. Den entsprechende Ordner herausfinden, wo die Bilder liegen, dürfte nicht schwer sein. Und das
Ergebnis? Nun zunächst mal kommt erst ein wenig Buchstabensalat. Aber dann erscheint auf einmal das Passwort zu
unserer Datenbank! Wenn nicht, so habt ihr Vollhonks keines vergeben. Und das ist noch schlimmer.
Wie geht denn so was?
Öffnet mal die hack.gif
mit einem normalen Texteditor. Keine Angst, hier passiert nichts. Und das Ergebnis sieht dann in
etwa so aus.
Zuerst ein GIF89a gefolgt von einem ziemlichen Buchstabensalat <?php echo $password; ?>:
Die erste Zeile enthält die Informationen für ein weißes 1x1 Pixel großes Gif-Bild. Danach aber kommt PHP-Code. Und der wird gnadenlos
ausgeführt, da diese Datei ohne Prüfung einfach so inkludiert wird. Die Sache mit dem $password
kann man relativ leicht in
Erfahrung bringen, da die Variablenbezeichnung doch meistens recht ähnlich ist. Wenn es beim ersten Mal nicht funktioniert, dann arbeitet
man halt mit $passwort
oder $pw
, bis man die Info hat.
Das kann man dann auch mit den übrigen Zugangsdaten machen, bis man alle zusammen hat. Dann schleust man noch ein Bild ein, mit dem man die komplette Datenbank ausgelesen kann. Und dann ist Holland in Not.
Also noch mal
Überprüft jedes Mal die Parameter, die ihr per GET
oder POST
entgegen nehmt. Da kann man wirklich üble Dinge mit
anstellen!
zurück zum vorherigen Abschnitt weiter zum nächsten Abschnitt