Web Cache Poisoning

Yayınlayan
Muhammed Eren Uygun
Yayınlanma tarihi
25/2/2022
Okuma süresi
15
Dakika
go back icon
Geri Dön

Web Cache Poisoning

Web Cache Poisoning, Türkçe karşılığı ile web önbellek zehirlenmesi yaklaşık bir sene önce Güvenlik Araştırmacısı James Kettle tarafından keşfedilen, belli başlı web sitelerinin ve çevrimiçi platformların web önbelleklerinde değişiklik yaparak zararlı kod çalıştırılmasına olanak sağlayan bir saldırı türüdür.

James Kettle’ın başarıyla amacına ulaştığı mağdurlar arasında çevrimiçi mağazalar, kritik bir yazılım ürünü, bir video oyunu, popüler bir bulut platformu sağlayıcısı, bir hosting sağlayıcısı ve yatırım şirketinin yatırımcı bilgileri bulunmaktadır. Böylelikle saldırının ne kadar önemli olduğunun bilgisini de anlamış oluyoruz.

Cache(Önbellek) Nedir?

Bir uygulamayı ikinci kez açtığımızda genellikle daha hızlı bir şekilde açılır. Bunun nedeni tabii ki bilgisayarımızda Cache (Önbellek)’in çalışmasıdır. Dolayısıyla sitelerin daha hızlı açılmasına olanak sağlar. Önbellek, verileri depolayan ve en son yaptığımız işlemleri değerlendirerek; bir sonraki işlemi %90 tahmin edip, bu bilgileri tutan bu şekilde de işlemlerimizi hızlı bir şekilde yapmamızı sağlayan CPU içindeki yüksek hızlı hafızalara denir.

Bilgisayar bilimlerindeki tüm önbellekleme biçimleri, ister CPU önbelleği, ister HTTP Web Sunucusu önbelleği isterse de veri tabanı önbelleği talep edilenler için yanıt sürelerini hızlandırmayı amaçlar. Bunu yapmak, aktif olarak önbelleğe alınan bileşen üzerindeki yükü mümkün olduğunca azaltmaya yardımcı olur.

Bu ilke nedeniyle, önbellek, istemci(web tarayıcısı, mobil uygulama, vb.) ve sunucu arasında olması eğilimindedir. Web Önbellek Zehirlenmesini anlamak için bunu anlamak çok önemlidir.

web-cache-poisoning

Ağın ekosisteminde, kullanılan önbellek türleri değişebilir. Bazı örnekler şunları içerir ancak bunlarla da sınırlı değildir:

  • Memcached
  • Varnish
  • CDNs (i.e. Akamai, MaxCDN, AWS)

Web önbelleklemesinin görevi ise, istemci tarafından yapılan ağ isteklerinin gelmesini beklemek ve daha sonra bu istekler sonucunda sunucudan dönen yanıtların kopyalarını kaydetmektir. Bu kopyalar Web sayfaları (HTML belgeleri), resimler, JavaScript dosyaları veya diğer dosya türleri olabilir.

web-cache-poisoning

Böylelikle kullanıcı aynı web adresi veya URL için başka bir talepte bulunursa web önbelleği, yeni bir isteği kaynak sunucuya geri göndermek yerine, önceden sakladığı yanıtı kullanabilir. Bu nedenle, biz web önbelleklerinin içeriğini bir şekilde değiştirip tekrar istemciyi döndürürsek zafiyetin temel noktasını başarmış oluruz.

Önbellek Anahtarları:

Önbellekleme kavramı hayatımızı kolaylaştıran, elverişli gibi görünebilir fakat bazı riskli yaklaşımları da bünyesinde gizler. Bir Önbellek, istemci tarafından bir istek aldığı zamanda daha önceden bu isteğin bir kopyasının depolanıp depolanmadığına bakması gerekir. Böylelikle eğer ki kopyasını bulursa onunla devam edip kullanıcıya döndürür eğer ki bulamazsa isteğin bir kopyasını depolayarak bir sonraki aşamalarda aynı işlemi yapmamak için işini kolaylaştırır.

Önbellek, bu durumda istek ile isteğin kopyasını bayt karşılaştırmamaktadır. O şekilde karşılaştırdığı zaman isteklerde bulunan User-Agent kavramının içinde tarayıcısı farklı olan veriler ile karşılaşabilir, başka header (başlık) bilgilerinde aksaklıklar oluşabilmektedir. Önbellek karşılaştırmasını yaparken HTTP İsteğinde bulunan aşağıdaki resimde turuncu renk ile gözüktüğü gibi URL veya Host anahtarlarını baz alarak karşılaştırma yapmaktadır.

web-cache-poisoning

Fakat önbellek bu şekilde karşılaştırma yaptığında aklımıza başka başlık bilgilerinde bulunan bilgilerin göz ardı edildiği gelmektedir. Örnek ile açıklayalım.

web-cache-poisoning

Burada normal bir şekilde sayfamızın /blog/post.php?mobile=1 kısmına GET isteği atıyoruz. Karşımıza normal koşullarda dili İngilizce olan bir sayfa çıkması muhtemel. Daha sonradan example.com’un bu dizinine giriş yaptığımızda bu yaptığımız istek ilk defa döneceği için önbellek tarafına anahtarlar baz alınarak kaydediliyor.(Daha sonradan gelen istek ile karşılaştırabilmek için).

Sonra biz aynı şekilde bu sefer language=en; parametresini language=pl; olarak değiştiriyoruz. Bu şekilde istek atıyoruz.

web-cache-poisoning

İsteğimizi bu resimdeki gibi düzenledikten sonra gönderiyoruz. Burada önbellek istekte karşılaştırması gereken anahtarlara baktığı zaman daha önceden attığımız anahtarlar ile aynı olduğunun farkına varıyor ve sunucuya gitmeden daha önce kaydetmiş olduğu isteğin yanıtını bu isteği gönderen kullanıcıya gönderiyor. Fakat saldırgan dil parametresini değiştirmişti. Sonuç olarak bize İngilizce sayfa dönmekte ve sayfaya anahtarsız bir giriş şeklinde bir yazı yansımaktadır.

Buradan sonra anahtarları değiştirip “/blog/post.php?mobile=1&cachebust=1” gibi ya da daha sonradan dil parametresinin içeriğinde “Cookie:language=;” gibi bir zararlı kod yazılırsa zararlı kodumuzu başarılı bir şekilde çalıştırabilmiş olacağız.

Aslında, sitelerde bu durumun önüne geçebilmek için, anahtarlanması gereken ek istek başlıklarını “Vary” yanıt başlığı ile belirterek kullanabilir. Fakat Cloudflare gibi CDN’ler bunu tamamen görmezden gelir ve kullanıcılar uygulamalarının herhangi bir başlık tabanlı girişi desteklediğini bile fark etmez.

Önbellek Zehirlenmesi

Web önbellek zehirlenmesinin amacı, önbellekte kaydedilen isteği değiştirip sunucu tarafından kullanıcılara zararlı bir yanıt döndürmektir.

web-cache-poisoning

Bundan sonra HTTP başlıkları gibi anahtarsız girdileri kullanarak önbellekleri nasıl zehirleyeceğimizi örnekler ile göreceğiz. Tabii ki bu yöntem, önbellek zehirlenmesinin tek yolu değildir. HTTP Yanıt Bölme (Response Splitting) veya Talep Kaçakçılığı (Request Smuggling) gibi yöntemler de kullanılabilmektedir.

Web Cache Poisoning (Web Önbellek Zehirlenmesi), Web Cache Deception (Web Önbellek Aldatması) adlı saldırı türü ile karıştırılmamalıdır.

Önbellek zehirlenmesi ile güvenlik açıklarını bulmak için aşağıdaki metodolojiyi kullanacağız.

web-cache-poisoning

Şimdi bu metodolojiyi inceleyelim. İlk adım, anahtarsız girişleri tespit etmektir. James Kettle bunu manuel olarak yapmayı sıkıcı bulduğundan ve aslında bizimde işlerimizi kolaylaştıracak bir Burp Suite eklentisi geliştirmiştir. Bu eklentinin ismi Param Miner(bkz. https://github.com/PortSwigger/param-miner), bu eklenti başlık ve çerez adlarını tahmin ediyor ve uygulamanın yanıtı üzerinde herhangi bir etkisi olup olmadığına bakıyor.

Anahtarsız bir girişi bulduktan sonraki adımda, bu bilgiler ile zarar verme potansiyelini değerlendirme işlemi yapmaktadır. Ardından önbelleğin içerisine enjekte etmeyi denemektedir. Başarısız olunması durumunda, yeniden denemeden önce önbelleğin nasıl çalıştığına ve önbelleğe alınabilir bir hedefin sayfaya nasıl atak yapıldığına bakıp çok iyi anlaşılması gerekmektedir. Bir sayfanın önbelleğe alınıp alınmadığı, dosya uzantısı, içerik türü, rota, durum kodu ve yanıt başlıkları gibi çeşitli faktörlere bağlı olabilir.

Önbelleğe alınan yanıtlar, anahtarsız girişleri maskeleyebilir, bu nedenle anahtarsız girişleri manuel olarak algılamaya veya araştırmaya çalışıyorsanız, bir önbellek bozucu çok önemlidir. Eğer Param Miner kullanılıyor ise, yapılan her isteğin sorgu dizgesine $randomplz değerinde bir parametre eklenip benzersiz bir önbellek anahtarına sahip olunmalıdır.

Normalde canlı bir web sitesinde bu işlemi denerken, yanlışlıkla önbelleğin zehirlenmesi ziyaretçiler üzerinde kalıcı bir etki bırakır. Fakat Param Miner, Burp Suite’den gelen tüm isteklere önbellek bozucu (cache-buster) ekleyerek bunu azaltır. Bu önbellek bozucu, sabit bir değere sahiptir, böylece diğer kullanıcıları etkilemeden önbellek davranışını kendiniz görebilirsiniz.

Redhat – Basic Poisoning(Basit Zehirlenme):

Redhat ana sayfasında Param Miner uygulaması çalıştırıldığı zaman hemen karşımıza anahtarsız bir girişe sahip olan istek gelmektedir.

web-cache-poisoning

Burada, X-Forwarded-Host başlığının uygulama tarafından bir meta etiketi içinde bir Open Graph URL oluşturmak için kullanıldığını görüyoruz. Bir sonraki adım ise sömürülebilir olup olmadığını araştırmaktır. Bu yüzden XSS payload’ı denenmiştir.

web-cache-poisoning

İsteğin gönderileceği kullanıcı için JavaScript kodunun çalıştırabildiği gözlenmektedir. Son adım ise bu yanıtın bir önbellekte saklanıp saklanmadığını kontrol etmektir. Böylece diğer kullanıcılara ulaştırılabilmektedir. ‘Cache-control: no cache’ başlığının etkisi bu noktada kontrol edilmelidir. Önce isteği kötü amaçlı bir başlık olmadan yeniden göndererek ve ardından URL’yi doğrudan farklı bir makinedeki tarayıcıya getirerek doğruladığınızda isteğin önbelleğe alındığını görmekteyiz.

Unity – Discreet Poisoning(Gizli Zehirlenme):

Bir bloğun ana sayfasını zehirlemek ve istismarımızı sonraki tüm ziyaretçilere sunmak için, önbelleğe alınan yanıtın süresi dolduktan sonra ilk isteği ana sayfaya göndermemizi sağlamamız gerekir.

Bu durum Burp Suite’in Intruder özelliği ile veya çok sayıda istek göndermek için özel bir komut dosyası ile denenebilmektedir. Ancak bu tür yöntemlerde trafik fazla yoğun olacağı için bu yaklaşım zor olmaktadır ve tercih edilmemektedir. Bir saldırgan, hedefin önbellek sona erme sistemini tersine mühendislikle tersine çevirip, dokümantasyonu inceleyerek ve siteyi zaman içinde izleyip kesin sona erme zamanlarını tespit ederek potansiyel olarak bu sorunu önleyebilmektedir.

Unity3d.com’da bulunan önbellek zehirlenmesini inceleyelim.

web-cache-poisoning

Burada  anahtarsız bir girişimiz ve bir komut dosyasının içerisine aktarma işlemi için kullanılan X-Host başlığı bulunmaktadır. Response headerları ‘Age’ ve ‘max-age’ sırasıyla geçerli yanıtın yaşını ve süresinin ne kadar olacağını belirtir. Birlikte ele alındığında, bunlar bize cevabımızın ön belleklenmesini sağlamak için yükümüzü göndermemiz gereken  son saniyeyi söylemektedir.

Redacted – Selective Poisoning (Seçici Zehirlenme):

HTTP başlıkları, önbelleklerin çalışmalarına zaman kazandıran bilgiler sağlayabilir.

web-cache-poisoning

Bu örnek durumda neredeyse başlangıçtaki ilk örnekle aynı durum görülmektedir. Ancak burada ilk örnekten farklı olarak başlık bilgisinde “Vary” değişkenimiz mevcut durumdadır.

Kullanıcının tarayıcısı “Firefox 60” sürümü olduğu için zafiyetin diğer kullanıcılar tarafından da oluşması için “Firefox 60” sürümünü kullanmaları gerekmektedir.

Farklı bir tarayıcı ile giriş yapıldığında “user-agent” başlık bilgisi farklı olacağından diğer kullanıcılara zafiyeti yansıtmak mümkün olmamaktadır. Bu durumda en çok tercih edilen “user-agent” bilgisi kullanılmaktadır.

Data-gov – DOM Poisoning(DOM Zehirlenmesi):

Anahtarsız bir girişi kullanırken her zaman bir XSS payload’ını kullanmak mantıklı değildir. Param Miner uygulamamızın sonucunda gelen anahtarsız giriş isteğini inceleyelim.

web-cache-poisoning

Burada ‘data-site-root’ özelliğinin kontrolü ele geçirilmektedir, ancak burada XSS payload’ı çalışmamakta ve bu özelliğin ne için kullanıldığı bilinmemektedir. Öncelikle  “data-site-root” özelliğinin işlevi öğrenilmelidir. Dolayısıyla, tüm isteklere ‘X-Forwarded-Host: id.burpcollaborator.net’ başlığı eklenerek Burp Suile ile bir eşleme (match) ve değiştirme (replace) kuralı oluşturmak ve siteyi taramak gereklidir. Belirli sayfalar yüklendiğinde, Firefox sunucusuna JavaScript tarafından oluşturulan bir istek gönderilmektedir.

web-cache-poisoning

Web sitesinde uluslararasılaştırma verilerini nereye yükleyeceğine karar vermek için “data-site-root” özelliğini kullanan JavaScript kodu olduğu görülmektedir. Bu verinin nasıl görünmesi gerektiğini öğrenmek adına https://catalog.data.gov/api/i18n/tr adresi incelendiğinde yalnızca boş bir JSON yanıtı dönmektedir. ‘en’’ değeri ‘es’ şeklinde değiştirildiğinde sonuç da değiştirmektedir.

web-cache-poisoning

Bu durumda XSS Payload’ı kullanılarak zafiyet oluşturulabilmektedir.

web-cache-poisoning
Hubspot – Route Poisoning (Güzergah Zehirlenmesi):

Bazı uygulamalar URL üretmek için yanlış başlıklar kullanmanın ötesine geçer ve bunları yanlış iç istek yönlendirme için kullanır.

web-cache-poisoning

Goodhire.com ve HubSpot’ta zafiyet net görülmektedir. HubSpot,  Host header’ına göre X-Forwarded-Server header önceliğini vermekte ve bu isteğin hangi müşteriye yönelik olduğu konusunda karışıklık yaratmaktadır. Girdilerimiz sayfalara yansıtılsa da, HTML kodludur, bu nedenle basit bir XSS saldırısı burada çalışmamaktadır. Bundan yararlanmak için hubspot.com adresine gitmemiz, kendimizi bir HubSpot istemcisi olarak kaydetmemiz, HubSpot sayfamıza bir payload yüklememiz ve ardından HubSpot’u goodhire.com’da bu cevabı vermesi için kandırmamız gerekir.

web-cache-poisoning

Bu durumda Cloudflare isteği önbelleğe almakta ve sonraki kullanıcılara yansıtmaktadır.

Savunma

Önbellek zehirlenmesine karşı en sağlam savunma, önbelleklemeyi devre dışı bırakmaktır. Bu, bazıları için kesinlikle gerçekçi olmayan bir öneridir, ancak birkaç web sitesinin DDoS koruması veya kolay SSL için Cloudflare gibi bir hizmeti kullanmaya başladığını ve yalnızca ön bellekleme varsayılan olarak etkin olduğu için zehirlenmeyi önleme konusunda savunmasız kalabilmektedir.

Aynı şekilde, başlıklardan ve çerezlerden girdi almaktan kaçınmak, önbellek zehirlenmesini önlemenin etkili bir yoludur, ancak diğer katmanların ve frameworklerin fazladan başlıkları desteklemek için gizlice girip girmediğini bilmek zordur. Bu nedenle, anahtarsız girişleri temizlemek için başvurunuzun her sayfasını Param Miner ile denetlemek önerilir.

Uygulamanızdaki anahtarsız girişleri belirledikten sonra, ideal çözüm bunları doğrudan devre dışı bırakmaktır. Bazı önbellekler, anahtarsız girişleri anahtarlamak için “Vary” header’ını kullanmanıza izin verirken, diğerleri özel önbellek anahtarları tanımlamanıza izin verir, ancak bu özelliği ‘kurumsal’ müşterilerle sınırlanabilmektedir.

Son olarak, uygulamanızın önbelleği olup olmadığına bakılmaksızın, HTTP başlıklarındaki XSS gibi güvenlik açığı asla göz ardı edilmemelidir.

Sonuç

Web Cache Poisoning zafiyeti ile önbellekleme sisteminde bulunan bir zafiyet ile diğer kullanıcı bilgisayarlarında zararlı kodlar çalıştırmak mümkün olmaktadır. Zafiyet neticesinde aynı özellikteki sayfayı görüntüleyen kullanıcıların oturum bilgisi elde edilebilmekte bir sonraki aşamalarda ise sistemde kod çalıştırmak mümkün olabilmektedir.

Bu yazıyı yazmamda desteklerinden dolayı Berk İmran’a içerik hakkında ise doğal olarak kendi bloğu ve konferans konuşmasından dolayı James Kettle’a teşekkür ederim.

Muhammed Eren Uygun    27.04.2019
Muhammed Eren Uygun

Detaylı Bilgi İçin

info@gaissecurity.com