Cache Poisoning and Cache Deception
Last updated
Last updated
Impara e pratica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Usa Trickest per costruire e automatizzare flussi di lavoro alimentati dagli strumenti comunitari più avanzati al mondo. Accedi oggi:
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.
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:
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.
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.
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.
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.
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 DoSTuttavia, nota che a volte questi tipi di codici di stato non vengono memorizzati nella cache, quindi questo test potrebbe non essere affidabile.
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ì:
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?...)
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.
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:
Nota che questo avvelenerà una richiesta a /en?region=uk
e non a /en
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.
Nota che se il cookie vulnerabile è molto utilizzato dagli utenti, le richieste regolari puliranno la cache.
Controlla:
Cache Poisoning via URL discrepanciesQuesta 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 discrepanciesA 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.
Vary
limitataSe 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:
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:
There it a portswigger lab about this: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get
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
Impara qui come eseguire Cache Poisoning attacks by abusing HTTP Request Smuggling.
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
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.
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 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
.
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.
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.
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.
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.
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.
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
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.
toxicache: scanner Golang per trovare vulnerabilità di web cache poisoning in un elenco di URL e testare più tecniche di iniezione.
Usa Trickest per costruire e automatizzare flussi di lavoro facilmente alimentati dagli strumenti della comunità più avanzati del mondo. Accedi oggi:
Impara e pratica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Impara e pratica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)