Einfacher Hack: So erhalten Sie Daten durch Cross Site Scripting Inclusion. Optimale Nutzung von XSS-Schwachstellen Xss-Noscript-Warnung

Was ist eine XSS-Sicherheitsanfälligkeit? Sollte ich Angst vor ihr haben?

Cross Site Scripting (kurz XSS) ist eine weit verbreitete Sicherheitsanfälligkeit, die viele Webanwendungen betrifft. Es ermöglicht einem Angreifer, schädlichen Code so in eine Website einzufügen, dass der Browser des Benutzers, der die Website besucht, den Code ausführt.

Das Ausnutzen einer solchen Sicherheitsanfälligkeit erfordert in der Regel eine gewisse Interaktion mit dem Benutzer: Entweder werden sie mithilfe von Social Engineering auf eine infizierte Site gelockt, oder sie warten einfach darauf, dass der Benutzer die Site selbst besucht. Daher nehmen Entwickler XSS-Schwachstellen häufig nicht ernst. Wenn sie jedoch nicht angesprochen werden, können sie eine ernsthafte Sicherheitsbedrohung darstellen.

Stellen wir uns vor, wir befinden uns im WordPress-Admin-Bereich und fügen neue Inhalte hinzu. Wenn wir hierfür ein für XSS anfälliges Plugin verwenden, kann dies den Browser dazu zwingen, einen neuen Administrator zu erstellen, Inhalte zu ändern und andere böswillige Aktionen auszuführen.

Durch Cross-Site-Scripting hat ein Angreifer heutzutage fast die vollständige Kontrolle über die wichtigste Software - den Browser.

XSS: Sicherheitsanfälligkeit bei Injektionen

Jede Website oder Anwendung verfügt über mehrere Einstiegspunkte - Formularfelder bis zur URL selbst. Das einfachste Beispiel für die Dateneingabe ist die Eingabe eines Benutzernamens und eines Kennworts in ein Formular:

Abbildung 1. Dateneingabeformular

Unser Name wird für zukünftige Interaktionen mit uns in der Datenbank der Site gespeichert. Wenn Sie sich auf einer Website angemeldet haben, haben Sie sicherlich eine persönliche Begrüßung im Stil von "Willkommen, Ilya" gesehen. Zu diesem Zweck werden Benutzernamen in der Datenbank gespeichert.

Eine Injektion ist eine Prozedur, bei der anstelle eines Namens oder Kennworts eine spezielle Zeichenfolge eingegeben wird, wodurch der Server oder Browser gezwungen wird, auf eine bestimmte Weise zu reagieren, die der Angreifer benötigt.

Cross-Site-Scripting bezieht sich auf eine Injektion, die Code einfügt, der im Namen einer Website Aktionen im Browser ausführt. Dies kann sowohl mit der Benachrichtigung des Benutzers als auch im Hintergrund ohne sein Wissen geschehen.

Abbildung 2. Ein visuelles Diagramm für Cross-Site-Scripting

Das einfachste Beispiel ist ein rudimentäres Skript, das ein Benachrichtigungsfenster anzeigt. Es sieht aus wie das:

Tabelle 1. Skript, das das Popup-Fenster aufruft

Dieses Skript ruft ein Fenster mit der Aufschrift "THIS IS XSS VULNERABILITY !!!" auf. Der Browser des Benutzers erkennt dieses Skript als Teil des legitimen Codes der Site und führt es aus.

Arten von XSS-Schwachstellen

Nicht alle XSS-Schwachstellen sind gleich, es gibt viele Arten. Hier sind die Typen und wie sie interagieren:

Abbildung 3. Arten von XSS-Schwachstellen


Sicherheitslücken durch serverseitigen Code (Java, PHP, .NET usw.):

Traditionelle XSS-Angriffe:

  1. Reflektiert (unbeständig). Ein reflektierter XSS-Angriff wird ausgelöst, wenn ein Benutzer auf einen speziell vorbereiteten Link klickt. Diese Sicherheitsanfälligkeiten treten auf, wenn von einem Webclient bereitgestellte Daten, meist in HTTP-Anforderungsparametern oder in HTML-Form, direkt von serverseitigen Skripten ausgeführt werden, um eine Ergebnisseite für diesen Client ohne ordnungsgemäße Verarbeitung zu analysieren und anzuzeigen.
  2. Gespeichert (persistent). Gespeichertes XSS ist möglich, wenn ein Angreifer bei jedem Zugriff auf die Originalseite schädlichen Code in einen Server einfügen kann, der im Browser ausgeführt wird. Ein klassisches Beispiel für diese Sicherheitsanfälligkeit sind Foren, in denen HTML-Kommentare zulässig sind.

Sicherheitslücken durch clientseitigen Code (JavaScript, Visual Basic, Flash usw.):

Auch als DOM-Modelle bekannt:

  1. Reflektiert (unbeständig). Wie auf der Serverseite ist der Angriff nur in diesem Fall möglich, da der Code vom Browser verarbeitet wird.
  2. Gespeichert (persistent). Ähnlich wie beim gespeicherten XSS auf der Serverseite wird nur in diesem Fall die schädliche Komponente auf der Clientseite mithilfe des Browserspeichers gespeichert.

Sicherheitslücken in der Infrastruktur (Browser, Plugins, Server usw.):

Sehr selten, aber gefährlicher:

  1. Clientseitige Infrastruktur. Dies tritt auf, wenn eine böswillige Komponente die Browserfunktionalität manipuliert, z. B. den XSS-Filter usw.
  2. Serverseitige Infrastruktur. Tritt auf, wenn der Webserver Anforderungen nicht korrekt verarbeitet und sie geändert werden können.
  3. Netzwerk. Tritt auf, wenn die Kommunikation zwischen einem Client und einem Server infiltriert werden kann.

Benutzerbedingte Sicherheitslücken:

  1. Selbst-XSS. Dies ist häufig das Ergebnis von Social Engineering, wenn ein Benutzer versehentlich schädlichen Code in seinem Browser ausführt.

Was ist die Gefahr von XSS?

Wie können Sie Ihre Site vor XSS schützen? Wie überprüfe ich den Code auf Schwachstellen? Es gibt Technologien wie die Sucuri Firewall, die speziell entwickelt wurden, um solche Angriffe zu vermeiden. Wenn Sie jedoch Entwickler sind, möchten Sie sicherlich mehr darüber erfahren, wie Sie XSS-Schwachstellen identifizieren und beheben können. Wir werden im nächsten Teil des Artikels über XSS darüber sprechen.

Jeder weiß seit langem, dass ein Angreifer mit XSS meistens versucht, ein Cookie an ein Opfer zu senden, CSRF-Token zu lesen, einen Phishing-Angriff auszuführen (indem er ein gefälschtes Anmeldeformular erstellt), eine Aktion im Namen eines Benutzers auszuführen und andere ähnliche Angriffe auszuführen (möglicherweise nicht) alle Möglichkeiten, aber dies sind die beliebtesten, die mir derzeit bekannt sind).

Der Zweck dieser Methode besteht darin, die Seiten im Namen des Benutzers zu überwachen, den er auf der angegriffenen Site aufruft, sowie seine Tastenanschläge zu überwachen (Sie können sich auch bewegen und mit der Maus klicken, aber für mich sind dies unnötige, nicht sehr nützliche Informationen, in den meisten Fällen sicher). ...
Nun zum maximalen Nutzen - ich glaube, der Algorithmus würde so aussehen:

  • cookies lesen und senden;
  • lesen und senden Sie den Rest der Informationen (IP-Adresse, installierte Plugins, Browserversion und -typ, Flash-Unterstützung, Silverlight-Unterstützung usw.) [optional]
  • wir bekommen Informationen über das interne Netzwerk, wir durchbrechen den Router [optional]
  • verschiedene Token lesen und senden [optional];
  • wir implementieren Phishing [optional];
  • etwas "von Hand" "durch den Benutzer tun [optional];
  • wir spionieren ihn weiterhin aus und extrahieren Informationen, bis er den Tab geschlossen oder die Site verlassen hat.

Alle optionalen Elemente in der Liste sollten abhängig von der Situation und den spezifischen Prioritäten für die mit XSS zu erreichenden Ziele ausgeführt werden. Sie können sich manchmal gegenseitig stören (wenn Sie versuchen, sie genauer zu kombinieren, nacheinander auszuführen) und die Wahrscheinlichkeit eines XSS-Ausnutzungsfehlers erhöhen.
Aber der erste und der letzte Punkt sollten auf jeden Fall immer befolgt werden. Eigentlich wird der Hauptteil des Artikels über den letzten Punkt aus dieser Liste sein.

Wir kommen zum Ziel.

Ich fange von weitem an: Über JavaScript ist es möglich, den Pfad in der Adressleiste zu ändern, ohne die Seite neu zu laden. Zum Beispiel, wenn der Benutzer die Seite unter geladen hat

http://site.com/some/path/to/page/


In der Adressleiste sieht der Inhalt dann wie folgt aus (ohne die Seite neu zu laden):

http://site.com/new-url/

http: //site.com/new-url/


Diese Funktion ist übrigens manchmal sehr nützlich, wenn die URL vor Benutzern (oder einer aufmerksameren Benutzerkategorie - Administratoren) ausgeblendet werden muss, nachdem sie auf den Link mit Reflected XSS geklickt hat, damit sie später nach dem Laden der Seite angezeigt wird in der Adressleiste fand nichts.

http: //site.com/search.php?q\u003d123

http://site.com/search.php?q\u003d123

http: //site.com/search.php?q\u003d123


wir werden ihm diese Gelegenheit nehmen.

Diese Technik hat jedoch noch interessantere und leistungsfähigere Anwendungen. Wir simulieren den Aufenthalt des Benutzers auf der Website, nachdem er auf den Link geklickt hat. Tatsächlich bleibt er die ganze Zeit auf derselben Seite. Zu diesem Zeitpunkt funktioniert ein Skript eines Drittanbieters, das Informationen extrahiert und an den Angreifer sendet. Auf diese Weise, XSS funktioniert so lange, wie der Benutzer dem Link in dieser Domain folgt .

Wir definieren die Idee.

Das allgemeine Funktionsprinzip lautet wie folgt: Wenn ein Benutzer eine Seite mit XSS besucht, erstellt das Skript einen Iframe mit derselben Adresse wie die Seite und "hängt" ihn an den Vordergrund. Der Benutzer hat den Eindruck, dass die Seite normal geladen wird, da Iframe nur im Code angezeigt wird Seiten.

Das Hilfsskript steuert die Logik des Spionage-Bots, dh es überwacht, wann sich die Adresse im Frame ändert, um sie in der Adressleiste zu ändern. Wenn sich jedoch in der neu geänderten Adresse des Frames eine andere Domäne befindet, können Sie sie auf einem neuen vlkadka öffnen, oder Sie müssen die Seite neu laden um nicht verbrannt zu werden.
Damit XSS momentan nicht mehr ausgeführt werden kann, muss der Benutzer die Seite entweder manuell aktualisieren (wenn XSS reflektiert wird und mit der POST-Methode übertragen wurde, wird das Update in anderen Fällen nicht gespeichert, und einige Browser können die POST-Anforderung jetzt beim Aktualisieren der Seite erneut senden) oder Schließen Sie die Registerkarte oder wechseln Sie zu einer anderen Domain (obwohl Sie in diesem Fall dennoch vermeiden können, die Kontrolle zu verlieren).

Wenn er zu einer Subdomain der angegriffenen Domäne wechselt, funktioniert die Auswahl des Angreifers, dh XSS, aber es besteht eine geringe Wahrscheinlichkeit, dass der Benutzer eine Diskrepanz zwischen der Adresse feststellt. Ich denke, dass hier je nach Situation, wenn beispielsweise die Domain google.ru angegriffen wurde, der Nutzer zum Cloud-Dateidienst von Google gegangen ist, der normalerweise in der Subdomain drive.google.ru liegt, und die Wahrscheinlichkeit, dass er den Haken beim Betrachten der Adressleiste bemerkt, ziemlich hoch ist , wenn er diesen Dienst oft nutzte... Andernfalls können Sie es riskieren. Wir müssen jedoch berücksichtigen, dass wir seine Daten nicht aus einem Frame mit einer Subdomain lesen können, da die Cross Origin-Richtlinie dies nicht zulässt. Aber wir können die Hauptdomäne in ihrem Namen im versteckten Modus ruhig erklimmen (weiter unten wird dies ausführlicher beschrieben).

Nur diese Methode hat Einschränkungen, nämlich - sie funktioniert nicht, wenn die Antworten des Webservers der Site einen Header enthalten X-Frame-Optionenmit Bedeutung VERWEIGERN... Aber ich persönlich habe solche Seiten nur ein paar Mal getroffen, jetzt sogar die Hälfte SAMEORIGINnicht ausgesetzt, geschweige denn volle Einschränkung durch VERWEIGERN.

Wir analysieren die Idee.

Jetzt erinnerten sich viele wahrscheinlich an eine so wundervolle Sache wie BeEF, die auch viele interessante Dinge enthält. Übrigens gibt es auch eine Option für die erzwungene Benutzerumleitung im Frame, aber die Adresse in der Adressleiste ändert sich nicht, was den Schreibtisch schnell verbrennen kann und diese Option für andere Zwecke ein wenig dient.
Im Allgemeinen hat BeEF'e fast alles, was Sie brauchen, und sogar viele zusätzliche Funktionen, aber ich persönlich wollte zusätzliche Funktionen, nämlich:

  • die Fähigkeit, den Code von Seiten, die dem angegriffenen Benutzer zur Verfügung stehen, in Echtzeit zu überwachen;
  • die Fähigkeit, alles zu sehen, was er auf dieser Site eingibt (von Login und Passwort bis zu Hotkeys und Nachrichten), dh Keylogger auf JS;
  • die Möglichkeit, Ihrem Bot JS-Befehle in Echtzeit zu erteilen, nachdem Sie den Code der empfangenen Seiten angezeigt haben;
  • die Fähigkeit, Befehle lokal dem Bot zu überlassen, so dass er sie dann „aufnimmt“ und ohne unsere direkte Teilnahme ausführt;
  • eine geringere Wahrscheinlichkeit, dass der Bot verbrannt wird, oder die Fähigkeit des Bots, sich vor neugierigen Blicken zu "verstecken";

Wie oben erwähnt, habe ich mich entschlossen, von BeEF eine coole Idee der Befehlsausführungswarteschlange auszuleihen. Zum Beispiel haben wir die Seiten analysiert, die der Bot geworfen hat, als ein privilegierter Benutzer mit gespeichertem XSS in sein Control Panel geklettert ist. Wir überlassen den Befehl dem Bot-JS-Code, wie beim nächsten Eingeben des Benutzers, drücken Sie diese Taste, schreiben Sie diesen Wert hier und so weiter. Wenn dieser Benutzer die Seite das nächste Mal besucht, liest der Bot die Befehle und führt sie aus, und wir müssen überhaupt nicht an seiner Spitze stehen - das ist sehr praktisch.

Grundsätzlich ist ein solcher Bot natürlich für Statusbenutzer einiger Websites gedacht, die über zusätzliche "Hebel" für die Inhaltsverwaltung, andere Benutzer usw. verfügen. Aus den Anforderungen an die Funktionalität geht hervor, dass Sie nicht auf eine Serverseite verzichten können.

Lassen Sie uns die Idee umsetzen.

Im Prinzip kann dieser Teil des Artikels übersprungen werden, da er lediglich den Prozess der Implementierung des gewünschten Bots und einige seiner Details beschreibt, falls jemand ihn neu erstellen oder für sich selbst fertigstellen möchte. Obwohl der Bot am Anfang des Codes Variablen enthält, über die Sie einige Einstellungen vornehmen können.
Zunächst der Algorithmus der Bot-Aktionen ab dem Zeitpunkt des Ladens:

1) Auf Header prüfen X-Frame-Optionen: VERWEIGERN(falls vorhanden, dann die Angelruten aufrollen);
2) Einbetten eines Rahmens und Einrichten aller Komponenten des Bots;
3) Entfernen des Skripts und aller Spuren im HTML-Code;
4) Herstellen eines Kontakts mit der Serverseite und Beginn des Sendens von Daten, Reagieren auf Antworten (Empfangen von Befehlen vom Server);

Der erste Punkt war nicht vollständig abgeschlossen, dh der Bot überprüft nur die erste Seite und den Stammkopf. Tatsache ist, dass diese Header normalerweise vom Webserver für alle Seiten gleichzeitig eingebettet werden und es sehr selten vorkommt, dass alles "manuell" für eine separate Seite ausgeführt wird. Und dieser Titel selbst ist ziemlich selten. Nun, zum zweiten und dritten gibt es nichts Besonderes zu sagen, alles wird niedriger sein.

Es gibt einen relativ wichtigen Punkt, dass Sie vor dem Hinzufügen des Bot-Skript-Codes in Ihrem Code die XSS-Zeichen in der Adressleiste sofort (aus dem JS-Code) entfernen müssen, da dies die Erkennungswahrscheinlichkeit verringert und vor allem die Rekursion verhindert, die auftritt, wenn dem Frame eine Adresse hinzugefügt wird mit demselben XSS-Code, der wiederum einen anderen Frame mit sich selbst erstellt, und so weiter.

Nur für den Fall, dass der Bot-Code die Möglichkeit implementiert, eine solche Frame-Rekursion zu erkennen und beim ersten Versuch, einen Frame zu einem bereits erstellten Frame hinzuzufügen, zu verhindern, ist es besser, sich nicht nur darauf zu verlassen, sondern den Code vor dem Laden des Bot-Codes zusätzlich zu löschen. Obwohl ich noch keine Probleme getroffen habe.

Frame Update Check Funktion. Ich habe verschiedene Möglichkeiten ausprobiert, um dieses Problem wirtschaftlich zu lösen, indem ich Event-Handler anhängte contentWindowoder contentDocumentDa jedoch nichts erfolgreich war, musste ich eine Funktion schreiben, die die Adresse des Frames überprüft und mit der zuvor gespeicherten vergleicht und auf dieser Grundlage entscheidet, ob der Frame aktualisiert wird (ob sich die Adresse geändert hat) und sich dann rekursiv selbst aufruft.

Die Häufigkeit solcher Überprüfungen pro Sekunde wird durch eine Variable gesteuert verzögern, die am Anfang der Bot-Code-Datei angegeben wird. Aber später, nachdem ich es bereits geschrieben hatte, fand ich eine effizientere Lösung - verwenden Sie eine einfache Lösung und hängen Sie onloadpro Frame, also habe ich diese Funktion verlassen, sie aber auskommentiert, falls sich später herausstellt, dass sie gefragter ist.

Senden des HTML-Codes der Seite.

Hier ist das Schema recht einfach: Nach jedem erneuten Laden des Frames (einschließlich des ersten Ladens) sendet der Bot den gesamten HTML-Code der Seite zusammen mit seiner aktuellen Adresse an den Server, damit Sie später unterscheiden können, ob der Code zu den erforderlichen Seiten gehört.

Die Logik zum Speichern von Seiten ist auf dem Server implementiert. Der Server für jede Domäne erstellt einen Ordner mit dem Namen dieser Domäne, und wir speichern alle Daten dort. Seitencodes werden gespeichert und ständig auf die neuesten Versionen aktualisiert. Jeden neuen Tag wird jedoch eine neue Kopie der Seite erstellt, damit Sie den Versionsverlauf bei Bedarf steuern können. Das heißt, für /news.phpAm 1. September wird der Status aktualisiert und am 2. September wird eine Kopie davon erstellt, die nur für diesen Tag und damit jeden Tag erneut relevant ist (wenn der Benutzer diese Seite jeden Tag besucht). Der Seitenname besteht aus dem Datum und dem Pfad zu dieser Seite relativ zum Site-Stammverzeichnis (dh ohne Domain).

Keylogger in JavaScript.

Die Idee wurde bereits von einigen Enthusiasten umgesetzt, aber für mich passten ihre Entwicklungen nicht, schon weil die meisten von ihnen recht einfach waren, dh sie erkannten den Code der gedrückten Taste und durch String.fromCharCodein Symbole übersetzt. Diese Methode hat jedoch eine Reihe von Nachteilen: Steuertasten wie Shift, Control, Space usw. werden nicht in irgendeine Form übersetzt (oft nur ein leeres Zeichen), die Interaktion von alphanumerischen Tasten mit der Shift-Taste wird falsch protokolliert, da dies programmgesteuert implementiert werden muss und Außerdem werden alle gedrückten Tasten in Großbuchstaben angezeigt, die auch programmgesteuert korrigiert werden können.

Das Ergebnis war ein Keylogger, der alle Tasten mit Zahlen, Buchstaben und Grundzeichen korrekt erkannte, an beiden Layouts arbeitete, auf die Verschiebung reagierte und alle wichtigen Sondertasten protokollierte. Einige Zeichen (im oberen Teil der digitalen Zeile, die gedruckt werden, wenn die Umschalttaste und die Nummer gedrückt werden) können auf einigen Computern abweichen, da sie gemäß dem Hauptstandard implementiert wurden, den einige Unternehmen für einige ändern.
Jeder Teil der gedrückten Zeichen wird vom Client beibehalten, bis das Textelement den Fokus verliert. Dieser Teil wird dann an den Server gesendet, wo er in einer Textdatei gespeichert wird, die ebenfalls jeden Tag mit einer neuen Kopie erstellt wird, sodass keine großen Größen entstehen und Sie schnell feststellen können, was der Benutzer zu einem solchen Zeitpunkt eingegeben hat.
Zusätzlich zu den Schlüsseln selbst werden mit jedem Teil (dh war es) Informationen über das Element gesendet, in das der Text eingegeben wurde ,