XSS (Cross Site Scripting)
Last updated
Last updated
Se você está interessado em carreira de hacking e hackear o inhackeável - estamos contratando! (fluente em polonês escrito e falado é necessário).
Verifique se qualquer valor que você controla (parâmetros, caminho, cabeçalhos?, cookies?) está sendo refletido no HTML ou usado pelo código JS.
Encontre o contexto onde está refletido/usado.
Se refletido
Verifique quais símbolos você pode usar e, dependendo disso, prepare o payload:
Em HTML bruto:
Você pode criar novas tags HTML?
Você pode usar eventos ou atributos que suportam o protocolo javascript:
?
Você pode contornar proteções?
Dentro de uma tag HTML:
Você pode sair para o contexto HTML bruto?
Você pode criar novos eventos/atributos para executar código JS?
O atributo onde você está preso suporta execução de JS?
Você pode contornar proteções?
Dentro do código JavaScript:
Você pode escapar da tag <script>
?
Você pode escapar da string e executar código JS diferente?
Sua entrada está em literais de template ``?
Você pode contornar proteções?
Função Javascript sendo executada
Você pode indicar o nome da função a ser executada. ex.: ?callback=alert(1)
Se usado:
Você poderia explorar um DOM XSS, preste atenção em como sua entrada é controlada e se sua entrada controlada é usada por algum sink.
Ao trabalhar em um XSS complexo, pode ser interessante saber sobre:
Para explorar com sucesso um XSS, a primeira coisa que você precisa encontrar é um valor controlado por você que está sendo refletido na página da web.
Refletido intermediaramente: Se você descobrir que o valor de um parâmetro ou até mesmo o caminho está sendo refletido na página da web, você poderia explorar um XSS Refletido.
Armazenado e refletido: Se você descobrir que um valor controlado por você está salvo no servidor e é refletido toda vez que você acessa uma página, você poderia explorar um XSS Armazenado.
Acessado via JS: Se você descobrir que um valor controlado por você está sendo acessado usando JS, você poderia explorar um DOM XSS.
Ao tentar explorar um XSS, a primeira coisa que você precisa saber é onde sua entrada está sendo refletida. Dependendo do contexto, você poderá executar código JS arbitrário de diferentes maneiras.
Se sua entrada é refletida dentro do valor do atributo de uma tag, você poderia tentar:
Escapar do atributo e da tag (então você estará no HTML bruto) e criar uma nova tag HTML para abusar: "><img [...]
Se você pode escapar do atributo, mas não da tag (>
está codificado ou excluído), dependendo da tag, você poderia criar um evento que executa código JS: " autofocus onfocus=alert(1) x="
Se você não pode escapar do atributo ("
está sendo codificado ou excluído), então dependendo de qual atributo seu valor está sendo refletido, se você controla todo o valor ou apenas uma parte, você poderá abusar disso. Por exemplo, se você controla um evento como onclick=
, você poderá fazê-lo executar código arbitrário quando for clicado. Outro exemplo interessante é o atributo href
, onde você pode usar o protocolo javascript:
para executar código arbitrário: href="javascript:alert(1)"
Se sua entrada é refletida dentro de "tags não exploráveis", você poderia tentar o truque do accesskey
para abusar da vulnerabilidade (você precisará de algum tipo de engenharia social para explorar isso): `" accesskey="x" onclick="alert(1)" x="
Exemplo estranho de Angular executando XSS se você controla um nome de classe:
Neste caso, sua entrada é refletida entre <script> [...] </script>
tags de uma página HTML, dentro de um arquivo .js
ou dentro de um atributo usando o protocolo javascript:
:
Se refletido entre <script> [...] </script>
tags, mesmo que sua entrada esteja dentro de qualquer tipo de aspas, você pode tentar injetar </script>
e escapar desse contexto. Isso funciona porque o navegador primeiro analisará as tags HTML e depois o conteúdo, portanto, não notará que sua tag injetada </script>
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 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 template, você pode incorporar expressões JS usando a sintaxe ${ ... }
: var greetings = `Hello, ${alert(1)}`
Codificação Unicode funciona para escrever código javascript válido:
Javascript Hoisting refere-se à oportunidade de declarar funções, variáveis ou classes após serem usadas, para que você possa abusar de 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:
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 na prática é algo como: ?callback=callbackFunc
.
Uma boa maneira de descobrir se algo fornecido diretamente pelo usuário está tentando ser executado é modificando o valor do parâmetro (por exemplo, para 'Vulnerable') e procurando no console por erros como:
Caso seja vulnerável, você poderá 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:
Algumas funções úteis para isso:
Você também pode tentar disparar 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, a exploração de Same Origin Method Execution (SOME) foi desenvolvida:
Há código JS que está usando inseguramente alguns dados controlados por um atacante como location.href
. Um atacante poderia abusar disso para executar código JS arbitrário.
Esses tipos de XSS podem ser encontrados em qualquer lugar. Eles não dependem apenas da exploração do cliente de uma aplicação web, mas de qualquer contexto. Esses tipos de execução arbitrária de JavaScript podem até ser abusados para obter RCE, ler arquivos arbitrários em clientes e servidores, e mais. Alguns exemplos:
Nesse caso e se nenhuma lista negra/branca for usada, você poderia usar payloads como:
Mas, se a lista negra/branca de tags/atributos estiver sendo usada, você precisará forçar quais tags você pode criar. Uma vez que você tenha localizado quais tags são permitidas, você precisará forçar atributos/eventos dentro das tags válidas encontradas para ver como você pode atacar o contexto.
Se você não encontrou 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 naquele objeto e executar o código:
Se algum tipo de blacklist estiver sendo usada, você pode tentar contorná-la com alguns truques bobos:
Eventos de estilo
Mesmo se você não puder escapar do atributo ("
está sendo codificado ou deletado), dependendo de qual atributo seu valor está sendo refletido em se você controla todo o valor ou apenas uma parte você poderá abusar disso. Por exemplo, se você controla um evento como onclick=
você poderá fazer com que ele execute código arbitrário quando for clicado.
Outro exemplo interessante é o atributo href
, onde você pode usar o protocolo javascript:
para executar código arbitrário: href="javascript:alert(1)"
Bypass dentro do evento usando codificação HTML/codificação URL
Os caracteres codificados em HTML dentro do valor dos atributos das tags HTML são decodificados em tempo de execução. Portanto, algo como o seguinte será válido (a carga útil está em negrito): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Voltar </a>
Note que qualquer tipo de codificação HTML é válido:
Observe que a codificação de URL também funcionará:
Bypass dentro do evento usando codificação Unicode
Lá você pode usar os protocolos javascript:
ou data:
em alguns lugares para executar código JS arbitrário. Alguns exigirão interação do usuário e outros não.
Lugares onde você pode injetar esses protocolos
Em geral, o protocolo javascript:
pode ser usado em qualquer tag que aceite o atributo href
e na maioria das tags que aceitam o atributo src
(mas não <img
)
Outras truques de ofuscação
Neste caso, a codificação HTML e o truque de codificação Unicode da seção anterior também são válidos, pois você está dentro de um atributo.
Além disso, há outro truque legal para esses casos: Mesmo que sua entrada dentro de javascript:...
esteja sendo codificada em URL, ela será decodificada em URL antes de ser executada. Portanto, se você precisar escapar da string usando uma aspa simples e você perceber que está sendo codificada em URL, lembre-se de que não importa, ela será interpretada como uma aspa simples durante o tempo de execução.
Note que se você tentar usar ambos URLencode + HTMLencode
em qualquer ordem para codificar o payload, isso não vai funcionar, mas você pode misturá-los dentro do payload.
Usando codificação Hex e Octal com javascript:
Você pode usar Hex e Octal encode dentro do atributo src
de iframe
(pelo menos) para declarar tags HTML para executar JS:
Se você puder injetar qualquer URL em uma tag <a href=
arbitrária que contenha os atributos target="_blank" e rel="opener"
, verifique a página a seguir para explorar esse comportamento:
E em meta tags:
A carga útil de XSS será algo como isto: " accesskey="x" onclick="alert(1)" x="
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 URL
Codificação Hex e Octal
Codificação de dados
Bypasses para tags e atributos HTML
Bypasses para código JavaScript
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 esse elemento ocupa para maximizar as probabilidades de ativar o link.
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 CSS Styling Gadgets, 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
<a href="" id=someid class=test onclick=alert() a="">
Nestes casos, sua entrada vai ser refletida dentro do código JS de um arquivo .js
ou entre as tags <script>...</script>
ou entre eventos HTML que podem executar código JS ou entre atributos que aceitam o protocolo javascript:
.
Se seu código for inserido dentro de <script> [...] var input = 'dados refletidos' [...] </script>
você poderia facilmente escapar fechando a tag <script>
:
Note que neste exemplo não fechamos nem mesmo a aspa simples. Isso ocorre porque a análise HTML é realizada primeiro pelo navegador, o que envolve identificar elementos da página, incluindo blocos de script. A análise de JavaScript para entender e executar os scripts incorporados é realizada apenas depois.
Se <>
estiverem sendo sanitizados, você ainda pode escapar a string onde sua entrada está localizada e executar JS arbitrário. É importante corrigir a sintaxe JS, porque se houver erros, o código JS não será executado:
Para construir strings além de aspas simples e duplas, o JS também aceita backticks ``
. Isso é conhecido como template literals, pois permite expressões JS embutidas usando a sintaxe ${ ... }
.
Portanto, se você descobrir que sua entrada está sendo refletida dentro de uma string JS que está usando backticks, você pode abusar da sintaxe ${ ... }
para executar código JS arbitrário:
Isso pode ser abusado usando:
Strings
Escapamentos especiais
Substituições de espaço dentro do código JS
Espaços em branco do JavaScript
Javascript dentro de um comentário
JavaScript sem parênteses
Chamada de função arbitrária (alert)
Se você pode acionar um XSS enviando a carga útil dentro de um cookie, isso geralmente é um self-XSS. No entanto, se você encontrar um subdomínio vulnerável a XSS, você pode abusar desse XSS para injetar um cookie em todo o domínio, conseguindo acionar o cookie XSS no domínio principal ou em outros subdomínios (aqueles vulneráveis a cookie XSS). Para isso, você pode usar o ataque de cookie tossing:
Talvez um usuário possa compartilhar seu perfil com o admin e, se o self XSS estiver dentro do perfil do usuário e o admin acessá-lo, ele acionará a vulnerabilidade.
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 peçam ajuda e, para que o admin 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.
A dupla "Key","Value" será retornada assim:
Então, o atributo onfocus será inserido e o XSS ocorre.
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 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 cross-site scripting é inútil.
<script>
Válidos para XSSA resposta é:
módulo (padrão, nada a explicar)
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)
Se a página estiver retornando um tipo de conteúdo text/xml, é possível indicar um namespace e executar JS arbitrário:
Se você tiver apenas um conjunto limitado de caracteres para usar, verifique estas outras soluções válidas para problemas de XSJail:
Usando import()
Acessando require
indiretamente
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
:
De maneira semelhante ao exemplo anterior, é possível usar manipuladores de erro para acessar o wrapper do módulo e obter a função require
:
Faça o usuário navegar na página sem sair de um iframe e roube suas ações (incluindo informações enviadas em formulários):
Tempos curtos indicam uma porta respondendo Tempos mais longos indicam nenhuma resposta.
Quando qualquer dado é introduzido 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.
Apenas pesquisando no github, encontrei alguns diferentes:
Você também pode usar metasploit http_javascript_keylogger
Pode injetar código Markdown que será renderizado? Talvez você consiga XSS! Verifique:
Conseguiu XSS em um site que usa cache? Tente atualizar isso para SSRF através da Injeção de Edge Side Include com este payload:
Se uma página da web está criando um PDF usando entrada controlada pelo usuário, você pode tentar enganar o bot que está criando o PDF para executar código JS arbitrário. Assim, se o bot criador de PDF encontrar algum tipo de tags HTML, ele vai interpretá-las, e você pode explorar esse comportamento para causar um XSS no Servidor.
Se você não conseguir injetar tags HTML, pode valer a pena tentar injetar dados PDF:
Se você está interessado em carreira de hacking e hackear o inhackeável - estamos contratando! (fluência em polonês escrita e falada é necessária).
O conteúdo HTML está sendo interpretado por algum mecanismo JS do lado do cliente (AngularJS, VueJS, Mavo...), você poderia abusar de uma .
Se você não puder criar tags HTML que executem código JS, você poderia abusar de uma ?
Se sua entrada é refletida no HTML bruto da página, você precisará abusar de alguma tag HTML para executar código JS: <img , <iframe , <svg , <script
... essas são apenas algumas das muitas tags HTML possíveis que você poderia usar.
Além disso, tenha em mente a .
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: Basta tentar refletir esse caractere e verificar se está sendo codificado em HTML ou deletado ou se está refletido sem alterações. Somente no último caso você poderá explorar esse caso.
Para esses casos, também tenha em mente .
Nota: Um comentário HTML pode ser fechado usando******** -->
ou ****--!>
Vá para 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 descoberta como maliciosa pelo WAF. Uma vez que você tenha descoberto quais tags pode usar, você pode forçar 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 de antes).
Mais pequenos XSS para diferentes ambientes payload e .
The last one is using 2 unicode characters which expands to 5: telsr Mais desses caracteres podem ser encontrados . Para verificar em quais caracteres são decompostos, verifique .
Se para explorar a vulnerabilidade você precisar que o usuário clique em um link ou em um formulário com dados pré-preenchidos, você pode tentar (se a página for vulnerável).
Se você apenas pensa que é impossível criar uma tag HTML com um atributo para executar código JS, você deve verificar porque você poderia explorar a vulnerabilidade sem executar código JS.
Se você está dentro de uma tag HTML, a primeira coisa que você poderia tentar é escapar da tag e usar algumas das técnicas mencionadas na para executar código JS. Se você não puder escapar da tag, você poderia criar novos atributos dentro da tag para tentar executar código JS, por exemplo, usando algum payload como (note que neste exemplo aspas duplas são usadas para escapar do atributo, você não precisará delas se sua entrada for refletida diretamente dentro da tag):
Primeiro, verifique esta página () para manipuladores de evento "on" úteis. Caso haja alguma lista negra impedindo você de criar esses manipuladores de evento, você pode tentar os seguintes bypasses:
De agora é possível abusar de inputs ocultos com:
De : Você pode executar um payload XSS dentro de um atributo oculto, desde que 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 acesso. Aqui está o vetor:
Leia os .
Leia a .
Esse truque foi retirado de
Comentários JavaScript (do )
Quebras de linha em JavaScript (do )
Há código JS que está usando dados controlados de forma insegura por um atacante como location.href
. Um atacante pode abusar disso para executar código JS arbitrário.
Devido à extensão da explicação de :
Lá você encontrará uma explicação detalhada sobre o que são 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 .
Você pode encontrar um grande abuso dessa técnica em .
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. .
Devido à atribuição em massa do RoR, citações são inseridas no HTML e, em seguida, a restrição de citação é contornada e campos adicionais (onfocus) podem ser adicionados dentro da tag. Exemplo de formulário (), se você enviar a carga útil:
Em e 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 no passado: mailto://
, //x:1/
, ws://
, wss://
, cabeçalho Location vazio, resource://
.
Se você conseguir indicar o callback que o javascript vai executar limitado a esses caracteres. para descobrir como abusar desse comportamento.
(De ) Se você tentar carregar um script com um tipo de conteúdo como application/octet-stream
, o Chrome lançará o seguinte erro:
Recusou-se a executar o script de ‘ porque seu tipo MIME (‘application/octet-stream’) não é executável, e a verificação estrita de tipo MIME está habilitada.
Os únicos Content-Type que permitirão que o Chrome execute um script carregado são aqueles dentro da constante kSupportedJavascriptTypes
de
(De ) Então, quais tipos poderiam ser indicados para carregar um script?
: Web Bundles é um recurso que permite empacotar um conjunto de dados (HTML, CSS, JS…) juntos em um .wbn
arquivo.
: Permite melhorar a sintaxe de importação
Esse comportamento foi usado em para remapear uma biblioteca para eval para abusar que pode acionar XSS.
: Este recurso é principalmente para resolver alguns problemas causados pela pré-renderização. Funciona assim:
(De ) Os seguintes tipos de conteúdo podem executar XSS em todos os navegadores:
Em outros navegadores, outros Content-Types
podem ser usados para executar JS arbitrário, confira:
Quando algo como "some {{template}} data".replace("{{template}}", <user_input>)
é usado. O atacante pode usar para tentar contornar algumas proteções: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
Por exemplo, em , isso foi usado para escapar uma string JSON dentro de um script e executar código arbitrário.
Se tudo está indefinido antes de executar código não confiável (como em ), é possível gerar objetos úteis "do nada" para abusar da execução de código não confiável arbitrário:
os módulos são encapsulados pelo Node.js dentro de uma função, assim:
Diferentes ofuscações em uma página:
Mais sofisticação JSFuck:
Você não conseguirá acessar os cookies do JavaScript se a flag HTTPOnly estiver definida no cookie. Mas aqui você tem se tiver sorte.
Revise a lista de portas banidas no Chrome e no Firefox .
Você também pode usar:
A partir de é possível aprender que mesmo que alguns valores desapareçam do JS, ainda é possível encontrá-los em atributos JS em diferentes objetos. Por exemplo, uma entrada de um REGEX ainda é possível encontrá-la após o valor da entrada do regex ter sido removido:
Use-o para contornar restrições de cookies, filtros de XSS e muito mais! Mais informações sobre esta técnica aqui: .
AMP, voltado para acelerar o desempenho de páginas da web em dispositivos móveis, incorpora tags HTML complementadas por JavaScript para garantir funcionalidade com ênfase em velocidade e segurança. Ele suporta uma variedade de componentes para diversos recursos, acessíveis através de .
O formato estende componentes AMP específicos para e-mails, permitindo que os destinatários interajam com o conteúdo diretamente em seus e-mails.
Exemplo .
Envie como uma imagem um arquivo como o seguinte (de ):
Encontre mais payloads SVG em
Aprenda e pratique Hacking AWS: Aprenda e pratique Hacking GCP:
Confira os !
Junte-se ao 💬 ou ao ou siga-nos no Twitter 🐦 .
Compartilhe truques de hacking enviando PRs para o e repositórios do github.