Aus Linux-Magazin 02/2011

SQL-Injection legt Newsletter lahm

© Gertie G., Photocase.com

Inn gewisser Weise passt der folgende Beitrag zum Schwerpunkt dieser Magazins-Ausgabe, demonstriert er doch am lebenden Webapplikations-Objekt die Verwundbarkeit einer Datenbank.

Die Sache begann sehr alltäglich: Im Zuge einer Wohnungssuche hatte ich mich irgendwann beim Immobilienmakler Immosky [1] für dessen Newsletter angemeldet. Als ich einige Zeit später eine Unterkunft gefunden hatte, wollte die nunmehr überflüssigen Empfehlungsschreiben wieder abbestellen. Ein Abmelden-Link im Newsletter führte mich zur Webseite des Schweizer Unternehmens. Die gab sich überraschend gesprächig: Offensichtlich für Debugging-Zwecke zeigte sie das SQL-Statement an, das meine Newsletter-Zusendung eben deaktiviert hatte.

Die Debugausgabe auf dem Produktivsystem lässt mich aufmerken werden: Webprogrammierer, denen so was egal ist, haben bestimmt noch Leichen im Keller. Auf mich wirkt die Debugausgabe wie eine Einladung zum Angriff. Sie hilft mir beim Einstieg, denn sie zeigt genau das SQL-Statement, das der Datenbankserver später abarbeiten wird. So sehe ich, welche Get- oder Post-Parameter wo in der Anfrage landen, ob die Webapplikation die Eingabe filtert und ob sie Sonderzeichen richtig schützt. Wer die Fehlermeldungen aus Abbildung  1 studiert, erfährt, dass Immosky einen Windows-Server mit PHP benutzt, der mehrere virtuelle Webserver anbietet und ohne Passwort per ODBC-Treiber aus PHP auf eine lokale MySQL-Datenbank zugegreift. Per Firebug [2] findet der Angreifer ferner aus den HTTP-Headern heraus, dass der Anbieter PHP  4.2.2 auf einem IIS  6.0 einsetzt – beide nicht aktuell und womöglich für bekannte Exploits empfänglich.

Abbildung 1: Die überflüssigen Fehlermeldungen verraten weitere Informationen über den Server – eine prima Einstieghilfe für Hacker.

Abbildung 1: Die überflüssigen Fehlermeldungen verraten weitere Informationen über den Server – eine prima Einstieghilfe für Hacker.

Meine Neugier auf fremden Webseiten zu befriedigen, versuche ich sehr sorgfältig zu organisieren. Lehne ich mich zu weit aus dem Fenster, droht Strafe wegen Ausspähens von Daten (siehe Kasten “Gesetzeslage”). Zwar ist das nur dann illegal, wenn die Daten besonders gesichert sind. Doch schreiben die StGB-Kommentare, dass es mehr auf den Wunsch des Betreibers nach Sicherung als auf deren tatsächliche Güte ankommt.

Gesetzeslage

Paragraf 202a StGB: Ausspähen von Daten

(1) Wer unbefugt sich oder einem anderen Zugang zu Daten, die nicht für ihn bestimmt und die gegen unberechtigten Zugang besonders gesichert sind, unter Überwindung der Zugangssicherung verschafft, wird mit Freiheitsstrafe bis zu drei Jahren oder mit Geldstrafe bestraft.

(2) Daten im Sinne des Absatzes 1 sind nur solche, die elektronisch, magnetisch oder sonst nicht unmittelbar wahrnehmbar gespeichert sind oder übermittelt werden.

Paragraf 263a StGB: Computerbetrug

(1) Wer in der Absicht, sich oder einem Dritten einen rechtswidrigen Vermögensvorteil zu verschaffen, das Vermögen eines anderen dadurch beschädigt, daß er das Ergebnis eines Datenverarbeitungsvorgangs durch unrichtige Gestaltung des Programms, durch Verwendung unrichtiger oder unvollständiger Daten, durch unbefugte Verwendung von Daten oder sonst durch unbefugte Einwirkung auf den Ablauf beeinflußt, wird mit Freiheitsstrafe bis zu fünf Jahren oder mit Geldstrafe bestraft.

Paragraf 303a StGB: Datenveränderung

(1) Wer rechtswidrig Daten (§ 202a Abs. 2) löscht, unterdrückt, unbrauchbar macht oder verändert, wird mit Freiheitsstrafe bis zu zwei Jahren oder mit Geldstrafe bestraft.

Paragraf 303b StGB: Computersabotage

(1) Wer eine Datenverarbeitung, die für einen anderen von wesentlicher Bedeutung ist, dadurch erheblich stört, dass er

1. eine Tat nach § 303a Abs. 1 begeht,

2. Daten (§ 202a Abs. 2) in der Absicht, einem anderen Nachteil zuzufügen, eingibt oder übermittelt oder

3. eine Datenverarbeitungsanlage oder einen Datenträger zerstört, beschädigt, unbrauchbar macht, beseitigt oder verändert,

wird mit Freiheitsstrafe bis zu drei Jahren oder mit Geldstrafe bestraft.

(2) Handelt es sich um eine Datenverarbeitung, die für einen fremden Betrieb, ein fremdes Unternehmen oder eine Behörde von wesentlicher Bedeutung ist, ist die Strafe Freiheitsstrafe bis zu fünf Jahren oder Geldstrafe.

Das Injizieren eigener Daten in Richtung Server passiert wie beim Cross-Site-Scripting über die HTTP-Parameter der Webseite-URL [3]. Serverseitig arbeitet ein CGI-Skript, das die Parameter entgegennimmt und zu einem Select-Statement in SQL umarbeitet. Und genau dabei lauern die Fallstricke.

Erstmal Anpiksen

Einen Schaden soll der erste Test aus juristischen, aber auch aus taktischen Gründen nicht anrichten – Hacker versuchen unterm Radar zu bleiben. Das gelingt, wenn ich die in der URL übergebenen Datenbankparameter um ein neutrales Element ergänze, also eines, dass das Ergebnis der Abfrage nicht verändert. So ergibt »A OR FALSE« wieder »A« . Der Debugcode in Abbildung  2 beweist, dass ich die Anfrage geeignet modifiziert habe.

Abbildung 2: Die SQL-Injection funktioniert offenbar. In diesem Beispiel bleibt der Angriff bewusst ohne Auswirkung auf die Datenbank.

Abbildung 2: Die SQL-Injection funktioniert offenbar. In diesem Beispiel bleibt der Angriff bewusst ohne Auswirkung auf die Datenbank.

Ein Cracker hätte die Bedingung im Parameter um »OR TRUE« ergänzt, was logisch immer »TRUE« ergibt. Praktische Folge: Die Immosky-Website hätte alle ihre Newsletterabonnements gekündigt. Den Erfolg erkennt der böswillige Angreifer an der möglicherweise höheren Laufzeit der Abfrage, wenn die Datenbank in allen Datensätzen ein Feld ändert.

Eigene Daten reinströmen lassen

Ich darf annehmen, dass die Immobiliendatenbank keinen Schaden nimmt, wenn ich versuche, mehr Datensätze zu sehen, als die aktuellen Suchkriterien eigentlich hergeben. Eine breiter angelegte, vom Anbieter vorgesehene Suche zeigt diese Daten nämlich ebenso an.

Beim Testen hilf mir der Trick mit »OR TRUE« : Akzeptiert das darunterliegende Skript die Injection, darf ich auf eine umfangreichere Ausgabe hoffen. Falls durch den Angriff ein Syntaxfehler entsteht, kommt entweder eine hilfreiche Fehlermeldung oder gar keine Ausgabe. So finde ich durch Versuch und Irrtum heraus, welche Parameter in das SQL-Statement eingehen und welche für andere Zwecke gedacht sind. Tatsächlich zeigt sich auch die Suchfunktion anfällig diesen Vorstoß, wie Abbildung  3 beweist.

Abbildung 3: Die offensichtlich unsinnigen Angebote beweisen: Auch die Suche ist angreifbar.

Abbildung 3: Die offensichtlich unsinnigen Angebote beweisen: Auch die Suche ist angreifbar.

Durch Experimente und in Kenntnis der booleschen Rechenregeln kriege ich sogar heraus, wie die einzelnen Suchparameter geklammert sind. Bei Immosky bietet sich an, zwei Suchparameter in der Suchmaske zu setzen und dann nur einen mit »OR TRUE« zu erweitern. So lassen sich SQL-Injections verfeinern.

Nur autoaggressiv

Wer nicht über fremde Webseiten herfallen will, der experimentiert besser mit eigenen. Ein Beispiel in PHP zeigt Listing  1, eines in Perl das Listing  2. Beide Skripte besitzen nur einen verwundbaren Parameter, »name« , der ohne Eingabekontrolle in die SQL-Query wandert. Beide Programme geben Feedback, indem sie das SQL-Statement und die erreichte Ausgabe auf einer Seite zeigen.

Listing 2

Injection-Dummy in Perl

01 #!/usr/bin/perl
02
03 use DBI;
04 use CGI;
05 my $q = new CGI;
06 my $name = $q->param("name");
07
08 print "Content-type: text/plain\n\n";
09
10 $dbh = DBI->connect("DBI:mysql:inject;" .
11 "host=localhost:3306", "inject", "inject")
12 or die("Connect failed. $DBI::errstr");
13
14 $query = "SELECT * FROM customers " .
15 "WHERE username LIKE '$name'";
16 print "$query\n";
17
18 $dbq = $dbh->prepare($query) or die
19 "Prepare failed. $dbh->err:$dbh->errstr";
20 $dbq->execute() or die
21 "Execute failed. $dbh->err:$dbh->errstr";
22 while ($hash = $dbq->fetchrow_hashref()) {
23 foreach my $key (keys %$hash) {
24 print "$key = $hash->{$key}\n";
25 }
26 print "---\n";
27 }
28
29 $dbq->finish();
30 $dbh->disconnect;

PHP birgt für den Angreifer einen Nachteil: Es ist nicht möglich, in einem »mysql_query()« -Aufruf mehr als einen SQL-Befehl per Semikolon getrennt mitzuschicken. Bei Perl gilt das nicht, wenn das Skript statt der verwendeten Prepare-Execute-Kombination direkt mit »do« arbeitet. Das ist nützlich, wenn die Injection zum Beispiel gleich einen neue Nutzer mit Admin-Rechten anlegen soll.

Schutz gegen Injections

Zwei Maßnahmen kann jeder Webprogrammierer gegen SQL-Injections ins Feld führen: Zum einen sollte er jede Eingabe zum Beispiel per regulärem Ausdruck prüfen, ob sie formal zulässig ist. Sind Wertebereiche der übergebenen Parameter bekannt, bezieht er die mit ein. Zum anderen können fast alle Sprachen Zeichenketten so umformen, dass sie keine Gefahr mehr für die Datenbank darstellen. Dazu verpacken sie kritische Sonderzeichen. Aus doppelten Gänsefüßchen wird damit etwa »"« . Das leistet in Perl die DBI-Funktion »quote()« und in PHP »mysql_real_escape_string()« . Wer Listing 1 und 2 in Betrieb hat, darf das gleich ausprobieren, indem er »$name« in beiden Skripten escaped und dann mit SQL-Injections experimentiert. Dabei helfen Cheat-Sheets wie [4], [5].

Listing 1

Injection-Dummy in PHP

01 <html>
02 <head>
03 <title>SQL-Inject</title>
04 </head>
05 <body>
06 <p>
07 <?php
08 $name = $_REQUEST["name"];
09 $query = "SELECT * FROM customers WHERE username LIKE '$name'";
10 echo "Query: " . $query . "<br />";
11 $conn_id = mysql_connect("localhost:3306", "inject", "inject");
12 mysql_select_db("inject");
13 $res = mysql_query($query);
14 if ($res)
15 {
16 while ($row = mysql_fetch_assoc($res))
17 {
18 foreach ($row as $key => $value)
19 {
20 echo "$key = $value<br />\n";
21 }
22 echo "<hr />\n";
23 }
24 mysql_free_result($res);
25 }
26 mysql_close();
27 ?>
28 </p>
29 </body>
30 </html>

Während Listing  1 nichts in der Richtung besitzt, betreibt das Perl-Skript ein ausbaufähiges Fehlerhandling. Statt der Ausgabe auf der Webseite per »die« würde sich eine automatische Mail an den Admin besser machen. Dem Nutzer reicht der Hinweis »Kommen Sie später wieder, wir haben ein Problem« aus. Eine eingebundene Funktion kann genau das leisten – mit dem Vorteil, dass der Admin jeden Fehler mitbekommt. Nebenbei eignet sich der Mechanismus als Frühwarnsystem für versuchte SQL-Injections.

Bei Seiten, die keine Daten vom Benutzer brauchen, sollte zudem der Datenbankuser des Skriptes nur Leserechte auf die Datenbank haben. Allerdings ist das in der Praxis selten möglich, da schon ein Gästebuch nach Schreibzugriff verlangt.

Nicht die leichte Schulter!

Durch die Debugdaten auf der Immosky-Seite war der Weg zur SQL-Injection besonders einfach zu entdecken. Bei besser präparierten Anbietern hilft qualifiziertes Raten: Welche Parameter könnten in eine Query Eingang finden? Dabei unterstützen Fehlermeldungen, die Interna offenlegen. Betreiber wie Immosky sollten sich vor Augen führen, dass echte, invasiv geführte SQL-Angriffe eine Datenbank völlig ruinieren können. Abhilfe bringt ein ordentliches Escaping der Webseiten-Parameter. Webprogrammierer dazu zu motivieren ist das Ziel dieses Artikels.

Für das eigene System bieten Multiinjector [6] und andere Tools automatische Brute-Force-SQL-Injections an. Wer einen Test mit diesen Tools übersteht, dürfte gegen einen Großteil der Standardangriffe gewappnet sein – hundertprozentig sicher ist das aber natürlich nicht.

Im Zuge der Recherchen zu diesem Beitrag hat das Linux-Magazin den Betreiber des Portals kontaktiert. Immosky reagierte darauf bislang nicht. Kurz vor Drucklegung des Hefts waren allerdings – Zufall oder nicht – die Debugausgaben beim Abmelden des Newsletters verschwunden. Die Redaktion wird dem Anbieter eine Woche vor Veröffentlichung den Artikel zu Verfügung stellen. (jk)

Infos

  1. Immosky: http://www.immosky.de
  2. Firebug: https://addons.mozilla.org/de/firefox/addon/6683/
  3. Tobias Eggendorfer, “Web-Sicherheitslücken am Beispiel eines Onlineshops”, Linux-Magazin 12/10, S. 100
  4. SQL Injection Cheat Sheet I: http://ferruh.mavituna.com/sql-injection-cheatsheet-oku
  5. SQL Injection Cheat Sheet II: http://michaeldaw.org/sql-injection-cheat-sheet#mysql
  6. Multiinjector: http://code.google.com/p/multinjector/

Der Autor

Tobias Eggendorfer ist freiberuflicher IT-Berater und Professor für angewandte Informatik und IT-Forensik http://www.eggendorfer.info. Bei Experimenten zu Artikeln staunt er immer wieder, wie nachlässig Unternehmen mit Sicherheitslücken umgehen. Die meisten ignorieren nämlich seine Hinweise auf Schwachstellen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 3 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben