Articles

Learning XSS with Google’s XSS Game

Instrukcja krok po kroku, jak rozwiązać Google’s XSS Game

Photo by Markus Spiske temporausch.com from Pexels

XSS aka Cross Site Scripting jest jedną z niebezpiecznych podatności po stronie klienta i jedną z najbardziej lubianych metod polowania na błędy.

Google XSS Game jest platformą szkoleniową dostarczoną przez google do ćwiczenia XSS. Składa się z 6 poziomów, a w każdym z nich musisz wykonać alert JavaScript, aby przejść do następnego poziomu. W każdym poziomie, będziesz miał do czynienia z różnymi problemami i będziesz musiał wykonać alert używając różnych technik na każdym poziomie. Pomoże ci to zrozumieć różne metody, które mogą być użyte do wykonania XSS na stronie internetowej.

Zacznijmy więc.

Przejdź do https://xss-game.appspot.com. To właśnie tam dostępna jest Gra Google XSS.

Zobaczysz stronę taką jak ta

Kliknij przycisk Let me at ’em! aby wejść do gry.

Pierwsze zadanie : Hello world of XSS

Musisz wstrzyknąć ładunek xss do wirtualnej przeglądarki. Możesz zobaczyć kod źródłowy klikając na link „toggle”. Jeśli nie jesteś w stanie wstrzyknąć kodu, możesz uzyskać podpowiedzi klikając na link „pokaż”.

Podczas sprawdzania kodu źródłowego, jest to skrypt python i 2 interesujące części w funkcji
def get(self) to

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

i

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

Pierwsza część wyłączy chromowego audytora XSS i pozwoli nam wstrzyknąć ładunek XSS do przeglądarki.

Druga część pokazuje, że wartość parametru url query jest bezpośrednio dodawana do ciała. To jest właśnie miejsce, które musimy wykorzystać.

To jest proste i możesz spróbować wpisać dowolny z poniższych (a nawet więcej) w polu wyszukiwania i przeszukać go

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

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

<script>alert()</script>

I tak dalej. Jeśli użyłeś pierwszego z nich, musisz kliknąć na Link, aby wykonać alert.

Great!!! Udało Ci się ukończyć poziom 1. Teraz zobaczysz przycisk, aby przejść do następnego poziomu.

Drugie zadanie : Wytrwałość jest kluczem

W tym zadaniu, musisz wykonać alert poprzez dodanie postu. W tej grze, jest to DOM XSS, ale podczas testów na prawdziwych aplikacjach czatu/komentarzy, będzie to przechowywany XSS.

Ok spójrzmy na źródło i poprzednią wiadomość, jak również.

Podczas inspekcji źródła, można zobaczyć, że domyślna wiadomość używa różnych typów znaczników html, aby ją stylizować. To jest nasz klucz.

Sprawdź źródło, aby to potwierdzić. Oto jak nasz post jest renderowany

Widzisz, że post nie przechodzi przez żadne filtry. Możemy więc użyć dowolnej metody wymienionej powyżej.

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

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

I tak dalej.

Gratulacje. Ukończyłeś poziom 2. Teraz przejdź do następnego poziomu.

Zadanie 3 : To uczucie tonięcia

To jest cichy inny od 2, które ukończyliśmy. Tutaj, musimy nauczyć się o window.location.hash. Jest to część przychodząca po symbolu # i jest używana do nawigacji wewnątrz strony. Jest to funkcja przeglądarki i będzie działać nawet bez JavaScriptu.

Sprawdźmy kod źródłowy dla tego kodu.

Interesującą częścią w kodzie jest

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

num przechowuje wartość window.location.hash i jest używany w 2 miejscach. W pierwszym miejscu jest on użyty wewnątrz funkcji parseInt, stąd nasz payload nie będzie tam działał. Natomiast w następnej linii, używane są surowe dane. To właśnie tam zamierzamy wstrzyknąć nasz payload.

Więc musimy zamknąć pojedynczy quot ' tam i musimy wstrzyknąć nasz payload.

Możesz wypróbować dowolny payload wewnątrz ' ' Po #

Spróbuj umieścić dowolny z poniższych po # i odwiedź adres url.

1' onerror='alert()

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

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

1'><a href="javascript:alert()">Link</a>'
I tak dalej.

Świetnie. Teraz możemy przejść do następnego poziomu.

Zadanie 4 : Context Matters

Mamy miejsce na wpisanie czasu trwania timera. To właśnie to miejsce zamierzamy wykorzystać.

Sprawdźmy kod źródłowy.

W pliku timer.html możemy zobaczyć taką linię

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

Musimy wykorzystać w wyrażeniu {{ timer }} Ale jest ono umieszczone wewnątrz funkcji startTimer('');, która jest event handlerem do zdarzenia onload. Głównym punktem do zauważenia jest to, że atrybut obsługi zdarzenia w HTML akceptuje wiele funkcji wywołania zwrotnego.

Więc musimy zamknąć funkcję i wykonać nasz alert tam. Zwróć uwagę, że wartość nie została przekazana przez funkcję parseInt zamiast tego używane są surowe dane. Więc możemy zamknąć funkcję przez dodanie '); i następnie wstrzyknąć nasz alert. Ponieważ jest on używany jako inline, nie możemy wstrzyknąć tam alert();, ponieważ zepsuje to rzeczy. The statement will become onload="startTimer('3'); alert();')" and it won’t work.

So we have to add a pattern that keep the pattern unbroken.
Add alert(' and it is enough.

So our payload will be

3');alert('

Clicking on start timer button will execute the alert and we’ve finished this level.

Przejdź do następnego zadania.

Zadanie 5 : Breaking Protocol

Na stronie głównej nie mamy możliwości wstrzyknięcia czegokolwiek. Wszystko co mamy to link. Kliknijmy więc na niego.

W tym miejscu widzimy dwa miejsca do wstrzyknięcia naszego payloadu. Jedno na samym adresie url, a drugie w polu wejściowym. Pole wejściowe jest miejscem, gdzie można wpisać email i mieć nadzieję, że nie zostanie on odbity gdzieś indziej. Przejdźmy więc do pierwszego z nich. Na adresie url.

Sprawdź kod źródłowy aktualnego paga, czyli signup.html i możemy zobaczyć linię

<a href="{{ next }}">Next >></a>

Doskonałe miejsce na wstrzyknięcie payloadu. Nasz payload będzie ustawiony jako wartość atrybutu href w tagu a. Jeśli uda nam się dodać javascript:alert() będziemy mogli wykonać nasz payload. Zobaczmy teraz jaka jest wartość atrybutu next. Nie możemy znaleźć żadnej na stronie. Gdzie mamy jej szukać???

Kod Pythona na ratunek. Sprawdź level.py i zobaczymy

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

Więc wartość next w adresie url zostanie użyta.

Zmień wartość next w url z confirm na javascript:alert() i ostateczny url będzie wyglądał jak

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 i wewnątrz ciała funkcji, możesz zobaczyć następujący kod.

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

Więc możemy załadować zewnętrzny plik js, ale nie z http lub https url.

Tutaj spróbujmy z data urls.

Dane urls są w postaci data:{type},content

Zmieńmy więc wartość po # na

data:application/javascript,alert()

lub na

data:text/plain,alert() i możemy wykonać alert.

Tutaj filmik z rozwiązywania Gry.

.