XSS-Angriffe, Teil 4: Ein Blick in die History, und dann auf ins LAN!
Nach dem Einschleusen von Informationen in den Browser und dem Ausspähen von Cookies und Tastendrücken sowie Zugangsdaten ist der Browser im Grunde abgegrast. Was bleibt, ist das Ausspähen der History. Und danach geht es weiter ins lokale Netz! Und auch das aus dem Browser heraus, allein mit JavaScript!
Ausspähen der Browser-History
Die Kurzfassung dieses Angriffs kann mit "Guck nach, wie der Link aussieht" umschrieben werden: Über CSS kann festgelegt werden, wie besuchte und nicht besuchte Links dargestellt werden sollen. Über JavaScript kann der Style jedes DOM-Elements einer Seite abgefragt werden. Dies zusammen kann ausgenutzt werden, um die Browser-History auszuspähen. Das funktioniert nach folgendem Muster:
- Über JavaScript wird ein Link zu einem den Angreifer interessierenden URL erzeugt.
- Der Link wird mit unterschiedlichen Style-Attributen für
:link
und:visited
versehen. - Der Browser wählt den passenden Style automatisch aus.
- Über JavaScript wird der Style des erzeugten Links geprüft. Dadurch können bereits besuchte Links von noch nicht besuchten unterschieden werden.
Der Angreifer kann also nicht die gesamte Browser-History nach Belieben durchgehen, aber stattdessen gezielt nach bestimmten Links fragen. Der Browser antwortet auf jede dieser Fragen mit "kenne ich nicht" bzw. "da war ich schon". Dieser gezielten Suche sind allerdings Grenzen gesetzt: Enthält die URL einer Seite Informationen wie zum Beispiel eine Session-ID, die bei jedem Besuch unterschiedlich sind, muss der Angreifer exakt die Version erzeugen, die der Benutzer zuvor besucht hat, um zum richtigen Ergebnis zu kommen.
Dieses "History Sniffing" ist ein uraltes Problem, denn die besuchten Websites verraten sehr viel über einen Benutzer. 2007 wurde ein Verfahren patentiert, dass Webnutzer anhand der von ihnen zuvor besuchten Websites klassifiziert. 2010 haben viele Websites "History Sniffing" genutzt, um nach zu sehen, wo ihre Besucher vorher schon überall waren. Was natürlich nicht immer im Interesse der Benutzer ist, da die Websites diese Informationen meist nutzen, um ihr Angebot an die Besucher anzupassen. Weshalb die Browser-Entwickler der Auswertung der Styles immer mehr Hürden in den Weg gelegt haben.
Statt den Style von Links auszuwerten kann aber auch ein Cache-Timing-Angriff (Beschreibung des Konzepts als PDF) genutzt werden, um zwischen sich ganz oder teilweise schon im Cache befindenden (und daher bereits besuchten) Seiten und komplett neu geladenen Seiten zu unterscheiden.
Die Browser-Hersteller versuchen zwar immer wieder, entsprechende Angriffe zu verhindern, trotzdem gibt es immer mal wieder neue Möglichkeiten zum Ausspähen der History, siehe zum Beispiel auch meinen Artikel im PHP Magazin 6.2014 und das eBook "JavaScript Security - Sicherheit im Webbrowser".
Aber damit haben wir uns jetzt lange genug auf den Browser beschränkt. Es ist Zeit, ihn zumindest virtuell zu verlassen und mal nach zu sehen, ob es im lokalen Netz vielleicht interessantere Ziele gibt.
Der Aufbruch ins lokale Netz
Wer die Kontrolle über den Browser hat, befindet sich im lokalen Netz - und damit hinter der Firewall. Da wäre es doch ganz praktisch (jedenfalls für den Angreifer, fürs Opfer eher nicht), wenn er dort nach weiteren brauchbaren Zielen suchen könnte. Auch das ist möglich.
Werfen wir zuerst mal einen Blick auf das, was JavaScript kann:
- Es können HTTP-Verbindungen zu beliebigen Hosts aufgebaut
werden.
Zwar ist meist kein Zugriff auf das Ergebnis möglich, aber der Erfolg oder Misserfolg des Verbindungsversuchs kann erkannt werden. - Es können Timer verwendet und
- ausgelöste Events erkannt werden.
Und dabei sind die Fähigkeiten von HTML5 wie Cross-Origin-Requests und WebSockets noch gar nicht berücksichtig!
Aus diesen Bausteinen kann zum Beispiel ein ping-Befehl konstruiert werden.
Dazu wird ein Image-Objekt mit onLoad()
- und
onError()
-Events und einem Timer erzeugt. Beim Setzen des
src
-Attributs wird ein HTTP-GET-Request zum angegebenen Host
ausgelöst, gleichzeitig wird der Timer gestartet. Jetzt gibt es 3
Möglichkeiten:
- Der Host existiert, der angesprochene Port ist aber geschlossen oder
es ist keine HTTP-Verbindung möglich: Der
onError()
-Event wird ausgelöst. - Der Host existiert und ein Webserver ist erreichbar: Der
onLoad()
-Event wird ausgelöst. - Der Host existiert nicht: Der Timer-Event wird ausgelöst.
Wie man von diesem Ping zu einem regelrechten Portscan gelangt, wird in der nächsten Folge beschrieben.
Ü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