[This lab](https://portswigger.net/web-security/websockets/lab-manipulating-handshake-to-exploit-vulnerabilities) combines two attack surfaces: **WebSocket message manipulation** and **WebSocket handshake tampering**. The goal is to bypass a flawed but aggressive XSS filter in the live chat system, which is also protected by an IP-based blocking mechanism. Our mission: deliver an obfuscated XSS payload to the support agent via WebSocket, even after being banned by the IP filter. --- ##### Understanding the Scenario The application’s live chat is powered by WebSockets. Each message is sent as a WebSocket frame, and the support agent receives and renders them in real time. However: * Messages are aggressively filtered to block obvious XSS. * Attempting a blocked payload triggers **IP-based banning**, enforced at the WebSocket handshake stage. * The ban is based on the IP from the handshake request — which we can spoof using HTTP headers. --- ##### Reconnaissance 1. **Send a normal chat message** and observe it in **Burp → Proxy → WebSockets** history. 2. **Send a basic XSS payload** via WebSocket frame: ```html <img src=1 onerror='alert(1)'> ``` Result: * The message is blocked. * The WebSocket connection is terminated. * Attempting to reconnect fails — IP banned. --- ##### The IP Ban Mechanism After being blocked, the WebSocket handshake fails. The handshake request is an HTTP upgrade request like: ``` GET /chat HTTP/1.1 Host: YOUR-LAB-ID.web-security-academy.net Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: ... Origin: https://YOUR-LAB-ID.web-security-academy.net ``` The ban relies on detecting your real IP — likely via the TCP connection or headers. If the server uses the `X-Forwarded-For` header for IP detection, we can spoof our address. ![[CleanShot 2025-08-13 at [email protected]]] --- ##### Spoofing the IP in the Handshake To bypass the ban: 1. In Burp, **intercept the WebSocket handshake** request. 2. Add the spoofing header: ``` X-Forwarded-For: 1.1.1.1 ``` 3. Forward the request — connection is re-established. To do that easily add match/replace rule: ![[CleanShot 2025-08-13 at [email protected]]] --- ##### Crafting the Bypass Payload The lab’s XSS filter is strict but flawed. Using attribute name obfuscation bypasses it. Instead of `onerror`, we can use **mixed-case event handlers** and **template literal backticks**: ```html <img src=1 oNeRrOr=alert`1`> ``` This evades naive filters that: * Match only lowercase `onerror` * Block normal parentheses but not backticks --- ##### Exploitation Steps 1. Reconnect the WebSocket using the spoofed IP header. 2. Send the obfuscated payload via WebSocket Repeater: ``` {"message":"<img src=1 oNeRrOr=alert`1`>"} ``` 3. The support agent’s browser executes `alert(1)` — lab solved. ![[CleanShot 2025-08-13 at 23.10.18@2x 1.png]]