XSS HTTP response’un Body kısmında gerçekleşir. Buradaki dataya odaklan. Hedef, arkadaki sistem değil onu kullanan kişiler aslında.
-
Bir HTTP response’u 3’e ayrılır:
- CSS : Kaşının, gözünün, teninin rengini verir.
- HTML : Senin iskeletindir.
- JavaScript : Vücudunu hareket ettirmeni sağlar. Biz de hareket kısmıyla ilgileniyoruz.
-
Response’un içerisinde kontrol edebildiğin bir değişkeni(değerini kendin belirleyebildiğin), browser’a geri gönderilen HTML içeriğin bir kısmında kullanılıyor.
-
Search kısmı olur, URL’in keywork kısımları olur, input edebildiğin her yer olabilir.
-
Browser, gelen HTML’i parse ediyor ve bir tane structure oluşturuyor. JS ile ilgili kısımları JS interpreterine veriyor, CSS kodlarını çalıştırıyor ve ortaya bir tane DOM oluşturmuş oluyor.
-
Response’un içerisindeki HTML içerik browser, browser bir yazılımdır,için bir input kaynağıdır. Browser’a giden HTML içeriğindeki taglerin manipülasyonuyla uğraşmaktayız.
-
XSS payloadımızı input olarak verdiğimizde(search kısmı bile olabilir bu), backend bunu input olarak alacak ve response içerisine data olarak bu payloadı eklemiş olacak. Request gittiği zaman web application bir view oluşturacak.
- Browser bu payloadı çalıştırıp çalıştırmaması gerektiği hakkında bilgi sahibi değildir.
-
XSS saldırısına input olarak şöyle başlayacaksın:
mdi'"><
-
yazıp dönen cevabın içinde mdi geçtiği taglere bak.
-
Browser tarafına bunun data olarak kullanılması gerekirken, tag olarak kullanabilme imkanı ortaya çıkıyor.
<script>alert(1)</script>
- data olarak gönderdiğimiz verinin, browsera aynı şekilde geri dönmesi halinde burada anlamalısın ki < tagi browser için başka bir anlam ifade ediyor.
- Bu gönderilen yazı backend tarafında data olarak kalıyor ama tekrar browser’a response olarak geri döndüğünde browser bunu artık tag olarak yorumluyor ve XSS doğuyor.
-
Xss ile pencere içerisinde yapamayacağın şey neredeyse yoktur. Tüm fonksiyonları çağırabilirsin. Resmen adamın mouse, klavyesini kontrol edebilir hale geliyorsun.
-
Beef adında opensource XSS exploitation frameworkü var. Burada kurbanın kamerasını kullanarak fotoğraf çekmeni sağlayan fonksiyonlar bile var, chrome extensionu kurdurtabiliyorsun, screenshot alabiliyorsun...
- Bu aracı kullanarak cookie’leri her zaman çekemeyebilirsin. HttpOnly diye bir mevzu var; JS kodlarının Cookie’yi manipüle etmesini engelliyor.
- Bunlardan korktuğumuz için XSS çıkmasını istemiyoruz.
-
MDI bir e-ticaret sitesinde XSS bulduğunda eğer URL checkout sayfası ise, kredi kartı ödeme formunun formidsini alıp, oraya girilen tüm formid’lerini çeker.
-
Mesela facebookta bir XSS çıktığında, adam gelip zafiyeti tetikletip bütün chat historyini çekebilir.
-
XSS denildiği zaman aklına Client side gelmesi gerekiyor. Hikaye hedef sistem değil, onu kullanan insanları hedeflemekten geçiyor.
-
XSS payloadın her zaman response’da yansımaz. Yansıyorsa —> Reflected XSS
-
Başka kullanıcıları da etkilemek istiyorsan URL shortener sitelerini kullanarak tetikletebilirsin. Yani olay şu: bir kullanıcı bu linke tıklıyor ve hedef websitesine(bir e-ticaret sitesi olabilir) gidiyor. Browserın başı kel mi giderken de bütün cookieleri ekliyor. Tüm cookieleri eklediği için o web sitesi için sen Mehmet D. İnce kullanıcısısın. Sonrasında bu adam bir script çalıştırmak istiyor, requestini atıyor, response Body’si içerisine de bu XSS payloadı yerleşmiş oluyor. Bu XSS payloadı ile istediğin şeyi yapabilir hale geliyorsun.
-
XSS payloadın her zaman response içerisinde yansımaz, DB’e kaydedilebilir. Diğer kullanıcılar da bu veriyi DB’den çekip browser da bunu yorumlayınca sömürülebilir. Böylece Stored XSS ortaya çıkar.(Stored XSS)
-
Browserlar “textarea” içerisindeki scriptleri çalıştırmaz. Senin de bu scripleri nereye yazacağın çok önemli.
- Saldırı kodunun textarea’yı kapatma ile başlaması gerekiyor.
-
Kendinden başkasına etki ettiremiyorsan Self XSS olmuş oluyor
-
Web sitesinin başka bir web servisinden gelen veriyi encoding yapmadan getiriyorsa orada Stored XSS çıkabilir. Facebook örneği (1:32:00)
Sadece form alanına girdiğin bilgilerle XSS yapmayı düşünüyorsan XSS konusunda başarısız olursun. Facebook örneğinde dropbox ile dosya yüklediğinde adam dosya ismini encoding yapmıyor ve XSS çıkıyor orda.
- <> tagların olabilmesi için bu işaretlerin olması gereklidir. Bunlar olmazsa asla XSS yapamazsın.
- Encode edebilirler < ve > olarak.
- Bu tagin value attribute’unda olduğun için XSS oluşmaz(Mehmet kısmı.)
- Öncelikle “ koyarak bu attributeun tanımını bitirmelisin. Sonrasında kendi tagini açıp scriptini yazabilirsin.
- Encode edilse bile kendi attribute unu oluşturup script çalıştırabilirsin :
- <> encode edilmeli VE “ ‘ ` encode edilmeli!!
- Encode ediliyorsa zaten input tagi olduğu için aşağıdaki payloadı kullan:
- id kısmına alert(1) göndermen yeterli olur XSS tetiklemek için.
- a href içine USER_DATA durum ile karşılaşırsan gidip JS’in browserlarda protocol handler olduğu durumu tetikleyebiliyorsun.
Nasıl çözülür? : Input Validation VE Output Encoding Input’u encode etmek yanlış bir yaklaşım olur. DB’e kaydederken datayı bozmuş olursun veya başka bir ekip bu datayı kullanmak için decode etmesi gerekir.
- Normalde sen böyle encode etmezsen sadece Browser’ın temelde yaptığı encodingleri sağlamış olursun. Hangi contextler için hangi karakterler encode edilmesi gerekiyor ise bunuları encode eden yardımcı methodları var bunlar kullanılmalı.
- Burada Asla XSS oluşmaz ama gidip yazılımcı Command line yaparsa işi biter.
- %0a new line demektir ve hiçbir Template Engine whitespace karakterleri default olarak encode etmez ve XSS payloadımızı istediğimiz gibi yazabiliriz.
- Bu yüzden context base encoderları anlamak ve öğrenmek önemli.
- Bu kodun arkada yaptığı şey; location hash üzerinden gelen veri hiçbir zaman backend’e gitmez. Yani backend XSS’in yaşandığını. Ama JS buradaki location hashi input olarak kullanmakta.
- Burada bir XSS ortaya çıkıyor: Payload kodu:
- Kullanıcının inputunu şu şekilde tutuyor —> inputa = ’-alert(1)-’ yazdığında tetiklenecektir.
- startTimer içerisinde DOM’u manipüle edebilen bir fonksiyon kodu görmedik. Şu yapı çalışacaktır:
NOT: HTTP içerisindeki + ifadeleri özellikle Query Stringde HTTP’nin ilk satırını GET’in bozduğu için boşluğu encode etmek gerek, + kullanmıyoruz da - kullanıyoruz.
- Location hashden bir path alıyor sonra “includeGadget” ile bu pathi yüklüyor. Eğer verilen input http ile başlarsa hata verir. http isteklerini göndermeni engelliyor kod.
data:text/javascript,alert(1)
- URL’deki # burada js’in kodu anlamlandırmasını sağlıyor.
- DOM based xsslerde hangi fonksiyonların engellendiğini filtrelendiğini kolayca anlayabilmek için url kısmında kendi fonksiyonunu yazıp bakabilirsin