Hauptmenü

Untermenü

Sicher programmieren - Dateiuploads Teil 1

1. Die Abschnitte

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