Learning XSS with Google’s XSS Game
Lépésről lépésre útmutató a Google’s XSS Game megoldásához

XSS aka Cross Site Scripting az egyik legveszélyesebb kliensoldali sebezhetőség és az egyik legkedveltebb hibavadászati módszer.
A Google XSS Game a Google által biztosított képzési platform az XSS gyakorlására. Ez áll 6 szintek és minden szinten, akkor kell végrehajtani egy JavaScript riasztás annak érdekében, hogy továbblépjen a következő szintre. Minden szinten különböző problémákat kap, és minden szinten különböző technikákkal kell végrehajtania a riasztást. Ez segít megérteni a különböző módszereket, amelyekkel XSS-t lehet végrehajtani egy weboldalon.
Szerint kezdjük el.
Navigáljon a https://xss-game.appspot.com címre. Itt elérhető a Google XSS játék.
Egy ilyen oldalt fog látni

Kattintson a Let me at ’em! hogy belépjen a játékba.
Első feladat : Hello world of XSS

A virtuális böngészőbe kell az xss payloadot befecskendeznie. A forráskódot a “toggle” linkre kattintva tekintheti meg. Ha nem sikerül az injektálás, akkor a “show” linkre kattintva kaphatsz tippeket.
A forráskód ellenőrzése közben kiderül, hogy ez egy python szkript, és a függvénydef get(self) 2 érdekes része a
self.response.headers.add_header("X-XSS-Protection", "0")
és
query = self.request.get('query', '')
message = "Sorry, no results were found for <b>" + query + "</b>."
message += " <a href='?'>Try again</a>."
Az első rész kikapcsolja a chrome XSS auditorát, és lehetővé teszi számunkra az XSS payload injektálását a böngészőben.
A második rész azt mutatja, hogy az url param query értéke közvetlenül a testhez kerül. Ezt kell kihasználnunk.
Ez egy egyszerű, és megpróbálhatod beírni az alábbiak bármelyikét (és még több is van) a keresőmezőbe, és keresni
<a href="javascript:alert()">Link</a>
<img src=X onerror="alert()">
<script>alert()</script>
És így tovább. Ha az elsőt használtad, akkor a Linkre kell kattintanod a riasztás végrehajtásához.
Nagyszerű!!! Sikeresen teljesítetted az 1. szintet. Most egy gombot fogsz látni, amellyel a következő szintre léphetsz.
Második feladat : A kitartás a kulcs

Ebben a feladatban egy poszt hozzáadásával kell végrehajtanod a riasztást. Ebben a játékban ez DOM XSS, de ha valódi chat/kommentáló alkalmazásokon teszteljük, akkor ez egy tárolt XSS lesz.
Oké, nézzük meg a forrást és az előző üzenetet is.
A forrás vizsgálatakor láthatjuk, hogy az alapértelmezett üzenet különböző típusú html tageket használ a stílushoz. Ez a mi kulcsunk.
Vizsgáljuk meg a forrást, hogy ezt megerősítsük. Így jelenik meg a bejegyzésünk
Láthatjuk, hogy a bejegyzés nem megy át semmilyen szűrőn. Tehát bármelyik fent említett módszert használhatjuk.
<a href="javascript:alert()">Link</a>
<img src=X onerror="alert()">
És így tovább.
Gratulálunk. Teljesítetted a 2. szintet. Most lépj tovább a következő szintre.
3. feladat : Az a süllyedő érzés

Ez csendben különbözik a 2-től, amit már teljesítettünk. Itt meg kell tanulnunk a window.location.hash.-t. Ez a # szimbólum után következő rész, és az oldalon belüli navigációhoz használják. Ez egy böngészőfunkció, és JavaScript nélkül is működik.
Vizsgáljuk meg ennek a forráskódját.
A kód érdekes része
var html = "Image " + parseInt(num) + "<br>";
html += "<img src='https://medium.com/static/level3/cloud" + num + ".jpg' />";
num a window.location.hash értékét tartja, és 2 helyen használják. Az első helyen a parseInt függvényen belül használják, ezért a mi payloadunk ott nem fog működni. A következő sorban azonban a nyers adatot használjuk. Ez az a hely, ahová be fogjuk injektálni a payloadunkat.
Szóval ott kell bezárnunk egyetlen idézőjelet ' és be kell injektálnunk a payloadunkat.
Kipróbálhatsz bármilyen payloadot a ' ' belsejében #
Kipróbálhatod, hogy a # után az alábbiak közül bármelyiket beteszed és meglátogatod az url-t.
1' onerror='alert()
1'><img src=X onerror="alert()">'
1'><script>alert()</script>'
1'><a href="javascript:alert()">Link</a>'
És így tovább.
Nagyszerű. Most már továbbléphetünk a következő szintre.
A 4. feladat : A kontextus számít

Az időzítő időtartamának megadására van hely. Ezt fogjuk kihasználni.
Nézzük meg a forráskódot.
A timer.html-ben ezt a sort láthatjuk
<img src="https://medium.com/static/loading.gif" onload="startTimer('{{ timer }}');" />
Az {{ timer }} kifejezésben kell kihasználnunk, de ez egy startTimer(''); függvényben van elhelyezve, ami egy onload esemény kezelője. A fő szempont, hogy a HTML-ben az eseménykezelő attribútum több visszahívási függvényt is elfogad.
Ezért be kell zárnunk a függvényt, és ott kell végrehajtanunk a figyelmeztetésünket. Vegye figyelembe, hogy az értéket nem egy parseInt függvényen keresztül adtuk át, hanem a nyers adatokat használjuk. Tehát lezárhatjuk a függvényt egy '); hozzáadásával, majd beilleszthetjük a alert-unkat. Mivel inline-ként van használva, nem injektálhatjuk oda a alert();-t, mert az tönkretenné a dolgokat. Az utasítás onload="startTimer('3'); alert();')" lesz, és nem fog működni.
Ezért hozzá kell adnunk egy mintát, hogy a minta ne törjön meg.
Adjunk hozzá alert(' és ez elég.
Szóval a payloadunk a következő lesz
3');alert('
Az időzítő indítása gombra kattintva végrehajtjuk a riasztást és ezzel befejeztük ezt a szintet.
Előrelépés a következő feladathoz.
Feladat 5 : A protokoll megtörése

A kezdőlapon nincs módunk semmit beadni. Csak egy linkünk van. Tehát kattintsunk rá.
Itt 2 helyet láthatunk, ahová bejuttathatjuk a hasznos terhelésünket. egyet magán az url-en, egyet pedig a beviteli mezőn. A beviteli mező egy olyan hely, ahová beírhatjuk az e-mail címünket, és reméljük, hogy az nem fog máshol visszatükröződni. Tehát menjünk az elsőhöz. Az url-en.
Nézzük meg az aktuális pag forráskódját, azaz a signup.html-t, és láthatjuk a sort
<a href="{{ next }}">Next >></a>
Nagyszerű hely a payload befecskendezésére. A mi payloadunk a href attribútum értékeként lesz beállítva egy a tagben. Ha képesek vagyunk a javascript:alert() hozzáadására, akkor végre tudjuk hajtani a hasznos terhelésünket. Most nézzük meg, hogy mi az next értéke. Nem találunk ilyet az oldalon. Hol keressük?
Python kód a segítségünkre. Nézzük meg a level.py-t, és látni fogjuk
if "signup" in self.request.path:
self.render_template('signup.html',
{'next': self.request.get('next')})
Az url-ben szereplő next értékét fogjuk használni.
Változtassuk meg az next értékét az url-ben confirm-ről javascript:alert()-re és a végleges url így fog kinézni
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 és a függvénytestben a következő kódot láthatjuk.
var scriptEl = document.createElement('script');
Szóval külső js fájlt tudunk betölteni, de nem http vagy https url-ből.
Itt próbáljuk ki a data urlokat.
Az adat urlok data:{type},content
Az # utáni értéket tehát módosítsuk
data:application/javascript,alert()
vagy
data:text/plain,alert()-re, és a alert-t végre tudjuk hajtani.
Itt van egy videó a játék megoldásáról.