Articles

Leren van XSS met Google’s XSS Game

Stap voor stap instructie over hoe Google’s XSS Game op te lossen

Foto door Markus Spiske temporausch.com from Pexels

XSS aka Cross Site Scripting is een van de gevaarlijkste kwetsbaarheden aan de clientzijde en een van de meest populaire methoden om bugs op te sporen.

Google XSS Game is een trainingsplatform van Google om XSS te oefenen. Het bestaat uit 6 levels en in elk level moet je een JavaScript alert uitvoeren om door te gaan naar het volgende level. In elk level krijg je verschillende problemen en moet je de alert uitvoeren met verschillende technieken in elk level. Dit zal je helpen om de verschillende methoden te begrijpen die kunnen worden gebruikt om XSS in een webpagina uit te voeren.

Dus laten we beginnen.

Navigeer naar https://xss-game.appspot.com. Hier is de Google XSS Game beschikbaar.

U ziet een pagina als deze

Je moet de xss payload in de virtuele browser injecteren. U kunt de broncode bekijken door op de “toggle” link te klikken. Als het niet lukt om te injecteren, kunt u de hints krijgen door op de “show” link te klikken.

Tijdens het bekijken van de broncode, is het een python script en de 2 interessante delen in de functie
def get(self) zijn

self.response.headers.add_header("X-XSS-Protection", "0")

en

query = self.request.get('query', '')
message = "Sorry, no results were found for <b>" + query + "</b>."
message += " <a href='?'>Try again</a>."

Het eerste deel schakelt de chrome XSS auditor uit en stelt ons in staat om de XSS payload in de browser te injecteren.

Het tweede deel laat zien dat de waarde van url-param query direct aan de body wordt toegevoegd. Daar moeten we misbruik van maken.

Dit is een eenvoudige en je kunt proberen een van de volgende (en er zijn er nog meer) in het zoekvak in te voeren en te zoeken

<a href="javascript:alert()">Link</a>

<img src=X onerror="alert()">

<script>alert()</script>

Enzovoort. Als je de eerste hebt gebruikt, moet je op de link klikken om de waarschuwing uit te voeren.

Geweldig!!! Je hebt niveau 1 succesvol afgerond. Nu zie je een knop om door te gaan naar het volgende level.

Tweede taak : Persistentie is de sleutel

In deze taak moet je een waarschuwing uitvoeren door een post toe te voegen. In dit spel is het DOM XSS, maar als je het test op echte chat/commentaar applicaties, zal het een opgeslagen XSS zijn.

Ok laten we eens kijken naar de bron en het vorige bericht ook.

Bij het inspecteren van de bron, kun je zien dat het standaard bericht verschillende soorten html tags gebruikt om het te stijlen. Dat is onze sleutel.

Kijk naar de bron om het te bevestigen. Dit is hoe ons bericht wordt weergegeven

U kunt zien dat het bericht niet door filters gaat. Dus we kunnen elke methode gebruiken die hierboven is genoemd.

<a href="javascript:alert()">Link</a>

<img src=X onerror="alert()">

Enzovoort.

Congrats. Je hebt niveau 2 gehaald. Ga nu door naar het volgende niveau.

Taak 3 : Dat zinkende gevoel

Dit is heel wat anders dan de 2 die we al hebben voltooid. Hier moeten we leren over window.location.hash. Het is het deel na het # symbool en wordt gebruikt voor in-page navigatie. Het is een browser-functie en het werkt zelfs zonder JavaScript.

Laten we de broncode voor deze inspecteren.

Het interessante deel in de code is

var html = "Image " + parseInt(num) + "<br>";
html += "<img src='https://medium.com/static/level3/cloud" + num + ".jpg' />";

num bevat de waarde van window.location.hash en wordt op 2 plaatsen gebruikt. Op de eerste plaats wordt het gebruikt in de parseInt functie, zodat onze payload daar niet zal werken. Maar in de volgende regel, wordt de ruwe data gebruikt. Dat is waar we onze payload gaan injecteren.

Dus we moeten een enkele quote ' daar sluiten en we moeten onze payload injecteren.

U kunt elke payload proberen in ' ' na #

Probeer een van de onderstaande te plaatsen na # en bezoek de url.

1' onerror='alert()

1'><img src=X onerror="alert()">'

1'><script>alert()</script>'

1'><a href="javascript:alert()">Link</a>'
En ga zo maar door.

Geweldig. Nu kunnen we door naar het volgende niveau.

Taak 4 : Context Matters

We hebben een ruimte om de duur van de timer in te voeren. Daar gaan we misbruik van maken.

Laten we de broncode eens bekijken.

In timer.html zien we deze regel

<img src="https://medium.com/static/loading.gif" onload="startTimer('{{ timer }}');" />

We moeten misbruik maken van de expressie {{ timer }} Maar die is geplaatst binnen een functie startTimer(''); die een event handler is voor onload event. Het belangrijkste punt om op te merken is dat het attribuut event handler in HTML meerdere callback functies accepteert.

Dus moeten we de functie sluiten en onze waarschuwing daar uitvoeren. Merk op dat de waarde niet door een parseInt functie is gehaald, maar dat de ruwe gegevens worden gebruikt. Dus we kunnen de functie sluiten door een '); toe te voegen en dan onze alert injecteren. Omdat het als inline wordt gebruikt, kunnen we alert(); daar niet injecteren, omdat het de dingen zal breken. Het statement wordt onload="startTimer('3'); alert();')" en dat werkt niet.

Dus moeten we een patroon toevoegen dat het patroon ononderbroken houdt.
Voeg alert(' toe en het is genoeg.

Dus onze payload wordt

3');alert('

Als we op de start timer knop klikken, wordt de waarschuwing uitgevoerd en zijn we klaar met dit level.

Doorgaan naar volgende taak.

Taak 5 : Protocol breken

Op de startpagina hebben we geen manier om iets te injecteren. Het enige wat we hebben is een link. Laten we daar dus op klikken.

Hier zien we 2 plaatsen waar we onze payload kunnen injecteren. een op de url zelf en een andere op het invoerveld. Het invoerveld is een plaats om e-mail in te voeren en hopen dat het niet ergens anders wordt weerspiegeld. Dus laten we naar de eerste gaan. Op de url.

Inspecteer de broncode van de huidige pag, dat is signup.html en we zien de regel

Goede plek om een payload te injecteren. Onze payload zal worden ingesteld als de waarde van href attribuut in een a tag. Als we in staat zijn om javascript:alert() toe te voegen kunnen we onze payload uitvoeren. Laten we nu eens kijken wat de waarde is van next. We kunnen er geen vinden op de pagina. Waar moeten we dat zoeken?

Python code to the rescue. Controleer level.py en we zullen zien

if "signup" in self.request.path:
self.render_template('signup.html',
{'next': self.request.get('next')})

Dus de waarde van next in de url zal worden gebruikt.

Wijzig de waarde van next in de url van confirm naar javascript:alert() en de uiteindelijke url ziet er als volgt uit

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 en in de body van de functie ziet u de volgende code.

var scriptEl = document.createElement('script');

Dus we kunnen externe js-bestanden laden, maar niet van een http of https url.

Hierna proberen we de data urls.

Data urls zijn in de vorm data:{type},content

Verander dus de waarde na # naar

data:application/javascript,alert()

of naar

data:text/plain,alert() en we kunnen de alert uitvoeren.

Hier is een video van het oplossen van het spel.