manipulating-messages-to-exploit-vulnerabilities

In this level, a real-time chat application is implemented via web sockets. Because content over the web socket is sent back and forth and rendered on the client, there is a potential for an adversary to inject malicious code that performs a cross-site scripting attack.

Find web socket

Bring up the lab and inspect the main landing page using Developer Tools. Click on the "Live chat" link. Inspect the form on the page and find the websocket that is used to communicate chat messages.

Then, go to the "Network" tab, find the web socket that has been established, and click on it. Ensure that the "Request URL" in the headers is a wss:// one and has a "Messages" tab. Click on the "Messages" tab and view the initial messages that have been sent from the client to the server and the server back to the client.. Type in "Hello, <OdinId>" into the message box, filling in your OdinID (e.g. Hello, <wuchang>). Four messages should have been generated as a result.

Examine the message sent when attempting to send the script tag. While we have attempted to include a tag, the chat application encodes the tag to prevent cross-site scripting attacks when the message is subsequently echoed back to the client.

Examine Javascript encoding

Javascript code ensures that any chat messages sent to the server are properly encoding to remove script tags. Within the page, find the Javascript file that implements the chat features. Retrieve the file and find the code that does so.

Exploit

Entrusting a client to perform input sanitization is not an effective countermeasure against adversarial attack. An adversary can directly send unsanitized script tags to the server and to inject Javascript code on the server. To do so, we can use a Python program to directly communicate over the websocket.

Using the websockets package, we can set up an asynchronous event loop to handle messages being sent to and from the server. From your level URL, fill in the websocket_uri and the format field used to send messages via the chat window.

import asyncio
import websockets
import json

async def chat():
 websocket_uri = "ws://<FMI>"
 async with websockets.connect(websocket_uri) as websocket:
   msg = {'<FMI>' : "Hello world"}
   json_msg = json.dumps(msg)
   print(f"Sending {json_msg}")
   await websocket.send(json_msg)
   resp = await websocket.recv()
   print(f"Received {resp}")

asyncio.get_event_loop().run_until_complete(chat())

When you have received the expected response from the server via the websocket, replace "Hello world" with "Hello, <OdinID>" as in the previous steps.

Solve

We can now insert malicious Javascript via the websocket to finish the level. Using an <img> tag, inject Javascript code via an event attribute that performs an alert() on the server.