Nur ein Klick ... Drei erstaunliche Schwachstellen vieler Web-Anwendungen

Ordnungsmerkmale

erschienen in: <kes> 2005#6, Seite 16

Rubrik: Bedrohung

Schlagwort: Sicherheit von Web-Anwendungen

Zusammenfassung: Session Riding, Website Spoofing und Session Lockout sind nicht nur schicke neue Buzzwords der Security-Szene, sondern handfeste Schwachstellen in Web-Anwendungen mit einem hohen Verbreitungsgrad. Dieser Beitrag liefert Einblicke und Ansätze für Gegenmaßnahmen.

Autor: Von Thomas Schreiber, München

Gehört eine von Ihnen genutzte oder sogar verantwortete Web-Anwendung auch zur Gruppe derjenigen, die eine oder mehrere gravierende Sicherheitslücken aufweisen? Die Wahrscheinlichkeit dafür ist hoch! Denn nach wie vor ist die Sicherheit etlicher Web-Anwendungen auf einem Niveau, das man getrost als schlecht bezeichnen kann. Aus der Vielzahl von Schwachstellen haben wir für diesen Beitrag drei zur Verdeutlichung der Problematik ausgewählt. Bevor wir uns zwei kaum bekannten Problemen (nebst möglichen Gegenmaßnahmen) zuwenden, soll mit Cross-Site-Scripting die vermutlich verbreitetste und gleichzeitig meistunterschätzte Sicherheitslücke betrachtet werden.

Achtung, Fälschung!

Phishing ist "in" – doch selbst wer auf eine gut gemachte E-Mail reinfällt, sollte doch bei genauem Hingucken und SSL-geschützter Übertragung feststellen, ob er mit einem legitimen Server verbunden ist oder nicht?! Leider genügt das allein aber nicht... Beispielsweise erfüllt die in Abbildung 1 dargestellte Webseite einer südamerikanischen Bank alle Echtheitskriterien:

[Screenshot: Zertifikatsanzeige des Internet Explorer] [Screenshot: SSL-geschützt übertragene Seite im Internet Explorer]
Abbildung 1: Original oder Fälschung? Selbst bei SSL-Übertragungen, von einem legitimen Server, der durch ein authentisches Zertifikat einer vertrauenswürdigen Stelle beglaubigt wird, ist Vorsicht geboten! Im Beispiel einer südamerikanischen Bank wurde per Cross-Site-Scripting HTML-Code "dazugeschummelt".

Natürlich ist die abgebildete Seite mit dem plumpen Fälschungshinweis tatsächlich nicht so von der Bank gewollt und veröffentlicht worden. Die Erklärung ist eine Cross-Site-Scripting-Schwachstelle auf dem Bank-Server, die diese Art der Fälschung – und vieles mehr – ermöglicht, auf erschreckend einfache Weise. Am Rande sei hier aber noch bemerkt: Obwohl im konkreten Beispiel eine ausländische Bank gewählt wurde, gibt es auch etliche Beispiele auf namhaften deutschen Websites, darunter auch Banken, wo genau dasselbe möglich ist.

Cross-Site Scripting (XSS)

Die Möglichkeit zum Cross-Site Scripting (XSS) besteht, wenn eine Web-Anwendung Eingaben (zumeist des Nutzers) in ihre (Antwort-)Webseiten einbaut, ohne zu prüfen, ob es sich hierbei um HTML- oder Script-Code handelt. Der wohl häufigste Fall ist die ungeprüfte Wiedergabe in einer direkt auf die Eingabe folgenden Antwortseite. Typisches Beispiel: Die Antwort auf eine Suchanfrage nach "München" (Benutzereingabe) lautet:

Die Suche nach 'München' hat leider keine Treffer geliefert.

Die Benutzereingabe, hier "München", wird in der Antwortseite einfach wiederholt. Ein simpler Test zeigt, ob eine XSS-Schwachstelle vorliegt: Wenn die Eingabe von "Münch<i>en" zum folgenden Ergebnis führt, führt die Website nicht die notwendigen Sicherungsmaßnahmen durch:

Die Suche nach 'München' hat leider keine Treffer geliefert.

Im Beispiel enthält die Antwortseite das eingegebene "<i>" nicht kodiert als Nutztext, sondern in buchstäblicher Wiederholung, die der Browser als HTML-Code zum Wechsel auf Kursivschrift interpretiert. Ein Blick in den Quellcode bestätigt das:

Die Suche nach 'Münch<i>en' hat leider keine Treffer geliefert.

Richtig und wichtig wäre es gewesen, dass die Web-Anwendung vor der Aufnahme in die Antwortseite die Zeichen "<" und ">" in diejenigen Sequenzen umwandelt, die den Browser anweisen, "größer als" und "kleiner als" darzustellen statt die Zeichen als Code zu interpretieren (hier die sog. HTML-Entities &lt; bzw. &gt;) – im geschilderten Fall also:

Quellcode:
Die Suche nach 'Münch&lt;i&gt;en' hat leider keine Treffer geliefert.
bewirkt im Browser:
Die Suche nach 'Münch<i>en' hat leider keine Treffer geliefert.

Diese Form von XSS wird verschiedentlich auch als HTML-Injection bezeichnet. Und in der Tat trifft dieser Begriff dieses Beispiel auch viel besser: HTML-Code wird von außen in eine fremde Seite injiziert. Natürlich legt es ein Angreifer kaum darauf an, einen Nutzer durch derart plumpe Änderung der Formatierung zu irritieren. Er könnte jedoch auch etwas aufwändigeren HTML-Code in das entsprechende XSS-anfällige Feld einfügen:

<div style="position:absolute; top:150px; width:1600px; left:25px; height:1250px; background-color:white"><h1>Diese Seite ist gefälscht!</div>

Das Ergebnis dieser HTML-Injection zeigt bereits Abbildung 1: Dieser HTML-Code überdeckt den "störenden" Originaltext der Seite mit einer weißen Fläche und druckt darauf, was immer man dem Aufruf mitgibt – im Zweifel bis hin zur perfekt gefälschten Login-Seite, die die Zugangsdaten des Benutzers abfischt und an den Server des Angreifers überträgt. Eine weitere Möglichkeit wäre die Übermittlung von Javascript-Code, der somit im Kontext der besuchten Website ausgeführt wird und beispielsweise das Auslesen der Session-ID und das nachfolgende Eindringen in den Benutzer-Account zur Folge haben kann (daher auch der Name Cross-Site-Scripting).

Transport zum Benutzer

Bisher haben wir alle Eingaben im eigenen Browser vorgenommen, es bleibt noch zu erklären, wie hier der angegriffene Dritte ins Spiel kommt, wie also der manipulierte Code in den Browser des Benutzers gelangt. Der Schlüssel dazu ist in der Regel ein Link, der, ausgelöst durch den Klick des Anwenders, die Anwendung mit der XSS-Lücke aufruft und den schädlichen Code über den ungesicherten Parameter übergibt.

Die einfachste Möglichkeit, einen solchen Link an eine Vielzahl möglicher Opfer zu übermitteln, ist der Versand in einer HTML-Mail – versteckt hinter einem harmlosen oder gezielt irreführenden Text. Dann genügt ein Klick und die verfälschte Seite vom denoch "authentischen" Server startet im Browser des Opfers.

Haftungsfragen

Interessant ist in diesem Zusammenhang auch die Haftungsfrage: Lässt sich der Benutzer durch die verbreitete plumpe Art des Phishings zur Eingabe von Kennung und Passwort auf der falschen Site verleiten, so ist er rechtlich "selbst Schuld". Kommt die Täuschung aber mithilfe einer Schwachstelle in der Web-Anwendung des Anbieters zustande, so ist sofort das Unternehmen in der Haftung.

Wer meint, Möglichkeiten für XSS seien selten anzutreffen, der irrt übrigens – das Gegenteil ist der Fall: Auf fast jeder Website findet sich irgendwo ein Ansatz zum XSS. Ein Grund dafür ist sicherlich, dass das Schadenspotenzial weithin unterschätzt wird und entsprechende Programmierfehler nach wie vor als Kavaliersdelikt durchgehen. Ein weiterer Grund: Eine einzelne entdeckte XSS-Schwachstelle ist zwar in der Regel leicht zu beheben – eine ganze Website nachhaltig XSS-frei zu bekommen, jedoch sehr schwer.

Session Lockout

Mit der (Ver-)Fälschung von Webseiten sind die Bedrohungen durch XSS noch lange nicht erschöpft. Wie es aussieht, wenn Javascript ins Spiel kommt, soll hier an einer ebenfalls häufig anzutreffenden, nach Wissen des Autors aber bisher noch nicht beschriebenen Denial-of-Service-Attacke illustriert werden. Ein Angreifer kann damit verhindern, dass ein Benutzer sich in seine Web-Anwendung einloggen kann.

Um die Funktionsweise des Angriffs zu verstehen, ist zunächst ein Blick auf folgenden Aspekt des Session-Handlings erforderlich: Eine typische Web-Anwendung mit Login setzt während des Login-Prozesses ein Session-ID-Cookie im Browser des Benutzers. Hat der Benutzer sich korrekt angemeldet, so verwendet die Anwendung für alle folgenden Aufrufe nur noch die Session-ID, um den Benutzer zu identifizieren. Wenn der Browser der Anwendung eine nicht existierende Session-ID sendet, so kann diese den Zugriffsversuch keiner bestehenden Sitzung zuordnen und geht in der Regel davon aus, dass hier ein Benutzer anfragt, der sich vor langer Zeit einmal eingeloggt hat und dessen Session-ID nun nicht mehr gültig ist. Sie löscht oder überschreibt das alte Session-ID-Cookie im Browser und fordert den Benutzer zur erneuten Anmeldung auf, verzweigt also zur Login-Seite – die Altlast ist damit bereinigt, ohne dass der Benutzer behindert worden wäre.

Wenn sich das Cookie jedoch nicht löschen oder überschreiben lässt und somit immer wieder an die Anwendung geschickt wird, dann ist der Benutzer in dieser Ablehnungsschleife gefangen: Die Anwendung verzweigt immer wieder zur Login-Seite, solange sie keine gültige Session-ID übermittelt bekommt.

Ein Angreifer kann genau diese Situation in vielen Fällen geschickt per XSS herbeiführen: Das Vertrackte für den, der einen solchen Angriff verhindern will, ist dabei, dass sich die XSS-Schwachstelle nicht notwendigerweise in der Anwendung selbst und nicht einmal auf dem Host, auf dem sie läuft, befinden muss. Es genügt, wenn die Schwachstelle auf einem beliebigen Host innerhalb derselben Domain vorliegt; zum Beispiel auch auf einem längst vergessenen Testsystem.

Immer diese Cookies (1)

Für die Beschreibung des Angriffs gehen wir davon aus, dass die Anwendung A über den Link https://b2b-portal.example.com/AnwA erreichbar ist und für das Session-Management ein Cookie namens JSESSIONID benutzt. Die auszunutzende XSS-Schwachstelle befindet sich hingegen auf dem Host test.example.com, genauer in einer Suchfunktion unter http://test.example.com/testscript?Suche=XSS.

Der Angreifer schickt zur Ausnutzung der XSS-Schwachstelle folgenden Link in einer E-Mail an den Benutzer:

http://test.example.com/testscript?Suche=<script>document.cookie="JSESSIONID=111; domain=example.com; path=/; expires=Saturday, 31-Dec-09 23:59:59 GMT;"</script>

Klickt der Benutzer auf den Link, so wird in seinem Browser ein Cookie namens JSESSIONID für alle Hosts und Anwendungen in der Domain example.com gesetzt, das bis Ende 2009 gültig bleibt, sofern es nicht explizit gelöscht wird (sog. Domain-Cookie). Die Anwendung selbst setzt und löscht hingegen ein Host-Cookie, dessen Gültigkeit auf einen bestimmten Host eingeschränkt ist, hier www.example.com.

Entscheidend für den Angriff ist nun, dass der Browser für www.example.com somit zwei verschiedene Cookies vorliegen hat (Host- und Domain-Cookie), die denselben Namen JSESSIONID tragen. Wenn die Anwendung das Cookie manipuliert oder löscht, dann operiert sie immer auf dem Host-Cookie, die vom Angreifer gesetzte Session-ID im Domain-Cookie bleibt dabei unangetastet. Da beide JSESSIONID-Cookies von ihrer Spezifikation her die entsprechenden Eigenschaften besitzen, schickt der Browser mit jedem Zugriff auf die Anwendung auch beide Cookies hintereinander im HTTP-Header:

Cookie: JSESSIONID=111;JSESSIONID=<Session-ID>

Wie geht nun die Anwendung mit einer solchen Situation um, für welches Cookie entscheidet sie sich? Was die Servlet-API betrifft, so kümmert sie sich nicht weiter darum, dass mehrere gleichnamige Cookies im Request enthalten sind. Sie nimmt einfach das erste – und damit im beschriebenen Fall die ungültige Session-ID. Wenn sie JSESSIONID (nach dem erneuten Login) aber mit einer frischen Session-ID versorgen will, so adressiert sie wieder das Host-Cookie. Da die Reihenfolge, in der der Browser die Cookies sendet, sich nicht ändert, geht das Spiel endlos weiter.

Nach Beobachtungen des Autors senden sowohl Internet Explorer als auch Mozilla/Firefox die Cookies zumeist in der Reihenfolge, in der sie einmal gesetzt worden sind. Warum es zu dieser Regel auch Ausnahmen gibt, ließ sich nicht ergründen.

In einer üblichen Anwendung mit Session-ID-Cookies ist jeder Benutzer dieser Anwendung in der gezeigten Weise angreifbar, sofern auf einem beliebigen Host in derselben Domain eine XSS-Schwachstelle existiert (oder auch eine andersartige geeignete Sicherheitslücke). Das betrifft gegenwärtig das Online-Banking vieler Banken genauso wie auch die kritische Anwendung einer Ausschreibungsplattform, bei der es auf gesicherte Verfügbarkeit bis zur letzten Minute vor Annahmeschluss ankommt.

Aussperrung verhindern

Wie können Entwickler einer Web-Anwendung dieses Problem umgehen? Die enttäuschende Antwort lautet: Es gibt keine einfache und saubere Lösung. Dieses Problem resultiert aus einem tief liegenden Designfehler der Cookies. Je nach Anwendungsfall kann es helfen:

Session Riding

Session Riding – auch als Cross-Site Request Forgery (CSRF) bezeichnet – ist eine erstaunlich einfache, aber erst kürzlich in ihrer ganzen Tragweite entdeckte Möglichkeit des Missbrauchs einer bestehenden Session [1], die in einer Vielzahl von Web-Anwendungen und auch in so sensitiven Tools wie Browsergestützten Administrationskonsolen anzutreffen ist. Bei diesem Angriff wird ein von außen zugeführter Link im Kontext einer bestehenden Session ausgeführt und wirkt so auf den Daten des betroffenen Benutzer. Potenziell gefährdet ist jede Web-Anwendung, die Cookies als Träger der Session-ID benutzt und keine besonderen Vorkehrungen dagegen getroffen hat.

So weist zum Beispiel Webmin ([externer Link] www.webmin.com), eine weit verbreitete Software zur Konfiguration von Unixsystemen, diese Schwachstelle auf und stellt damit ein breites Einfallstor in die Unternehmens-IT dar. Als Beispiel soll hier die Webmin-Funktion zur Verwaltung der Datei /etc/hosts dienen: Nach erfolgtem Login (somit Vergabe der Session-ID) kann ein Administrator per Mausklick auf "Add a new host address" via Web-Formular Ergänzungen an die Host-Datei anfügen (vgl. Abb. 2). Dabei schickt der Browser den folgenden HTTP-GET-Request (im Beispiel zu einem securenet-Server):

https://roma.securenet.de:10000/net/save_host.cgi?new=1&address=82.135.17.210&hosts=b2bportal.example.com

[Screenshot]
[Screenshot] Abbildung 2: Viele Web-Applikationen transportieren "Befehle" in URLs (GET-Methode in HTML-Formularen) und sind so leichte Beute für Session Riding (im Bild: Eintrag in Host-Datei mit Webmin).

Immer diese Cookies (2)

Welcher Benutzer zugreift, erfährt Webmin wiederum über das Session-ID-Cookie (namens "sid"). Zur Verfolgung der Session benutzt Webmin dasselbe Verfahren wie unzählige andere Web-Anwendungen auch: die "form-based Authentication" mit Cookies als Träger der Session-Information. Einmal gesetzt, schickt der Browser dieses Cookie bei jeder Anfrage an den Server automatisch mit, ohne dass Benutzer oder Web-Anwendung etwas dazu beitragen müssten.

Würde der Administrator, statt das Formular zu verwenden, den obigen Link in die Adresszeile des Browser eintippen und abschicken, so würde Webmin den Eintrag in /etc/hosts in gleicher Weise ergänzen – das sid-Cookie schickt der Browser auch in diesem Fall automatisch mit. Dasselbe geschieht auch, wenn der Administrator – ohne sich bei Webmin abzumelden – in demselben oder einem anderen Browserfenster auf einer beliebigen Webseite einen entsprechenden Link betätigt, vielleicht durch eine "interessante" E-Mail zu solchem Tun angeregt.

Daraus ergibt sich ein durchaus reales Angriffsszenario: Angreifer X weiß, dass Admin A im Unternehmen U Hosts und Netzwerke mit Webmin administriert und er kennt den für ihn interessanten ZielHost. Um dort eine Modifikation der Namensauflösung vorzunehmen – etwa, um den Zugriff auf den regelmäßig angesprochenen Server für Software-Updates umzulenken –, muss es X lediglich gelingen, im Browser von A den besagten Link zur Ausführung zu bringen.

Die wohl unauffälligste Art, dies zu erreichen, benutzt das IMG-Tag in einer HTML-E-Mail, die das folgende "Bild" nachlädt:

<img src="https://roma.securenet.de:10000/net/save_host.cgi?new=1&address=82.135.17.210&hosts=b2bportal.example.com">

Sofern HTML-Mails über denselben Browser dargestellt werden, der auch zum Surfen dient (der Regelfall also), wird bereits in dem Moment, in dem der Mail-Client diese Nachricht auch nur in der Vorschau wiedergibt, der Request zum Laden des Bildes und somit die Modifikation an der Host-Datei ausgelöst. Einzige Bedingung: ein gültiges Session-ID-Cookie, der Administrator muss also im Moment der Ausführung in Webmin eingeloggt sein.

Sichere Einstellungen von Browser und E-Mail-Client können die hier beschriebene "eleganteste" Form zwar unterbinden, geeignete Modifikationen des Angriffs würden aber in vielen Fällen trotzdem zum Erfolg führen. Dass der Browser im Mail-Client hier kein Bild darstellen kann, weil unerwartete Zeichen kommen, hilft nichts – im Gegenteil: Die Antwortseite bleibt auf diese Weise für den Benutzer unsichtbar.

Bei Web-Anwendungen im Internet sind die Möglichkeiten für einen Angriff per Session Riding noch weitaus größer als im hier beschriebenen Beispiel. Untersuchungen des Autors zufolge stellt Session Riding neben XSS die verbreitetste Schwachstelle und somit die größte Bedrohung im Bereich der Web Application Security dar.

Huckepack-Sessions verhindern

Die Lösung für dieses Problem lässt sich leicht formulieren, ist in vielen Fällen aber nicht oder nachträglich nur mit großem Aufwand umsetzbar. Sie lautet: Verzichte auf Cookies zum Transport der Session-ID, verwende stattdessen URL-Rewriting oder Hidden-Fields. Sind Session-ID-Cookies unverzichtbar, so ist in jede Anfrage ein "geheimer" oder zufälliger Parameter aufzunehmen, der beim Login vergeben und von der Anwendung bei jedem Zugriff auf Gültigkeit überprüft wird. Für einen erfolgreichen Angriff wäre dann auch dieser Parameter notwendig. Da Programmierschnittstellen, über die professionelle Web-Anwendungen das Session-Handling abwickeln, ein solches Vorgehen derzeit nicht transparent unterstützen, wäre allerdings auch das mit erheblichem Zusatzaufwand verbunden. Dafür bekäme die Anwendung aber gleichzeitig einen sehr wirksamen Schutz vor einer Vielzahl weiterer Bedrohungen, unter anderem Session-Hijacking oder Session-Fixation.

Fazit

Die gezeigten drei prägnanten Beispiele sind letztlich nur eine kleine Auswahl aus dem Spektrum der Möglichkeiten von Angriffen auf Web-Anwendungen. Gemessen daran ist es erstaunlich, wie wenig von vielen Unternehmen bisher unternommen wird, um derartige Probleme in den Griff zu bekommen. Vielleicht ist die Erklärung darin zu suchen, dass Web-Anwendungen gegenwärtig noch nicht so sehr im Fokus der Hacker stehen. Viren und Trojaner sind momentan wohl noch einträglichere Angriffsformen, die es zu verhindern gilt und die die Aufmerksamkeit der Verantwortlichen bindet. Doch es ist davon auszugehen, dass sich diese Situation ändern wird, vielleicht sogar mit einem Schlag – auch massives Phishing kam fast über Nacht.

Wenn die Abwicklung von – auch sensitiven – Geschäftsprozessen im Web so verbreitet ist wie heute, dann ist auch die Verlockung für einen Wettbewerber groß, sich über Schwachstellen in Web-Anwendungen einen Vorteil zu verschaffen. So wird es künftig immer seltener "irgendein Hacker" sein, der die Bedrohung darstellt, als vielmehr handfeste wirtschaftliche Interessen, die in Vorteilsnahme bis hin zu Betrug und Wirtschaftsspionage münden werden.

Thomas Schreiber (ts@securenet.de) ist Berater für Web Application Security und Geschäftsführer der SecureNet GmbH in München.

Literatur

[1]
Thomas Schreiber, Session Riding – A Widespread Vulnerability in Today's Web Applications, [externer Link] www.securenet.de/papers/Session_Riding.pdf