preload Hayat Kurtarır, vBulletin Zafiyetleri, Yaratıcı XSS Teknikleri
Bu haftaki yazımızda HSTS preload özelliğinin ön tanımlı hale getirilmesinden, vBulletin’deki kritik zafiyetlerden ve oldukça yaratıcı XSS tetikleme yöntemlerinden bahsediyoruz.
preload Hayat Kurtarır
Her geçen gün web trafiğinin artan bir oranda SSL/TLS yani güvenli bir bağlantı üzerinden sağlanması şüphesiz sevindirici bir gelişme. Let's Encrypt gibi girişimlerin sertifika sahipliğini giderek kolaylaştırması, browser üreticilerin proaktif yaklaşımları bu artışın önemli sebeplerinden. Bu proaktif yaklaşımlardan en önemlisi de browserların HSTS preload listeleri.
Teknik ayrıntılarını Haftanın Hackleri'nde pek çok kez dile getirdiğimiz gibi, güvenli bir bağlantının seçenek olarak kullanıcıya sunulması, daha doğrusu bunun bir seçenek olarak yer alması, MiTM saldırıları ile kolaylıkla bypass edilebilecektir. Nitekim 2009 yılında Blackhat'da Moxie Marlinspike tarafından tanıtılan SSLStrip aracı, kullanıcının ya da bağlantı kuran tarafın güvenli bağlantı kurup kurmama seçeneğinde inisiyatif sahibi olduğu gerçeğini istismar ederek aktif ağ dinlemesi ile güvenli bir bağlantıyı henüz kurulmadan daha güvensiz bir bağlantıya çeviriyor idi.
Teorik olarak güvenli bağlantı kurulabildiğinde, gizlilik ve güvenliği temin ediyor. Fakat altını çizmekte fayda var: güvenli bağlantı kurulabildiği takdirde(!) Gerçekten güvenli bir bağlantı kurabilmek için ise zincirin kayıp halkası, HSTS.
HSTS talimatı ile birlikte web sayfaları, bağlantıyı talep eden tarafın yönlendirdiği bu seçeneği, kendi üzerine alarak browsera, kendisine yönelecek tüm bağlantıların HTTPS 'e dönüştürülmesi emrini vermektedir.
Sadece bu kadar da değil. Akıllara pek çok soru geliyor olabilir. 80 numaralı portumu kapatırım, sunucu tarafında bu yönlendirme işlemini yaparım gibi. Bütün bunlar SSL/TLS'in güvenli bağlantı zincirindeki eksik halkayı, güçlü bir halka ile ikame etmeye yetmeyecek.
Ama önce bu retoriği bir gözden geçirelim. 80 numaralı portu kapatıp, sadece 443 numaralı port üzerinden bağlantı talep kabul etmeye başladınız. Araya giren biri, kendisi ile browser arasında ve aynı zamanda sayfanız ile kendi arasında da güvenli bir bağlantı kurup, sahte bir sertifikayı browsera sunabilir.
Elbette browserlar bu tarz geçerli olmayan sertifikalara karşı bir dizi güvenlik önlemi içeriyor. Örneğin sertifika geçersiz ise, vadesi dolmuş ise veya güçsüz bir şifreleme mekanizmasına sahip ise, browserlar kullanıcıyı uyarmakta. Ama bu uyarıların tamamı kullanıcı tarafından göz ardı edilebilir. Üstelik Add Exception seçenekleri ile kaideyi bozmayan istisnalar olarak kabul edilebilirler.
Kasım 2012 yılında kullanıma sunulan HSTS headerı set edildiğinde, HSTS set eden siteye yönelen bağlantılar max-age'de belirtilen süre boyunca browser tarafından güvenli bir bağlantıya dönüştürülmekte, hem de geçersiz sertifikalar ile karşılaşılması durumunda Go Anyway, Add Exception gibi seçeneklerle bu hataların etrafından dolaşılmasını engellemektedir.
Geçersiz sertifikaların söz konusu olduğu durumları HSTS kullanarak engelledik. Peki browser güven zincirinde yer alan sertifika otoritelerinden biri hacklendi ve sitemiz adına bir sertifika imzalandı ise? Yukarıdaki "geçersizlik" şartlarından hiçbirinin şimdi söz konusu olamayacağı aşikar. Üstelik bu hiç de afaki bir senaryo değil. 2011 yılında Hollandalı sertifika dağıtıcısı DigiNotar hacklenip, akabinde 500 'e yakın sertifika imzalanması buna güzel bir örnek.
Bir sertifika otoritesi teknik olarak bir site için sertifika imzalarken, o site sahibini bundan haberdar etmek zorunda değil. Elbette ki bu eylem meşru bir eylem olmayacaktır ama teknik olarak buna sahip olduklarını bilmek gerekiyor. Certificate Transparency'nin varlığı ve Nisan 2018'den itibaren zorunlu olacak olması bunun en büyük delili.
Peki biz bunun önünü nasıl alacağız? Yani bizim haberimiz olmadan web sayfalarımız adına sertifika imzalanmasını nasıl önleyeceğiz? Maalesef sertifika imzalanmasını engelleyemeyiz. Ancak bu sertifikaların kullanılmasını engelleyebiliriz. Peki ama nasıl? Public Key Pinning teknolojisi ile. (Public Key Pinning teknolojisine browser desteğinin peyderpey ortadan kaldırılacağını Haftanın Hackleri'nin geçmiş sayılarında konu etmiş idik.)
Chrome'un 13 versiyonundan itibaren desteklenen bu özellik sayesinde siteler kendi sertifikalarının fingerprint yani hash değerlerini Public-Key-Pinning response headerı ile tarayıcılara bildirebiliyor.
Tarayıcılar bu sertifikaları hafızalarına alıp, bundan sonra herhangi bir istekte belirtilen sertifikalar dışında bir sertifika iddia edilirse, güvenli bağlantı kurmayı reddediyor, hatta report-uri ile belirtilen URL'e rapor ediyor.
İşte Public-Key-Pinning özelliği, güvenli iletişim için mecbur olunan otoritelerin, bir şekilde sahte sertifika imzalamaya zorlandığı durumlarda, kullanıcı ve sitelerimizi korumamızı sağlıyor. Deprecate edilmesi durumunda ya CA'ların CAA DNS entrysinde izin verilen otorite tercihine saygı duymalarını bekleyeceğiz ya da Certificate Transparency listesini kontrol ederek sitemiz adına imzalanan bir sertifika olup olmadığını crt.sh sitesi üzerinden kontrol edeceğiz. Nisan 2018'den itibaren Google imzalanacak olan her sertifikanın bu listede yer almasını, aksi takdirde browser tarafından bağlantı krumanın reddedileceğini belirtiyor. 2018'den önce sizin adınıza, örneğin 10 yıllık bir sertifika imzalandı ise bu tarz durumları da Expect-CT headerını enforce modunda set ederek engelleyebilirsiniz.
Bu iki zorlayıcı güvenlik headerının temel dayanağı max-age'de belirtilen (saniye cinsinden) süre zarfında browserı belirli davranışları zorlamaları. max-age süresi dolduğunda ise bu güvenlik headerlarının bir zorlayıcılıkları kalmıyor. Bu sebeple her yanıtta HSTS ve HPKP headerlarını tekrar tekrar döndürerek saniye cinsinden olan bu max-age süresini güncellemek gerekiyor.
Herhangi bir şekilde bu kayıtlar silinir veya süresi dolarsa bu katı güvenlik mekanizmasının bir yaptırımı kalmayacağı aşikar. Silinir mi dedik? Evet!
Londra'da gerçekleşen Black Hat 2017 konferansında yer alan bir sunuma göre tüm majör browserlarda, yani Firefox, Google, Edge/IE, HSTS listesini, listenin fiziksel limitlerini zorlayarak silebilmek ya da devre dışı bırakabilmek mümkün.
Google Chrome browserlarında HSTS ve HPKP listelerini chrome://net-internals/#hsts adresinden sorgulayabiliriz. Firefox'ta ise HSTS ve HPKP listesine ulaşmanın bir yolu yok. Ancak araştırmacıların çalıştığı Eleven Paths firmasının geliştirdiği PinPatrol benzeri pluginler yolu ile bu listeye ulaşabilirsiniz.
Burada ilginç bir ayrıntı ile karşılaşıyoruz. Firefox HSTS ve HPKP listelerini yönetmek için 1024 satır ile sınırlanmış bir TXT dosyası kullanıyor. PinPatrol' un Firefox eklentisi de bu TXT dosyasını görüntülüyor.
İlk bakışta normal bir kullanıcı için 1024 adet entrynin fazlasıyla yeterli olduğunu düşünebilirsiniz. Oysa limitleri zorlamak isteyen bir saldırgan için bu değer, yeni saldırılar için bir saldırı vektörü olarak kullanılabilir.
Peki ama nasıl?
1024'den fazla kayıt girildiğinde, Firefox yeni kayıtlara yer açmak için listede yer alan eski kayıtları siliyor. Ama burada kullandığı ilginç bir ayrıntı var: Score değeri.
Score değeri bir sitenin farklı günlerde, bir kullanıcı tarafından kaç kez ziyaret edildiğini gösteren bir değer. Örneğin site bir kullanıcı tarafından ilk kez ziyaret ediliyor ya da sitenin set ettiği değerler expire oldu ise bu değer 0 olarak set ediliyor. Bir sonraki gün tekrar ziyaret edilirse bu değer (Score değeri) 1 olarak güncelleniyor. Sonraki bir ziyarette ise 2 olarak güncelleniyor. Kullanıcı bir siteyi her ziyaret ettiğinde bu değer güncelleniyor ve browser 1024 entry'e ulaştığında, yeni entrylere yer açmak için Score'u en düşük olan kayıt listeden siliniyor.
Araştırmacıların Bettercap Javascript'i kullanarak yaptıkları araştırmaya göre *.cloudpinning.com/headers.php sayfasına farklı subdomainler yolu ile yaptıkları isteklere döndürülen HSTS headerları ile listenin saniyeler içerisinde 1024 limitine ulaşması sağlanıyor. Böylece Score 'u 0 olan kayıtlar bu listeden silinmiş oluyor.
Peki Score'u 1 olan siteler de silinebilir mi? Araştırmacılar, aynı saldırıyı bir sonraki gün de tekrarlayarak cloudpinning.com'a ait subdomainlerin listedeki Score'unu 1 puan daha yükselterek, bu şekilde limitleri zorlayarak eski kayıtların 0 ve 1 Score'una sahip kayıtların silinmesini sağlıyor.
Bir sonraki gün saldırganın aynı vektörü kullanması size gerçek dışı mı geliyor? Araştırmacılar bütün gün şansın yaver gitmesini beklemek istemeyenlere Black Hat 2014'de Jose Selvi tarafından sunulan "Bypassing HTTP Strict Transport Security" araştırmasına konu olan, bazı Mac ve Linux makinelerinde zamanı hızlandırmaya yarayan NTP MiTM aracı Delorean'ı öneriyorlar. (Delorean ismini meşhur Geleceğe Dönüş filminden hatırlayan kaç kişiyiz? :) )
Kayıtlar silinince ne oluyor?
HSTS ve HPKP headerlarının hükümranlığı ancak listeye kayıt edilmeleri ve max-age süresince idi. Dolayısı ile listeden silindiklerinde artık browser için bir zorlayıcılıkları kalmayacak, dolayısı ile saldırgan hiçbir engele takılmadan MiTM saldırıları gerçekleştirilebilecek.
Peki Chrome ve Edge'de Durum Nedir?
Chrome'da Score benzeri bir konsept ve limit yok. Chrome HSTS ve HPKP değerlerini bir JSON (C:\Users\USERNAME\AppData\Local\Google\Chrome\User Data\Default\TransportSecurity) dosyasında saklıyor. Eğer bit MiTM saldırısı ile ya da bir sunucudan dönen yanıtlarda bu dosyaya fazla sayıda kayıt girilirse Chrome herhangi bir limit olmadan kayıtları yazmaya devam ediyor.
Saldırganların Chrome'daki yaklaşımları ise binlerce istek yapmak ve headerların izin verdiği en üst limitte HSTS ve HPKP headerı set ederek bu dosyayı doldurmak. Peki ya sonuç? 10 dakika sonra JSON dosyasının 500 MB boyutuna eriştiğini ve Chrome'un donduğunu görebilirsiniz. Yeniden başlatıldığında dahi Chrome kullanılamayacak derecede yavaşlayacaktır.
Böylesi bir durumda ise yeni bir kayıt bu dosyaya set edilemeyecektir. Kullanıcıya kalan tek seçenek ise, içerdiği geçerli değerlerle birlikte tüm dosyayı silmek. Tahmin edersiniz ki bu kullanıcının valid sitelere kuracakları bağlantının da HSTS zorlamasından azade olmasına neden olacak.
IE/Edge
IE ve Edge browserları için HSTS listesini yöneten ve HttpIsHostHstsEnabled ismi ile çağrılan API ya da fonksiyon WININET.DLL kütüphanesinde bulunuyor. Fakat maalesef resmi bir dökümantasyonu yok.
Microsoft HSTS datasını Extensible Storage Engine (ESE) adı verilen bir database'de tutuyor ve bu database'in kullandığı data, kullanıcı profil dizini altındaki WebCache dizininde WebCacheV01.dat adı ile saklanıyor.
Araştırmacılar tersine mühendislik mesaisi gerektiren ayrıntıların araştırmanın kapsamı dışında olduğunu belirterek, o meseleye hiç el atmamışlar. Ancak bir takım davranış anomalilerini de kayda değer bularak raporda paylaşıyorlar:
Araştırmada özetle HSTS'in IE/Edge browserda beklendiği gibi çalışmadığı, verilerin tutulduğu tablonun sadece popüler domainler için işlem yaptığını belirtiyorlar.
Bir PoC olarak da araştırmada kullanılan test sitesine https://www.cloudpinning.com 131 kez istek yaptıklarını tarayıcı ve hatta bilgisayarı yeniden başlatmalarına rağmen HSTS tablosunda hiçbir değişiklik göremediklerini not ediyorlar.
Peki, çözüm nedir?
Teoride her şey çok güzel. Peki bağlantıyı dinleyen bir saldırgan HSTS headerının ya da HPKP headerının set edilmesini engellerse? Ya da yukarıda sözünü ettiğimiz client-side saldırılardan biri ile HSTS/HPKP kayıtlarının silinmesine yol açarsa?
Buradan doğacak riskleri engellemek için tarayıcılara içkin olarak gelen preload listeleri yordamıyla, işimizi şansa bırakmaktan kurtuluyoruz. Sitemizi preload listesine ekleyerek, sitemizle daha önce hiç bağlantı kurulmamış ve HSTS talimatı alınmamış bile olsa, ilk bağlantının güvenli bir yoldan kurulmasını sağlıyoruz. Ayrıca dinamik olarak oluşturulan listeler yerine, preload özelliği sayesinde browserlarla birlikte deploy edilen HSTS listesine sitemizin de dahil edilip, HSTS'in uygulanmasını sağlayabiliriz.
Bunun belirli şartları var:
- Öncelikle geçerli bir SSL sertifikasına sahip olmalıyız.
- HTTP'den HTTPS'e redirect ederken aynı host'u kullanmalıyız. (Yani HTTPS trafiği example.com için secure.example.com üzerinden değil, yine example.com üzerinden devam etmeli).
- www subdomain'i başta olmak üzere, tüm altdomainlerin güvenli bağlantı üzerinden sunuluyor olması,
- Base domain (ana) domainden güvenli bağlantı üzerinden sağlanan HSTS headerımızdaki max-age değerinin en az 18 hafta yani 10886400 saniye olarak set edilmesi, includeSubdomains ve preload seçeneklerinin HSTS headerında bulunması gerekmektedir:
Strict-Transport-Security: max-age=10886400; includeSubDomains; preload
Araştırmanın ayrıntılarına ulaşmak için lütfen tıklayınız.
vBulletin'de İki Kritik Zafiyet
vBulletin aralarında Alexa Top 1 Milyon ve Fortune 500 şirketlerinin de olduğu pek çok web sitesi tarafından kullanılan popüler bir forum scripti.
Bağımsız bir araştırmacının Beyond Security's SecuriTeam Secure Disclosure programı kapsamında bildirdiği rapora göre vBulletin LFI yolu ile komut çalıştırma ve dosya silme gibi iki kritik zafiyet içeriyor. Araştırmacıların 21 Kasım tarihinden bu yana vBulletin yetkililerine ulaşmaya çalıştıklarını fakat yanıt alamadıklarını belirtmeleri raporun en dikkat çekici yanı.
Doğal olarak zafiyet için yayınlanmış bir yama da yok. Biz sadece vBulletin'deki LFI zafiyetinin ayrıntılarını paylaşacağız.
Araştırmacılar routestring= parametresi yoluyla sunucuda bulunan dosyaların görüntülenebildiğini belirtiyorlar. Güvenlik terminolojisinde LFI adını alan bu zafiyetin ayrıntıları için, yine Netsparker Türkiye Blogu'nda yayınladığımız LFI, RFI Güvenlik Zafiyetleri Bağlamında PHP Stream Wrapper'ları başlıklı yazımıza göz atabilirsiniz.
Zafiyetin ayrıntıları ise şu şekilde:
index.php üzerinden gönderilen routeString parametresi şayet, '.gif', '.png', '.jpg', '.css' veya '.js' değerlerinden birini (/includes/vb5/frontend/routing.php satır 84) ve "/" (aynı dosya, satır 234) karakterini içermiyorsa legacy() isimli fonksiyona parametre olarak gönderiliyor. (/vb5/frontend/controller/relay.php)
Araştırmanın not ettiğine göre "/" karakteri engellendiğinden, Linux sunucularda current directory'i değiştirmek mümkün değil, fakat vBulletin'in kurulu olduğu sistem şayet Windows ise dizin seperator olarak backslash (\) kullanılabileceğinden zafiyet exploit edilebilecektir.
/index.php?routestring=.\\
LFI'da amaç local bir dosya yardımı ile code execute edebilmektir. Bu yanıyla, dosya içeriklerinin raw hallerini görmeye dayanan directory traversal'dan ayrılıyor. Saldırgan sunucudaki local dosyaları okuyabildiğine göre, kendisine PHP kodu execute edebilecek bir girdi noktası bulmak zorunda.
Apache access.log bu girdi noktalarından biri olabilir. Kullanıcının siteye olan tüm erişimlerinin loglandığı bu dosyaya kayıt edilen bilgilerden biri de kullanıcının istek yaptığı URL'dir.
Kullanıcının aşağıdaki gibi URL ile istek yaptığını varsayalım:
/?LogINJ_START=<?php phpinfo();?>LogINJ_END
acccess.log dosyasına bu URL kayıt edilecektir. Dolayısıyla LFI zafiyeti vasıtası ile access.log okunduğu takdirde <?php phpinfo();?> kısmı sunucu tarafından yorumlanıp, ekrana phpinfo() fonksiyonunun çıktısı basılacaktır.
/index.php?routestring=\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\xampp\\apache\\logs\\access.log
Zafiyet ile ilgili ayrıntılar için lütfen tıklayınız.
Güvenlik Araştırmacıları Biraz Yaratıcı Olmaya Ne Dersiniz?
Güvenlik söz konusu olduğunda hepimiz aynı mottoyu kullanırız: Kullanıcıdan alınan dataya güvenme!
Peki ya sistemin iletişimde olduğu diğer unsurlar? Servisler, sunucular, dosya sistemleri? İşte bütün bunlar, ya da daha genel anlamıyla second order zafiyetler hayal gücümüzün sınırlarını zorluyor.
19 Aralık'ta yayımladığı blog postuyla Roberto Salgado da işte bu yüzden güvenlik araştırmacılarını daha yaratıcı olmaya, ayrıntıda gizlenen şeytanların farkına varmaya davet ediyor. Üstelik iddiasını ispat eden üç parlak örnek ile!
Araştırmacı ilk örnekte PowerDNS web arayüzünde gösterilen DNS sorguları üzerinden nasıl XSS payloadu enjekte edebildiğinin örneğini veriyor:
Araştırmacının ikinci örneği ise Symantec'e 3 yıl önce raporlanan, SSL Tester toolundaki bir zafiyet.
Common Name (CN) 'ine bir XSS payloadu yerleştirdiği sertifikayı test için web arayüzünden yükleyen araştırmacı, sertifika bilgileri ekrana basılır basılmaz XSS payloadunun çalıştığını görüyor:
Araştırmacının verdiği son örnek ise CERN Bilgisayar Güvenliği Departmanı tarafından geliştirilen RATS (Rough Auditing Tool for Security) uygulamasından. 2013 'den beri güncelleme yapılmayan program bir statik kod analizi programı. Analiz sonucunda HTML formatında rapor oluşturabilen uygulamanın bu özelliği bir saldırı vektörü olarak kullanılarak XSS payloadu enjekte ediliyor.
Görüldüğü gibi saldırgan işletim sisteminde XSS payloadlarını dosya isimleri olarak kullanıyor. ls -l yani listeme komutu verildiğinde açıkça görülüyor.
Kıssadan hisse:
- Girdiler her zaman HTTP istekleri üzerinden gelmez.
- Pratik olarak, her bir noktadan dosya sistemi, log, API mesajları, veritabanı kayıtları saldırı gelebileceği hesap edilmeli.
- Bir girdi noktasından aldığı değeri, başka bir kontekste kullanırken mutlaka girdi ve çıktı denetimi yapılmalı.