Merhaba ben crackmeci bu konumda sizlere xss açığının oluşum sebebi ve nasıl kapatılabileceğini göstereceğim.
Xss Açığı Nedir?
XSS açılmış haliyle de Cross Site Scripting anlamına gelir. Kısaca özetleyecek olursak HTML veya JS kodlarının sayfaya gömülerek kullanılması diyebiliriz. Yani şimdi diyebilirsiniz, "Altı üstü HTML ve JS kodu çalıştırıyoruz Linux komutları çalıştırmıyoruz bu bizim ne işimize yarayacak?" Şimdi şöyle bir senaryo düşünelim siz hacksite.com sitesinin yöneticisisiniz(adminisiniz) bir üyeniz size email yoluyla hacksite.com/index.php?search=<script>alert("Hacked by xxxhacker")</script> şeklinde bir mesaj gönderdi ama mesaj bu şekilde değil de link kısaltılmış şekilde geldi siz de bir merakla girip baktınız oradaki kod şuanda sadece basit bir alert kodu olduğu için sorun teşkil etmiyor ancak bu kod cookieleri çalmaya da yönelik olabilirdi. Oturum bilgilerinizin çalınması sizin için büyük sıkıntılar doğurabilirdi.
Şimdi de XSS'in türlerinden bahsedelim.
Reflected XSS
Demin search parametresine bir javascript değeri vermiştik ancak bu kod arama sayfasında çalıştığı için herhangi bir veritabanına kaydedilmedi zaten kim yapılan aramaları veri tabanına kaydeder ki İşte bu xss türünde bir parametre yerine kendi istediğimiz şeyi yazıyoruz ve o kod çalışıyor.
Stored XSS
Mesela sitenizde bir ziyaretçi defteriniz var buraya gelen ziyaretçiler mesaj bırakıyor istenen bilgiler de şunlar olsun: isim,soyisim,email,mesaj. Normal ziyaretçiler bu bilgileri girip mesajını bırakıyor ancak kötü niyetli bir kullanıcı geldiğinde buraya ad yerine <h1>XXX Hacker</h1> şeklinde bir değer girerse ismi diğer kullanıcılara göre daha büyük gözükecektir veya <script>alert("Hacked by xxxhacker")</script> şeklinde bir değer girerse sayfaya giren herkes "Hacked by xxxhacker" mesajını görecektir. O yüzden bu açık Reflected Xss'ye göre bir tık daha tehlikelidir.
Dom XSS
Bu XSS türleri arasında en tehlikelisidir çünkü kod direkt dom'a gömülür yani CTRL+U veya öğeyi denetle(inspect) yapınca gözükmez bu sebeple kurban herhangi bir atağa hedef olduğunu fark etmez. DOM dediğimiz şey Document Object Model demektir yani "Belge Nesne Modeli" gibisinden bir anlama geliyor. Bu model javascript ile html arasında bağlantı kuruyor. Mesela Javascriptte bir html öğesi seçileceği zaman document.querySelector(".element"); kullanılıyor DOM sayesinde Html üzerindeki öğeyle bağlantı kuruluyor.
Şimdi bir Stored XSS atağı gerçekleştirelim bunun için localhostta bir sayfa hazırladım.
Görüldüğü üzere sayfamızda daha önce gelen üç mesaj bir tane de form var bu form üzerinden yeni mesajlar gönderebiliyoruz. Bir de sayfamızın kaynak kodunu inceleyelim.
Kaynak koda baktığımız zaman $adsoyad, $email , $mesaj değişkenlerine yani formdan alınan verilere herhangi bir filtre uygulanmamış bu sebeple eğer ben mesaj yerine <h1>...</h1> şeklinde bir mesaj yazdığımda <h1> temizlenmeyecek bu sayede büyük bir mesajım olacak. Hadi deneyelim!
Mesajımızı ayarladık şimdi gönderelim.
Evet görüldüğü üzere sistemde herhangi bir filtreleme yapılmadığı için <h1> tagı direkt çalıştı ve bu sayede diğer mesajlara göre daha büyük bir mesajımız oldu. Bunun yerine <script> kodlarının da çalıştırılabileceği hesaba katılıp bu açık küçümsenilmemelidir.
Peki bunu nasıl kapatabiliriz?
Şimdi trilyonlarca decode encode yöntemi olduğu için saldırgan eğer niyetliyse bir şekilde kodu çalıştırabilir. Ama kullanacağımız filtreleme metotları yardımıyla saldırıların önünü büyük ölçüde kesebiliriz. Genelde çoğu sayfada htmlspecialchars kullanmanız yeterli diyorlar ancak ben internetten bulduğum bir hazır fonksiyonu kullanmayı tercih ediyorum.
Fonksiyonumuz bu. Bence bu fonksiyon siteniz aşırı büyük değilse belli bir yere kadar yeterli gelecektir. Şimdi deminki örneğimizdeki koda bu fonksiyonu ekleyelim bakalım çalışacak mı.
Değişiklik yaptığım tek kısım bu olduğu için tüm kodu atma gereği duymadım. Şimdi bir xss daha deneyelim ziyaretçi defterimize.
Bu sefer deminkinden farklı olarak bir JS kodu denedim şimdi sonuca bakalım.
Görüldüğü üzere mesaj boş ve sayfaya girince bir alert vermedi çünkü kodu temizledi. Normalde bu verinin eklenmemesi lazım çünkü genelde girilen değerlerin boş olup olmadığını kontrol ediyoruz ama buradaki konsept o olmadığı için yapmadım. Şimdi bir de <h1> tagini deneyelim bakalım o çalışacak mı.
Görüldüğü üzere mesajımız hazır hadi gönderelim.
Mesajımız gönderildi ancak mesajımızın etiketi yani <h1> kaldırıldı. Bu sayede bu mesaj da diğer mesajlarla aynı boyutta oldu.
Evet, bir konumun daha sonuna geldim okuduğunuz için teşekkür ederim.
(Not: Normalde reflected ve dom xss türleriyle ilgili de örnek yapacaktım ancak konu fazla uzamasın diye burada kestim)
Xss Açığı Nedir?
XSS açılmış haliyle de Cross Site Scripting anlamına gelir. Kısaca özetleyecek olursak HTML veya JS kodlarının sayfaya gömülerek kullanılması diyebiliriz. Yani şimdi diyebilirsiniz, "Altı üstü HTML ve JS kodu çalıştırıyoruz Linux komutları çalıştırmıyoruz bu bizim ne işimize yarayacak?" Şimdi şöyle bir senaryo düşünelim siz hacksite.com sitesinin yöneticisisiniz(adminisiniz) bir üyeniz size email yoluyla hacksite.com/index.php?search=<script>alert("Hacked by xxxhacker")</script> şeklinde bir mesaj gönderdi ama mesaj bu şekilde değil de link kısaltılmış şekilde geldi siz de bir merakla girip baktınız oradaki kod şuanda sadece basit bir alert kodu olduğu için sorun teşkil etmiyor ancak bu kod cookieleri çalmaya da yönelik olabilirdi. Oturum bilgilerinizin çalınması sizin için büyük sıkıntılar doğurabilirdi.
Şimdi de XSS'in türlerinden bahsedelim.
Reflected XSS
Demin search parametresine bir javascript değeri vermiştik ancak bu kod arama sayfasında çalıştığı için herhangi bir veritabanına kaydedilmedi zaten kim yapılan aramaları veri tabanına kaydeder ki İşte bu xss türünde bir parametre yerine kendi istediğimiz şeyi yazıyoruz ve o kod çalışıyor.
Stored XSS
Mesela sitenizde bir ziyaretçi defteriniz var buraya gelen ziyaretçiler mesaj bırakıyor istenen bilgiler de şunlar olsun: isim,soyisim,email,mesaj. Normal ziyaretçiler bu bilgileri girip mesajını bırakıyor ancak kötü niyetli bir kullanıcı geldiğinde buraya ad yerine <h1>XXX Hacker</h1> şeklinde bir değer girerse ismi diğer kullanıcılara göre daha büyük gözükecektir veya <script>alert("Hacked by xxxhacker")</script> şeklinde bir değer girerse sayfaya giren herkes "Hacked by xxxhacker" mesajını görecektir. O yüzden bu açık Reflected Xss'ye göre bir tık daha tehlikelidir.
Dom XSS
Bu XSS türleri arasında en tehlikelisidir çünkü kod direkt dom'a gömülür yani CTRL+U veya öğeyi denetle(inspect) yapınca gözükmez bu sebeple kurban herhangi bir atağa hedef olduğunu fark etmez. DOM dediğimiz şey Document Object Model demektir yani "Belge Nesne Modeli" gibisinden bir anlama geliyor. Bu model javascript ile html arasında bağlantı kuruyor. Mesela Javascriptte bir html öğesi seçileceği zaman document.querySelector(".element"); kullanılıyor DOM sayesinde Html üzerindeki öğeyle bağlantı kuruluyor.
Şimdi bir Stored XSS atağı gerçekleştirelim bunun için localhostta bir sayfa hazırladım.
Görüldüğü üzere sayfamızda daha önce gelen üç mesaj bir tane de form var bu form üzerinden yeni mesajlar gönderebiliyoruz. Bir de sayfamızın kaynak kodunu inceleyelim.
Kaynak koda baktığımız zaman $adsoyad, $email , $mesaj değişkenlerine yani formdan alınan verilere herhangi bir filtre uygulanmamış bu sebeple eğer ben mesaj yerine <h1>...</h1> şeklinde bir mesaj yazdığımda <h1> temizlenmeyecek bu sayede büyük bir mesajım olacak. Hadi deneyelim!
Mesajımızı ayarladık şimdi gönderelim.
Evet görüldüğü üzere sistemde herhangi bir filtreleme yapılmadığı için <h1> tagı direkt çalıştı ve bu sayede diğer mesajlara göre daha büyük bir mesajımız oldu. Bunun yerine <script> kodlarının da çalıştırılabileceği hesaba katılıp bu açık küçümsenilmemelidir.
Peki bunu nasıl kapatabiliriz?
Şimdi trilyonlarca decode encode yöntemi olduğu için saldırgan eğer niyetliyse bir şekilde kodu çalıştırabilir. Ama kullanacağımız filtreleme metotları yardımıyla saldırıların önünü büyük ölçüde kesebiliriz. Genelde çoğu sayfada htmlspecialchars kullanmanız yeterli diyorlar ancak ben internetten bulduğum bir hazır fonksiyonu kullanmayı tercih ediyorum.
PHP:
function htmlclean($text){
$text = preg_replace("'<script[^>]*>.*?</script>'si", '', $text );
$text = preg_replace('/<a\s+.*?href="([^"]+)"[^>]*>([^<]+)<\/a>/is', '\2 (\1)',$text );
$text = preg_replace( '/<!--.+?-->/', '', $text );
$text = preg_replace( '/{.+?}/', '', $text );
$text = preg_replace( '/ /', ' ', $text );
$text = preg_replace( '/&/', ' ', $text );
$text = preg_replace( '/"/', ' ', $text );
$text = strip_tags($text);
$text = htmlspecialchars($text);
return $text;
}
Fonksiyonumuz bu. Bence bu fonksiyon siteniz aşırı büyük değilse belli bir yere kadar yeterli gelecektir. Şimdi deminki örneğimizdeki koda bu fonksiyonu ekleyelim bakalım çalışacak mı.
Değişiklik yaptığım tek kısım bu olduğu için tüm kodu atma gereği duymadım. Şimdi bir xss daha deneyelim ziyaretçi defterimize.
Bu sefer deminkinden farklı olarak bir JS kodu denedim şimdi sonuca bakalım.
Görüldüğü üzere mesaj boş ve sayfaya girince bir alert vermedi çünkü kodu temizledi. Normalde bu verinin eklenmemesi lazım çünkü genelde girilen değerlerin boş olup olmadığını kontrol ediyoruz ama buradaki konsept o olmadığı için yapmadım. Şimdi bir de <h1> tagini deneyelim bakalım o çalışacak mı.
Görüldüğü üzere mesajımız hazır hadi gönderelim.
Mesajımız gönderildi ancak mesajımızın etiketi yani <h1> kaldırıldı. Bu sayede bu mesaj da diğer mesajlarla aynı boyutta oldu.
Evet, bir konumun daha sonuna geldim okuduğunuz için teşekkür ederim.
(Not: Normalde reflected ve dom xss türleriyle ilgili de örnek yapacaktım ancak konu fazla uzamasın diye burada kestim)
Son düzenleme: