
Encuentra expresiones regulares que son vulnerables a ReDoS (Denegación de Servicio por Expresión Regular)

Encuentra expresiones regulares vulnerables a Denegación de Servicio por Expresión Regular (ReDoS).
Más información en el blog de Doyensec
Muchos analizadores de expresiones regulares por defecto tienen una complejidad de caso peor no acotada. La coincidencia de regex puede ser rápida cuando se presenta una cadena de entrada que coincide. Sin embargo, ciertas cadenas de entrada que no coinciden pueden hacer que el motor de expresiones regulares entre en bucles de retroceso locos y tarde mucho tiempo en procesarse. Esto puede causar denegación de servicio, ya que la CPU quedará atascada intentando hacer coincidir la regex.
Esta herramienta está diseñada para:
Esto refleja la complejidad del procedimiento de retroceso del motor de expresiones regulares con respecto a la longitud de la cadena introducida.
Complejidad cúbica aquí significa que si la parte vulnerable de la cadena se duplica en longitud, el tiempo de ejecución debería ser aproximadamente 8 veces mayor (2^3).
Para ReDoS exponencial con estrellas anidadas, por ejemplo (a*)*$, se utiliza un factor de corrección y la complejidad será mayor que 10.
Para ser explotable, normalmente se requiere una complejidad cúbica o superior, a menos que se permitan cadenas realmente largas como entrada.
Ejecuta regexploit e introduce la expresión regular v\w*_\w*_\w*$ en la línea de comandos.
$ regexploit
v\w*_\w*_\w*$
Pattern: v\w*_\w*_\w*$
---
Worst-case complexity: 3 ⭐⭐⭐ (cubic)
Repeated character: [5f:_]
Final character to cause backtracking: [^WORD]
Example: 'v' + '_' * 3456 + '!'
La parte \w*_\w*_\w* contiene tres grupos repetitivos superpuestos (\w coincide con letras, dígitos y guiones bajos). Como se muestra en la línea Repeated character: [5f:_], una cadena larga de _ (0x5f) coincidirá con esta sección de muchas maneras diferentes. La complejidad en el peor caso es 3 porque hay 3 grupos que se repiten infinitamente. Se proporciona un ejemplo para provocar ReDoS: consiste en el prefijo requerido v, una cadena larga de _ y luego un ! (carácter no palabra) para provocar el retroceso. No todos los ReDoS requieren un carácter particular al final, pero en este caso, una cadena larga de _ coincidirá con la regex correctamente y no retrocederá. La línea Final character to cause backtracking: [^WORD] muestra que se necesita un carácter que no coincide (no un carácter de palabra) al final para evitar la coincidencia y provocar ReDoS.
Como otro ejemplo, instala una versión de módulo vulnerable a ReDoS como pip install ua-parser==0.9.0.
Para escanear los módulos de Python instalados, ejecuta regexploit-python-env.
Importing ua_parser.user_agent_parser
Vulnerable regex in /somewhere/.env/lib/python3.9/site-packages/ua_parser/user_agent_parser.py #183
Pattern: \bSmartWatch *\( *([^;]+) *; *([^;]+) *;
Context: self.user_agent_re = re.compile(self.pattern)
---
Worst-case complexity: 3 ⭐⭐⭐
Repeated character: [20]
Example: 'SmartWatch(' + ' ' * 3456
Worst-case complexity: 3 ⭐⭐⭐
Repeated character: [20]
Example: 'SmartWatch(0;' + ' ' * 3456
Vulnerable regex in /somewhere/.env/lib/python3.9/site-packages/ua_parser/user_agent_parser.py #183
Pattern: ; *([^;/]+) Build[/ ]Huawei(MT1-U06|[A-Z]+\d+[^\);]+)[^\);]*\)
Context: self.user_agent_re = re.compile(self.pattern)
---
Worst-case complexity: 3 ⭐⭐⭐
Repeated character: [[0-9]]
Example: ';0 Build/HuaweiA' + '0' * 3456
...
Para cada expresión regular vulnerable, imprime una o más cadenas maliciosas para desencadenar ReDoS. Si estableces tu user agent en ;0 Build/HuaweiA000000000000000... y navegas por un sitio web que usa una versión antigua de ua-parser, el servidor podría tardar mucho en procesar tu solicitud, probablemente terminando en el estado 502.
Se requiere Python 3.8+. Para extraer expresiones regulares de código JavaScript/TypeScript, también se requiere NodeJS 12+.
Opcionalmente, crea un entorno virtual
python3 -m venv .env
source .env/bin/activate
Ahora instala con pip
pip install regexploit
Introduce expresiones regulares a través de stdin (una por línea) en regexploit.
regexploit
o a través de un archivo
cat myregexes.txt | regexploit
Hay soporte integrado para analizar expresiones regulares de Python, JavaScript, TypeScript, C#, YAML y JSON.
Analiza código Python (sin ejecutarlo) a través del AST para encontrar expresiones regulares. Luego, las expresiones regulares se analizan en busca de ReDoS.
regexploit-py my-project/
regexploit-py "my-project/**/*.py" --glob
Esto usará el paquete NodeJS incluido en regexploit/bin/javascript que analiza tu JavaScript como un AST con eslint e imprime todas las expresiones regulares.
Esas expresiones regulares se introducen en el buscador de ReDoS de Python.
regexploit-js my-module/my-file.js another/file.js some/folder/
regexploit-js "my-project/node_modules/**/*.js" --glob
Nota: hay diferencias entre el análisis de expresiones regulares de JavaScript y Python, por lo que puede haber algunos errores. ¡No estoy seguro de querer escribir un AST de regex de JS!
Busca expresiones regulares en todos los módulos de Python actualmente instalados en tu ruta/entorno. Esto significa que puedes hacer pip install de cualquier módulo que te interese y serán analizados. El código de Cpython está incluido.
regexploit-python-env
Nota: esto no analiza el código Python en un AST y solo encontrará expresiones regulares compiladas automáticamente en la importación del módulo. Los módulos se importan realmente, por lo que se ejecutará el código de los módulos. Esto es útil para encontrar expresiones regulares que se construyen a partir de cadenas más pequeñas al cargarse, por ejemplo, CVE-2021-25292 en Pillow
El soporte para YAML requiere pyyaml, que se puede instalar con pip install regexploit[yaml].
regexploit-json *.json
regexploit-yaml *.yaml
regexploit-csharp something.cs
Esta herramienta ha sido creada por Ben Caller de Doyensec LLC durante el tiempo de investigación.