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
Überprüfen Sie, ob irgendein Wert, den Sie kontrollieren (Parameter, Pfad, Header?, Cookies?) im HTML reflektiert oder von JS-Code verwendet wird.
Finden Sie den Kontext, in dem es reflektiert/verwendet wird.
Wenn reflektiert:
Überprüfen Sie, welche Symbole Sie verwenden können und bereiten Sie je nach dem die Payload vor:
In rohem HTML:
Können Sie neue HTML-Tags erstellen?
Können Sie Ereignisse oder Attribute verwenden, die das
javascript:
-Protokoll unterstützen?Können Sie Schutzmaßnahmen umgehen?
Wird der HTML-Inhalt von einer Client-seitigen JS-Engine (AngularJS, VueJS, Mavo...) interpretiert, könnten Sie eine Client Side Template Injection ausnutzen.
Wenn Sie keine HTML-Tags erstellen können, die JS-Code ausführen, könnten Sie eine Dangling Markup - HTML scriptless injection ausnutzen?
Innerhalb eines HTML-Tags:
Können Sie in den rohen HTML-Kontext wechseln?
Können Sie neue Ereignisse/Attribute erstellen, um JS-Code auszuführen?
Unterstützt das Attribut, in dem Sie gefangen sind, die Ausführung von JS?
Können Sie Schutzmaßnahmen umgehen?
Innerhalb JavaScript-Code:
Können Sie das
<script>
-Tag entkommen?Können Sie den String entkommen und anderen JS-Code ausführen?
Ist Ihre Eingabe in Template-Literalen ``?
Können Sie Schutzmaßnahmen umgehen?
Javascript Funktion, die ausgeführt wird:
Sie können den Namen der auszuführenden Funktion angeben. z.B.:
?callback=alert(1)
Wenn verwendet:
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:
Reflektierte Werte
Um eine XSS erfolgreich auszunutzen, müssen Sie zuerst einen Wert finden, der von Ihnen kontrolliert wird und in der Webseite reflektiert wird.
Zwischendurch reflektiert: Wenn Sie feststellen, dass der Wert eines Parameters oder sogar der Pfad in der Webseite 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 wird 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 der 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:
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 [...]
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="
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 wieonclick=
kontrollieren, können Sie es dazu bringen, beliebigen Code auszuführen, wenn es angeklickt wird. Ein weiteres interessantes Beispiel ist das Attributhref
, wo Sie dasjavascript:
-Protokoll verwenden können, um beliebigen Code auszuführen:href="javascript:alert(1)"
Wenn Ihre Eingabe innerhalb von "nicht ausnutzbaren Tags" reflektiert wird, könnten Sie 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:
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:
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:
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 Parameterwert 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:
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:
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.
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:
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 zu reflektieren 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:
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:
Blacklist Bypasses
Wenn eine Art von Blacklist verwendet wird, könnten Sie versuchen, sie mit einigen einfachen Tricks zu umgehen:
Length bypass (kleine XSS)
Weitere kleine XSS für verschiedene Umgebungen Payloads sind hier zu finden und hier.
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, schauen 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):
Stilereignisse
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?
'-alert(1)-'
';">Zurück</a>
Beachten Sie, dass jede Art von HTML-Kodierung gültig ist:
Beachten Sie, dass die URL-Codierung ebenfalls funktioniert:
Umgehung von Innenereignissen mit Unicode-Kodierung
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.
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>
)
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.
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.
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:
Reverse Tab-Nabbing
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:
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:
XSS in "Unexploitable tags" (hidden input, link, canonical, meta)
Von hier ist es jetzt möglich, versteckte Eingaben zu missbrauchen mit:
Und in meta-Tags:
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:
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 Stil-Attribut filtert, kannst du CSS-Styling-Gadgets verwenden, also 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:
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:
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:
Kodierte Codeausführung
Unicode Encode JS-Ausführung
JavaScript-Umgehung von Blacklist-Techniken
Strings
Spezielle Escapes
Raumersetzungen innerhalb von JS-Code
JavaScript-Kommentare (aus JavaScript-Kommentare Trick)
JavaScript-Zeilenumbrüche (aus JavaScript-Zeilenumbruch Trick)
JavaScript Leerzeichen
Javascript innerhalb eines Kommentars
JavaScript ohne Klammern