XSS lernen mit Googles XSS-Spiel
Schrittweise Anleitung, wie man Googles XSS-Spiel löst
XSS aka Cross Site Scripting ist eine der gefährlichsten clientseitigen Schwachstellen und eine der beliebtesten Methoden zur Fehlersuche.
Google XSS Game ist eine Trainingsplattform von Google, um XSS zu üben. Es besteht aus 6 Levels und in jedem Level müssen Sie einen JavaScript-Alarm ausführen, um zum nächsten Level zu gelangen. In jedem Level werden Sie mit verschiedenen Problemen konfrontiert, und Sie müssen den Alarm mit verschiedenen Techniken in jedem Level ausführen. Dies wird Ihnen helfen, verschiedene Methoden zu verstehen, die zur Ausführung von XSS in einer Webseite verwendet werden können.
Legen wir also los.
Navigieren Sie zu https://xss-game.appspot.com. Hier ist das Google XSS-Spiel verfügbar.
Sie werden eine Seite wie diese sehen
Klicken Sie auf die Schaltfläche Let me at ‚em! um in das Spiel einzusteigen.
Erste Aufgabe: Hello world of XSS
Sie müssen den XSS-Payload in den virtuellen Browser injizieren. Sie können den Quellcode anzeigen, indem Sie auf den Link „toggle“ klicken. Wenn Sie nicht in der Lage sind, zu injizieren, können Sie die Hinweise erhalten, indem Sie auf den Link „show“ klicken.
Während Sie den Quellcode überprüfen, ist es ein Python-Skript und die 2 interessanten Teile in der Funktiondef get(self)
sind
self.response.headers.add_header("X-XSS-Protection", "0")
und
query = self.request.get('query', '')
message = "Sorry, no results were found for <b>" + query + "</b>."
message += " <a href='?'>Try again</a>."
Der erste Teil wird den Chrome XSS-Auditor ausschalten und uns erlauben, die XSS-Nutzlast in den Browser zu injizieren.
Der zweite Teil zeigt, dass der Wert des Url-Parameters query
direkt in den Body eingefügt wird. Das ist der Punkt, den wir ausnutzen müssen.
Dies ist ein einfacher und Sie können versuchen, eine der folgenden (und noch mehr gibt es) in das Suchfeld einzugeben und sie zu durchsuchen
<a href="javascript:alert()">Link</a>
<img src=X onerror="alert()">
<script>alert()</script>
Und so weiter. Wenn du die erste benutzt hast, musst du auf den Link klicken, um den Alarm auszuführen.
Gut!!! Du hast Level 1 erfolgreich abgeschlossen. Jetzt siehst du einen Button, um zum nächsten Level zu gelangen.
Zweite Aufgabe: Ausdauer ist der Schlüssel
In dieser Aufgabe musst du eine Meldung ausführen, indem du einen Beitrag hinzufügst. In diesem Spiel handelt es sich um DOM XSS, aber wenn man es in echten Chat-/Kommentaranwendungen testet, wird es ein gespeichertes XSS sein.
Schauen wir uns den Quelltext und die vorherige Nachricht an.
Bei der Untersuchung des Quelltextes kann man sehen, dass die Standardnachricht verschiedene Arten von HTML-Tags verwendet, um sie zu gestalten. Das ist unser Schlüssel.
Überprüfen Sie den Quelltext, um dies zu bestätigen. So wird unser Beitrag gerendert
Sie können sehen, dass der Beitrag keine Filter durchläuft. Wir können also jede der oben genannten Methoden verwenden.
<a href="javascript:alert()">Link</a>
<img src=X onerror="alert()">
Und so weiter.
Glückwunsch. Du hast Level 2 abgeschlossen. Jetzt gehst du zum nächsten Level.
Aufgabe 3: Das Gefühl des Versinkens
Dies ist ganz anders als die 2, die wir abgeschlossen haben. Hier müssen wir etwas über window.location.hash.
lernen. Es ist der Teil, der nach dem #
-Symbol kommt und für die seiteninterne Navigation verwendet wird. Es handelt sich um eine Browserfunktion, die auch ohne JavaScript funktioniert.
Schauen wir uns den Quellcode an.
Der interessante Teil des Codes ist
var html = "Image " + parseInt(num) + "<br>";
html += "<img src='https://medium.com/static/level3/cloud" + num + ".jpg' />";
num
, der den Wert von window.location.hash
enthält und an zwei Stellen verwendet wird. An der ersten Stelle wird er innerhalb der parseInt-Funktion verwendet, so dass unsere Nutzlast dort nicht funktionieren wird. Aber in der nächsten Zeile werden die Rohdaten verwendet. Dort werden wir unsere Nutzdaten einfügen.
So müssen wir dort ein einzelnes quot '
schließen und unsere Nutzdaten einfügen.
Sie können jede beliebige Nutzlast innerhalb von ' '
nach #
Versuchen Sie, eine der folgenden nach #
zu setzen und die URL zu besuchen.
1' onerror='alert()
1'><img src=X onerror="alert()">'
1'><script>alert()</script>'
1'><a href="javascript:alert()">Link</a>'
Und so weiter.
Gut. Jetzt können wir zur nächsten Stufe übergehen.
Aufgabe 4: Der Kontext zählt
Wir haben ein Feld, um die Dauer des Timers einzugeben. Das werden wir ausnutzen.
Schauen wir uns den Quellcode an.
In timer.html sehen wir diese Zeile
<img src="https://medium.com/static/loading.gif" onload="startTimer('{{ timer }}');" />
Wir müssen den Ausdruck {{ timer }}
ausnutzen, aber er befindet sich innerhalb einer Funktion startTimer('');
, die ein Event-Handler für das Ereignis onload
ist. Der wichtigste Punkt ist, dass das Event-Handler-Attribut in HTML mehrere Callback-Funktionen akzeptiert.
So müssen wir die Funktion schließen und unseren Alarm dort ausführen. Beachten Sie, dass der Wert nicht durch eine parseInt
-Funktion übergeben wurde, sondern die Rohdaten verwendet werden. Wir können also die Funktion durch Hinzufügen eines ');
schließen und dann unser alert
einfügen. Da die Funktion als Inline-Funktion verwendet wird, können wir alert();
dort nicht einfügen, da dies zu Problemen führen würde. Die Anweisung wird zu onload="startTimer('3'); alert();')"
und es wird nicht funktionieren.
So müssen wir ein Muster hinzufügen, das das Muster ungebrochen hält.
Fügen Sie alert('
hinzu und es ist genug.
So wird unsere Nutzlast sein
3');alert('
Klicken Sie auf die Schaltfläche „Start Timer“, um den Alarm auszuführen und wir haben dieses Level beendet.
Weiter zur nächsten Aufgabe.
Aufgabe 5 : Breaking Protocol
Auf der Startseite haben wir keine Möglichkeit, etwas einzuschleusen. Alles, was wir haben, ist ein Link. Klicken wir also darauf.
Hier sehen wir zwei Stellen, an denen wir unsere Nutzlast einschleusen können: eine auf der URL selbst und eine auf dem Eingabefeld. In das Eingabefeld kann man seine E-Mail eingeben und hoffen, dass sie nicht irgendwo anders wiedergegeben wird. Gehen wir also zur ersten Stelle. Auf der url.
Inspektieren Sie den Quellcode der aktuellen Seite, das ist signup.html und wir können die Zeile
<a href="{{ next }}">Next >></a>
Großartiger Ort, um eine Nutzlast zu injizieren. Unsere Nutzlast wird als Wert des Attributs href
in einem a
-Tag gesetzt. Wenn wir in der Lage sind, javascript:alert()
hinzuzufügen, können wir unseren Payload ausführen. Nun wollen wir sehen, was der Wert von next
ist. Wir können keinen auf der Seite finden. Wo können wir danach suchen?
Python-Code zur Rettung. Schauen wir uns level.py an, sehen wir
if "signup" in self.request.path:
self.render_template('signup.html',
{'next': self.request.get('next')})
So wird der Wert von next
in der Url verwendet.
Ändern Sie den Wert von next
in der URL von confirm
auf javascript:alert()
und die endgültige URL wird wie folgt aussehen
Now clicking on Next >> in the page will trigger our payload.
We now completed level 5. And 1 level remains.
Task 6 : Follow the 🐇
There is a path to a js file in the url.
Let’s inspect the source code. In page index.html, you can see a function includeGadget
und innerhalb des Funktionskörpers können Sie den folgenden Code sehen.
var scriptEl = document.createElement('script');
So können wir externe js-Dateien laden, aber nicht von einer http
oder https
URL.
Hier probieren wir die data
urls.
Daten urls sind in der Form data:{type},content
So ändern wir den Wert nach #
zu
data:application/javascript,alert()
oder zu
data:text/plain,alert()
und wir können die alert
ausführen.
Hier ist ein Video zum Lösen des Spiels.