Snyking In: explotación de una vulnerabilidad de denegación de servicio por expresiones regulares en el paquete ms
13 de marzo de 2019
0 minutos de lectura¡Te damos la bienvenida a otra edición de nuestra serie de exploits Snyking In! La vez pasada vimos un exploit de una vulnerabilidad de recorrido de directorios en la biblioteca st. En este episodio veremos la vulnerabilidad de denegación de servicio por expresiones regulares, mostraremos cómo se puede explotar y explicaremos el riesgo potencial que representa para tus datos y sistemas.
También te mostraremos cómo encontrar y corregir este tipo de vulnerabilidad en tu aplicación. Sin más preámbulos, aquí tienes el video del exploit, seguido de más información sobre la vulnerabilidad de denegación de servicio por expresiones regulares.

Denegación de servicio por expresiones regulares
La denegación de servicio (DoS) describe una familia de ataques cuyo objetivo es impedir que los usuarios legítimos originales puedan acceder a un sistema. Hay muchos tipos de ataques DoS, desde intentar saturar los canales de red del sistema al generar un gran volumen de tráfico desde muchas máquinas (un ataque distribuido de denegación de servicio, DDoS) hasta enviar solicitudes diseñadas para hacer que un sistema falle o tarde una cantidad desproporcionada de tiempo en procesarlas.
La denegación de servicio por expresiones regulares (ReDoS) es un tipo de ataque de denegación de servicio. Las expresiones regulares son increíblemente potentes, pero no son muy intuitivas y, en última instancia, pueden facilitar que los atacantes dejen tu sitio fuera de servicio.
El reciente informe sobre el estado de la seguridad del código abierto, publicado por Snyk, reveló que las divulgaciones de vulnerabilidades de denegación de servicio por expresiones regulares aumentaron un 143 % solo durante el último año.

Retroceso catastrófico
Veamos la siguiente expresión regular:
Esta expresión regular hace lo siguiente:
ALa cadena debe comenzar con la letraA(B|C+)+Después de la letraA, la cadena debe incluir la letraBo una o más apariciones de la letraC(el signo+indica una o más apariciones). El signo+al final de esta sección indica que podemos buscar una o más coincidencias de esta sección.DPor último, nos aseguramos de que esta sección de la cadena termine con unaD
La expresión coincidiría con entradas como ABBD, ABCCCCD, ABCBCCCD y ACCCCCD. En la mayoría de los casos, el motor de expresiones regulares encuentra una coincidencia rápidamente:
Todo el proceso de probarla con una cadena de 30 caracteres tarda alrededor de 52 ms. Pero, si se proporciona una cadena no válida, la prueba tarda casi dos segundos en completarse: más de diez veces lo que tardó en probar una cadena válida. Esta diferencia tan marcada se debe a la forma en que se evalúan las expresiones regulares.
La mayoría de los motores de expresiones regulares funcionan de manera muy similar (con pequeñas diferencias). El motor encuentra la primera forma posible de aceptar el carácter actual y continúa con el siguiente. Si no logra coincidir con el siguiente carácter, retrocede para ver si había otra forma de procesar el carácter anterior. Si avanza demasiado por un camino sin salida y luego descubre que la cadena no coincide, y si muchos caracteres tienen varias rutas válidas en la expresión regular, la cantidad de pasos de retroceso puede volverse muy grande. Esto se conoce como retroceso catastrófico.
El exploit de ms
El siguiente comando agrega una tarea pendiente a nuestra aplicación de tareas Snyk Goof. El motor de expresiones regulares interpreta la parte in 20 minutes del texto como una representación de tiempo. Por ejemplo, la lógica de negocio de la aplicación podría usar esto para crear recordatorios o alertas.
Podemos intentar forzar la longitud de la entrada de la tarea pendiente de la siguiente manera. El comando imprime 60000 5s como cantidad de minutos, pero responde muy rápido porque el patrón todavía coincide.
Para provocar una denegación de servicio, hay que pasar una cadena que genere una situación de retroceso catastrófico. En parte, esto requiere una cadena de entrada larga, como en el ejemplo anterior, pero también debemos asegurarnos de que el motor de expresiones regulares nunca encuentre una coincidencia con el patrón y, por lo tanto, retroceda por todas las posibilidades antes de fallar. Esto provoca la demora o denegación de servicio que buscamos. Para lograrlo, podemos cambiar el texto minutes de nuestro contenido por minutea, por ejemplo, un patrón con el que el motor de expresiones regulares no encontrará coincidencias. El siguiente comando de entrada provocará una denegación de servicio de unos 10 a 15 segundos. Si pasamos 600000 5s, tendremos que esperar prácticamente todo el día para que el servidor complete la solicitud.
Para probar si tu aplicación tiene vulnerabilidades en bibliotecas de terceros, como ms, prueba Snyk gratis.
Empieza con los desafíos de Capture the Flag
Aprende a resolver desafíos de captura la bandera con nuestro taller virtual introductorio a pedido.
