Cross-Site Scripting im Überblick, Teil 5: Resident XSS
Diesmal geht es um eine Art von XSS-Angriffen, die auf eine herkömmliche XSS-Schwachstelle als Einfallstor angewiesen ist. Denn beim sogenannten Resident XSS wird der Schadcode über eine der bekannten XSS-Schwachstellen (also reflektiertes, peristentes oder DOM-basiertes XSS) eingeschleust und danach im Browser verankert. Es handelt sich also eigentlich weniger um einen neue Art von XSS als um einen weiteren Angriff über XSS.
Resident XSS ermöglicht Rootkit im Webclient
Der Begriff "Resident XSS" wurde auf dem 28C3 von Artur Janc geprägt. Das Thema seines Vortrags: "Rootkits in your Web application". Und das Resident XSS ist dabei nur ein Mittel zur Erreichung dieses Ziels.
Zur Erinnerung eine kurze Beschreibung, was ein
Rootkit
überhaupt ist. Rootkits stammen ursprünglich aus dem
Unix-Umfeld. Ihre ursprüngliche Aufgabe bestand darin, die Aktionen
eines erfolgreichen Angreifers, der sich Administrator-Rechte (unter Unix
eben die des Benutzers root
) beschaffen konnte, vor einer
Entdeckung zu verbergen. Allgemein dient ein Rootkit einem Angreifer also
dazu, nach einer erfolgreichen Kompromittierung die Kontrolle über den
angegriffenen Rechner zu erhalten und möglichst lange unentdeckt zu
bleiben.
Das funktioniert natürlich sinngemäß auch im Rahmen einer Webanwendung - und zwar sowohl auf dem Server als auch auf dem Client. Und hier setzt Artur Jancs Angriff an: Er greift nicht die Webanwendung auf dem Server selbst, sondern deren Client im Webbrowser der Benutzer an.
Aus herkömmlichen XSS wird Resident XSS...
Dabei geht er davon aus, dass der Angreifer es schafft, einem Benutzer JavaScript-Schadcode unter zu schieben. Zum Beispiel, wenn ein Benutzer eine mittels persistenten XSS präparierte Webseite aufruft, die den Schadcode enthält. Damit aus diesem normalen XSS-Angriff, dessen Schadcode nur läuft, so lange die betroffene Seite im Browser offen ist, das deutlich langlebigere Resident XSS wird, wird der eingeschleuste JavaScript-Schadcode im Kontext der angegriffenen Webanwendung im Local Storage oder der SQL-Datenbank des Webbrowsers gespeichert und zusätzlich in einem versteckten iframe oder Tab aktiv gehalten.
Um jederzeit auf den Schadcode zugreifen zu können, benötigt der Angreifer eine Backdoor. Statt auf dem Webserver wird die ebenfalls auf dem Client geöffnet, indem entsprechender Schadcode Bestandteil des eingeschleusten Codes des Resident XSS ist..
... und daraus das Rootkit für den Webclient, ...
Über das Resident XSS kann dann das Rootkit für die Webanwendung realisiert werden: Der Schadcode hat die vollständige Kontrolle über die Kommunikation zwischen Benutzer und angegriffener Webanwendung und kann Aktionen im Namen des Benutzers ausführen und Antworten der Webanwendung manipulieren.
Manipulationen durch den Schadcode auf dem Client, zum Beispiel eine geänderte Ausgabe der Webanwendung, werden von der Webanwendung selbst nicht bemerkt, es gibt keinerlei Hinweise auf die Manipulationen in den Logfiles von Webserver oder -anwendung.
Und alle Manipulationen des Schadcodes an den an die Webanwendung geschickten Request sowie vom Schadcode selbst geschickte Requests werden von der Webanwendung auf dem Server dem eingeloggten Benutzer zugeordnet, sie erregen also erst Recht keinen Verdacht. Die fallen eher dem Benutzer auf, da er ja weiß, was er getan hat und was nicht. Was vom Rootkit aber wiederum verhindert werden kann, da das ja die Ausgaben der Webanwendung passend manipulieren kann.
"Man-in-the-Browser"-Schadcode für Angriffe auf das Onlinebanking hat entsprechende Taktiken schon vor einigen Jahren genutzt: Nachdem eine gefälschte Überweisung in die Weg geleitet wurde, wurden die Ausgabe im Browser so manipuliert, dass die Überweisung nirgends auftauchte. Wenn das Opfer dann irgendwann die nicht manipulierten Papier-Auszüge kontrollierte oder einen nicht manipulierten Browser benutzte und die gefälschte Überweisung entdeckte, waren die Cyberkriminellen meist längst mit ihrer Beute auf und davon.
... und das wird man nicht so einfach wieder los!
Aber kommen wir zurück zum Rootkit im Webclient: Selbst wenn die Webanwendung auf dem Server oder der Benutzer den Angriff erkennt, ist es gar nicht so einfach, den Schadcode wieder los zu werden:
Der Server scheitert dabei daran, dass er keine Kontrolle über den
Browser hat (was im Allgemeinen auch besser ist). Solange ein Tab oder ein
Fenster zur Domain der angegriffenen Webanwendung mit dem Schadcode offen
ist, kann der Schadcode die laufende Session manipulieren. Ein über
meta
-Tag oder Ajax ausgelöster Refresh der Seite kann vom
ihm aufgehoben werden, und die Webanwendung kann den Benutzer nicht einmal
vor dem laufenden Angriff warnen, da der Schadcode diese Warnung
unterdrücken oder manipulieren kann.
Und auch der Benutzer wird den laufenden Schadcode nicht so leicht los, wie man meinen möchte: Das Schließen des Tabs mit der Webanwendung ist nutzlos, wenn der Schadcode in weiteren Tabs oder versteckten iframes im Kontext der Webanwendung läuft. Auch das Schließen aller Browserfenster und das Beenden des Webbrowsers eliminieren den Schadcode nicht, wenn der sich zum Beispiel im Local Storage oder der SQL-Datenbank eingenistet hat. Löscht der Benutzer den Local Storage, bevor er den Browser neu startet, kann in noch geöffneten Tabs oder Fenstern laufender Schadcode sich sofort wieder im Local Storage einnisten.
Artur Janc hält folgendes Vorgehen für eine mögliche Lösung:
- Schließen aller Browserfenster bis auf eines.
- Schließen aller Tabs in diesem Fenster bis auf einen.
- In diesem verbleibenden Tab
about:blank
aufrufen. - Löschen aller von der Webanwendung auf dem Client gespeicherten Daten, also Cookies, Caches, Local Storage, SQL-Datenbank, Local Shared Objects des Flash Players...
- Neustart des Browsers.
Na, wer von Ihnen würde das machen? Wenn eine Webanwendung es verlangt? Vermutlich niemand, oder? Es gibt aber noch eine zweite Möglichkeit, den Resident XSS dem Garaus zu machen: Alternativ kann auch einfach das betroffene Browserprofil gelöscht werden. Aber das macht ja wohl erst recht niemand, oder?
Resident XSS und dessen Folgen will keiner haben!
Sie sehen also: Resident XSS wird man ziemlich schwierig wieder los. Da hilft nur eins: Passen Sie auf, dass sie sich sowas gar nicht erst einfangen. Aber das ist für Webentwickler recht einfach: Wenn ihre Webanwendung keine XSS-Schwachstellen hat, kann darüber auch kein Resident XSS eingeschleust werden. Und XSS-Schwachstellen sollte es ja generell nicht geben.
Oh. Äh... da gibt es jetzt nur ein klitzekleines Problem: Selbst wenn Ihre Webanwendung keine XSS-Schwachstelle enthält, kann sie zum Opfer eines XSS-Angriffs über eine "Universal XSS"-Schwachstelle wie die im Internet Explorer werden, die der Auslöser all dieser Artikel über XSS ist. Und dagegen gibt es im Grunde keinen 100%igen Schutz. Die Content Security Policy kann einen Teil der Angriffe abwehren, aber nicht alle.
Und als Benutzer ist es noch schwieriger, XSS-Angriffe zu verhindern. Die XSS-Filter der Browser und Erweiterungen wie NoScript schützen zwar vor vielen Angriffen, konzeptbedingt aber nicht vor allen. Der einzig wirklich zuverlässige Schutz ist das Ausschalten von JavaScript (und selbst dann sind noch Angriffe möglich, die nur auf HTML und CSS setzen). Aber wie viele Websites kennen Sie, die ohne JavaScript noch halbwegs benutzbar sind? Da bleiben nicht besonders viele übrig. Sie müssen sich also darauf verlassen, dass die Entwickler der Webanwendungen die sicher implementieren. Was sie schon aus reinem Eigennutz tun werden, denn sie wollen ja nicht, das ihre Webanwendung Opfer eines Angriffs wird. Was natürlich Fehler nicht ausschließt, und ebenso Angriffe über bisher unbekannte Angriffsvektoren. Ein gewisses Restrisiko bleibt immer. Das das gilt ja immer und überall, von daher: Kein Grund zur Panik.
In der nächsten Folge geht es um weitere über XSS mögliche Angriffe.
Übersicht über alle Artikel zum Thema
- Cross-Site Scripting im Überblick, Teil 1: Reflektiertes XSS
- Cross-Site Scripting im Überblick, Teil 2: Persistentes XSS
- Cross-Site Scripting im Überblick, Teil 3: Der MySpace-Wurm Samy
- Angriffe über Cross-Site Scripting: Der Sourcecode des MySpace-Wurms Samy
- Cross-Site Scripting im Überblick, Teil 4: DOM-basiertes XSS
- Cross-Site Scripting im Überblick, Teil 5: Resident XSS
- XSS-Angriffe, Teil 1: Informationen einschleusen
- XSS-Angriffe, Teil 2: Cookies und Tastendrücke ausspähen
- XSS-Angriffe, Teil 3: Zugangsdaten ausspähen
- XSS-Angriffe, Teil 4: Ein Blick in die History, und dann auf ins LAN!
- XSS-Angriffe, Teil 5: Ein Portscan (nicht nur) im LAN
- XSS-Angriffe, Teil 6: Ein verbesserter Portscanner
- XSS-Angriffe, Teil 7: Hindernisse beim JavaScript-Portscan beseitigen
- XSS-Angriffe, Teil 8: Ein Portscan mit WebSockets oder Cross-Origin Requests
- XSS-Angriffe, Teil 9: Der Router im Visier
- XSS-Angriffe, Teil 10: Weitere Angriffe auf den Router
- XSS-Angriffe, Teil 11: Unerwünschtes Firmware-Update für den Router
- XSS-Angriffe, Teil 12: Browser-basierte Botnets
- XSS-Angriffe, Teil 13: Fortgeschrittene Angriffe
- XSS-Angriffe, Teil 14: Das Browser Exploitation Framework BeEF
Trackbacks
Dipl.-Inform. Carsten Eilers am : Die IoT Top 10, #1: Unsichere Weboberflächen, Teil 5
Vorschau anzeigen
Dipl.-Inform. Carsten Eilers am : Drucksache: Windows Developer 2.17 - Websecurity 2016: Browser und Webclient
Vorschau anzeigen