Leren van XSS met Google’s XSS Game
Stap voor stap instructie over hoe Google’s XSS Game op te lossen
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 functiedef 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.