WebSocket attacks guide
Guía sobre WebSocket Attacks
Certificaciones
- eWPT
- eWPTXv2
- OSWE
- BSCP
Descripción
Explicación técnica de vulnerabilidades que se pueden dar a través de websockets. Detallamos cómo identificar y explotar esta vulnerabilidades. Además, exploramos estrategias clave para prevenirlas
¿Qué son los WebSockets?
Los WebSockets son un protocolo de comunicación bidireccional y full duplex iniciado sobre HTTP. Se usan comúnmente en las aplicaciones web modernas para transmitir datos y otro tipo de tráfico asíncrono
En esta sección explicaremos la diferencia entre HTTP y WebSockets, cómo se establecen las conexiones WebSocket, y cómo son los mensajes WebSocket
¿Cuál es la diferencia entre HTTP y WebSocket?
La mayoría de la comunicación entre navegadores web y sitios web utiliza HTTP. Con HTTP, el cliente envía una solicitud y el servidor devuelve una respuesta. Normalmente, la respuesta ocurre de inmediato y la transacción termina. Incluso si la conexión de red permanece abierta, se usará para una transacción separada de solicitud y respuesta
Algunos sitios modernos usan WebSockets. Las conexiones WebSocket se inician sobre HTTP y suelen ser de larga duración. Los mensajes pueden enviarse en cualquier dirección y en cualquier momento y no son de tipo transaccional. La conexión normalmente permanece abierta e inactiva hasta que el cliente o el servidor esté listo para enviar un mensaje
Los WebSockets son especialmente útiles en situaciones donde se requieren mensajes de baja latencia o iniciados por el servidor, como en transmisiones en tiempo real de datos financieros
¿Cómo se establecen las conexiones WebSocket?
Las conexiones WebSocket normalmente se crean usando JavaScript del lado del cliente, como el siguiente ejemplo:
1
var ws = new WebSocket("wss://normal-website.com/chat");
El protocolo wss establece un WebSocket cifrado sobre una conexión TLS, mientras que ws usa una conexión sin cifrar
Para establecer la conexión, el navegador y el servidor realizan un handshake WebSocket sobre HTTP. El navegador envía una solicitud de handshake como la siguiente:
1
2
3
4
5
6
7
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 WebSocket como esta:
1
2
3
4
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 puede usarse para enviar mensajes WebSocket en cualquier dirección
Varias características de los mensajes de handshake de WebSocket son importantes:
Las cabeceras
ConnectionyUpgradeen lasolicitudy larespuestaindican que se trata de unhandshake WebSocketLa cabecera
Sec-WebSocket-Versionespecifica laversión del protocolo WebSocketque el cliente desea usar . Esto es normalmente13La cabecera
Sec-WebSocket-Keycontiene unvalor aleatorio codificado en Base64, quedebe generarse aleatoriamente en cada solicitud de handshakeLa cabecera
Sec-WebSocket-Accepten larespuestacontiene unhash del valorenviado enSec-WebSocket-Key, concatenado con unacadena específica definida en la especificación del protocolo. Esto evitarespuestas falsascausadas porservidores mal configuradosoproxies en caché
¿Cómo son los mensajes WebSocket?
Una vez que se ha establecido una conexión WebSocket, los mensajes pueden enviarse de forma asíncrona en cualquier dirección, ya sea por el cliente o el servidor
Un mensaje simple puede enviarse desde el navegador usando JavaScript del lado del cliente como en el siguiente ejemplo:
1
ws.send("Peter Wiener");
En principio, los mensajes WebSocket pueden contener cualquier contenido o formato de datos. En las aplicaciones modernas, es común usar JSON para enviar datos estructurados dentro de los mensajes WebSocket
Por ejemplo, una aplicación de chat-bot que use WebSockets podría enviar un mensaje como el siguiente:
1
{"user":"Hal Pline","content":"I wanted to be a Playstation growing up, not a device to answer your inane questions"}
Manipulación del tráfico WebSocket
Encontrar vulnerabilidades en WebSockets generalmente implica manipular el tráfico de formas que la aplicación no espera. Podemos hacerlo usando Burpsuite
Con Burpsuite podemos:
Interceptar y modificar mensajes WebSocket
Reproducir y generar nuevos mensajes WebSocket
Manipular conexiones WebSocket
Interceptar y modificar mensajes WebSocket
Podemos usar el Proxy de Burpsuite para interceptar y modificar los mensajes WebSocket, de la siguiente forma:
Abrir el
navegadordeBurpsuiteNavegarhasta lafunciónde laaplicaciónqueusa WebSockets. Podemosidentificarque se usanWebSocketsobservando las entradas que aparecen en la pestañaWebSockets historydentro delProxydeBurpsuiteEn la pestaña
InterceptdelProxydeBurpsuite, asegurarnos de que laintercepciónestéactivadaCuando se
envíeunmensaje WebSocketdesde elnavegadoro elservidor, se mostrará en la pestañaInterceptpara que loveamoso lomodifiquemos. Pulsar el botónForwardparareenviarelmensaje
Repetición y generación de nuevos mensajes WebSocket
Además de interceptar y modificar mensajes WebSocket en tiempo real, podemos repetir mensajes individuales y generar mensajes nuevos. Podemos hacerlo usando el Repeater de Burpsuite:
En el
ProxydeBurpsuite, debemosseleccionarunmensajeen elWebSockets history, o en la pestañaIntercept, y elegirSend to Repeaterdesde elmenú contextualEn el
RepeaterdeBurpsuite, ahora podemoseditar el mensaje seleccionadoyenviarlo una y otra vezPodemos
introducir un mensaje nuevoyenviarloencualquiera de las dos direcciones, alclienteo alservidorEn el panel
Historydentro delRepeaterdeBurpsuite, podemosver el historial de mensajes transmitidos sobre la conexión WebSocket. Esto incluyemensajesquehemos generadoen elRepeaterdeBurpsuitey también losgeneradospor elnavegadoro elservidorvía lamisma conexiónSi queremos
editaroreenviarcualquiermensajedel panelHistory, podemos hacerloseleccionando el mensajey eligiendoEdit and resenddesde elmenú contextual
Manipulación de conexiones WebSocket
Además de manipular mensajes WebSocket, a veces es necesario manipular el handshake que establece la conexión
Existen varias situaciones en las que manipular el handshake WebSocket puede ser necesario. El hacerlo puede ser útil en los siguiente casos:
Permitirnos alcanzar
más superficie de ataqueEstablecer una nueva conexión, ya que, algunos ataques pueden provocar que nuestra conexión se caigaTokensuotros datosen lasolicitud de handshake originalpueden estarobsoletosynecesitar actualización
Podemos manipular el handshake WebSocket usando el Repeater de Burpsuite:
Enviarunmensaje WebSocketalRepeaterdeBurpsuitecomo se ha descritoEn el
RepeaterdeBurpsuite, hacerclicken elicono del lápizjunto a laURLdelWebSocket. Esto abre unasistenteque nos permiteadjuntarnosa unWebSocket conectado existente,clonarunWebSocket conectado, oreconectarnosa unWebSocket desconectadoSi elegimos
clonar un WebSocket conectadooreconectarnos a un WebSocket desconectado, elasistentemostrará losdetalles completosde lasolicitud de handshake del WebSocket, la cual podemoseditar según sea necesarioantes de que se realice elhandshake.Cuando pulsemos en
Connect,Burpsuiteintentaráejecutar el handshake configurado y mostrará el resultado. Sise establece correctamente una nueva conexión WebSocket, podremos usarla paraenviar mensajes nuevosmediante elRepeaterdeBurpsuite
Vulnerabilidades de seguridad en WebSocket
En principio, prácticamente cualquier vulnerabilidad de seguridad web podría surgir en relación con los WebSockets:
Cuando el
inputproporcionado por elusuariose transmite alservidorpodríaprocesarse de forma insegura, conduciendo avulnerabilidadescomoSQL injectionoXXEAlgunas vulnerabilidades
blindalcanzables víaWebSocketspodríandetectarsesolamente usandoOAST (técnicas out-of-band)Si los
datos controladospor elatacantesetransmitenvíaWebSocketsa otros usuarios de la aplicación, esto podría provocar unXSSu otrasvulnerabilidades del lado del cliente
Manipular mensajes WebSocket para explotar vulnerabilidades
La mayoría de las vulnerabilidades basadas en entrada que afectan a WebSockets pueden encontrarse y explotarse manipulando el contenido de los mensajes WebSocket
Por ejemplo, supongamos que una aplicación tiene un chat que usa WebSockets para enviar mensajes entre el navegador y el servidor. Cuando un usuario escribe un mensaje en el chat, se envía al servidor el mensaje mediante un WebSocket como el siguiente:
1
{"message":"Hello Carlos"}
El contenido del mensaje se transmite de nuevo vía WebSockets a otro usuario del chat, y se renderiza en el navegador del usuario así:
1
<td>Hello Carlos</td>
En esta situación, siempre que no existan otros procesados del input o defensas, un atacante puede realizar un PoC de XSS enviando el siguiente mensaje WebSocket:
1
{"message":"<img src=1 onerror='alert(1)'>"}
En este laboratorio podemos ver como se aplica esta técnica:
- Manipulating WebSocket messages to exploit vulnerabilities - https://justice-reaper.github.io/posts/WebSocket-Attacks-Lab-1/
Manipular el handshake WebSocket para explotar vulnerabilidades
Algunas vulnerabilidades de WebSocket solo pueden encontrarse y explotarse manipulando el handshake WebSocket. Estas vulnerabilidades suelen implicar fallos de diseño, como:
Confianza en cabeceras HTTP para tomar decisiones de seguridad, por ejemplo la cabeceraX-Forwarded-ForDefectos en los mecanismos de manejo de sesiones, ya que elcontexto de sesiónen el cual losmensajes WebSocketsonprocesadosestá generalmente determinado porel contexto de sesión del mensaje handshake, es decir, porel mensaje de establecimiento de conexiónSuperficie de ataqueintroducida porcabeceras HTTP personalizadasusadas por la aplicación
En este laboratorio podemos ver como se aplica esta técnica:
- Manipulating the WebSocket handshake to exploit vulnerabilities - https://justice-reaper.github.io/posts/WebSocket-Attacks-Lab-3/
Cross-site WebSocket hijacking
En esta sección explicaremos el CSWSH (cross-site WebSocket hijacking), describiremos el impacto de comprometerlo, y detallaremos cómo realizar un ataque de cross-site WebSocket hijacking
¿Qué es el cross-site WebSocket hijacking?
El cross-site WebSocket hijacking también es conocido como cross-origin WebSocket hijacking e implica una vulnerabilidad de CSRF en el handshake WebSocket. Surge cuando la solicitud de handshake WebSocket confía únicamente en las cookies HTTP para el manejo de la sesión y no incluye token CSRF u otros valores impredecibles
Un atacante puede crear una página web maliciosa en su propio dominio que establezca una conexión WebSocket cross-site con la aplicación vulnerable. La aplicación tratará la conexión en el contexto de la sesión del usuario víctima
Por esto, la página del atacante puede enviar mensajes arbitrarios al servidor a través de la conexión y leer el contenido de los mensajes que el servidor devuelva. Esto significa que, a diferencia del CSRF normal, el atacante obtiene interacción bidireccional con la aplicación comprometida
¿Cuál es el impacto del cross-site WebSocket hijacking?
Un ataque exitoso de cross-site WebSocket hijacking a menudo permitirá a un atacante:
Realizar acciones no autorizadas haciéndose pasar por el usuario víctima- Como en elCSRFhabitual, el atacante puedeenviar mensajes arbitrarios a la aplicación del servidor. Si laaplicaciónutilizamensajes WebSocket generados por el clienteparaejecutar acciones sensibles, el atacantepuede generar esos mensajes desde otro dominio y disparar esas accionesRecuperar datos sensibles a los que el usuario tiene acceso- A diferencia delCSRF normal, elcross-site WebSocket hijackingproporciona al atacanteinteracción bidireccionalcon laaplicación vulnerablea través delWebSocket secuestrado. Si laaplicaciónusamensajes WebSocket generados por el servidorparadevolver datos sensibles al usuario, el atacante puedeinterceptar esos mensajesycapturar los datos de la víctima
Realizar un cross-site WebSocket hijacking
Dado que un ataque de cross-site WebSocket hijacking es esencialmente una vulnerabilidad de CSRF en un handshake WebSocket, el primer paso para ejecutar un ataque es revisar los handshakes WebSocket que realiza la aplicación y determinar si están protegidos contra CSRF
En términos de las condiciones normales para ataques CSRF, normalmente necesitamos encontrar una solicitud de handshake que dependa únicamente de las cookies HTTP para la gestión de sesión y que no emplee tokens u otros valores impredecibles en los parámetros de la solicitud
Por ejemplo, la siguiente solicitud de handshake WebSocket probablemente sea vulnerable a CSRF, porque el único token de sesión se transmite en una cookie:
1
2
3
4
5
6
7
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
La cabecera Sec-WebSocket-Key contiene un valor aleatorio para prevenir errores de proxies en caché, y no se usa para autenticación ni para la gestión de sesión
Si la solicitud de handshake WebSocket es vulnerable a CSRF, la página del atacante puede realizar una petición cross-site para abrir un WebSocket en el sitio web vulnerable. Lo que ocurra a continuación depende completamente de la lógica de la aplicación y de cómo use WebSockets. El ataque podría implicar:
Enviar mensajes WebSocketpararealizar acciones no autorizadas en nombre del usuario víctimaEnviar mensajes WebSocketpararecuperar datos sensiblesA veces, simplemente
esperara quelleguen mensajes entrantesque contengandatos sensibles
En este laboratorio podemos ver como se aplica esta técnica:
- Cross-site WebSocket hijacking - https://justice-reaper.github.io/posts/WebSocket-Attacks-Lab-2/
Cheatsheet
Usaremos estas cheatsheet para facilitar la detección y explotación de esta vulnerabilidad:
- Hacking tools https://justice-reaper.github.io/posts/Hacking-Tools/
¿Cómo llevar a cabo un ataque mediante WebSocket?
Teniendo en cuenta que los términos y herramientas mencionados a continuación se encuentran en la cheatsheet mencionada anteriormente, llevaremos a cabo los siguientes pasos:
Instalar las extensiones
Param MineryRandom IP Address HeaderdeBurpsuiteUsar la extensión
Param MinerdeBurpsuitepara descubrir si podemos usar algunacabecera. Para estavulnerabilidadseguramente podamos usarX-Forwarded-Forparabypassearlosbloqueos mayores a 1 minuto. Una vez probado que podemos usarX-Forwarded-For, podemos usar la extensiónRandom IP Address Headerpara que nosañadaestacabeceraa todas laspeticionesObservar a ver si podemos enviar algún
payloadmediante unmessage WebSocket. Revisar laguía de ofuscacióny la deXSSSi observamos que se nos asigna una
cookieyno existe token CSRFpodemos probar aenviarleunpayloadalusuario víctimayobtener su chat
¿Cómo asegurar una conexión WebSocket?
Para minimizar el riesgo de vulnerabilidades de seguridad al usar WebSockets, debemos seguir las siguientes recomendaciones:
Usar el protocolo
wss:// (WebSockets sobre TLS)Codificar de forma fijalaURL del endpoint WebSockety nunca incluirdatos controlados por el usuarioen estaURLProteger el mensaje de handshakedelWebSocketcontraCSRF, paraevitar vulnerabilidades de tipo cross-site WebSocket hijackingTratar los
datos recibidosa través delWebSocketcomono confiablesenambas direcciones. Debemosmanejar los datos de forma seguratanto en elservidorcomo en elcliente, paraprevenir vulnerabilidades basadas en inputscomoSQL injectionycross-site scripting (XSS)
