
PoC de la vulnérabilité CVE-2022-22978 dans le framework Spring Security
D'après les informations que j'ai trouvées, il s'agit d'une vulnérabilité liée à la classe RegexRequestMatcher du framework Spring Security. Plus précisément, les applications utilisant RegexRequestMatcher dont l'expression régulière contient un point (.) peuvent être contournées en utilisant les caractères \r(%0a) , \n(%0d) ; ainsi, les attaquants n'ont pas besoin d'authentification pour accéder aux chemins non autorisés.
Versions affectées du framework Spring Security :
5.5.x avant 5.5.75.6.x avant 5.6.4Nous devons accéder au code source de Spring Security pour analyser statiquement cette vulnérabilité. Plus précisément, j'utilise la fonctionnalité de comparaison des commits entre les versions 5.6.3 (version vulnérable) et 5.6.4 (version corrigée) de Github. Voir le lien suivant : Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

Je vérifie les modifications dans la classe RegexRequestMatcher. On peut voir que dans la version 5.6.4, cette classe utilise Pattern.DOTALL au lieu du . par défaut de la version 5.6.3.
Où :
Pattern : une des trois classes du paquet java.util.regex, servant à traiter les expressions régulières.Pattern.DOTALL : Lorsque ce flag est utilisé, le “.” dans l'expression régulière correspond à tous les caractères, y compris les caractères de nouvelle ligne comme \n , \r.Pattern.CASE_INSENSITIVE : ignore la casse (majuscules/minuscules).
Par défaut, le point . dans une expression régulière correspond à tous les caractères sauf les caractères de nouvelle ligne comme \n, \r. Ainsi, si une fonction regex valide un motif pour une chaîne, cette regex ne correspondra pas si la chaîne contient des sauts de ligne. Pour éviter cela, on peut utiliser le flag Pattern.DOTALL.
Cependant, si quelqu'un utilise intentionnellement %0d au lieu de \n ou %0a au lieu de \r, la regex ci-dessus ne peut toujours pas correspondre. Par conséquent, dans la version 5.6.4, une vérification supplémentaire a été ajoutée dans RegexRequestMatcherTests.java. Plus précisément, elle convertit %0d et %0a respectivement en \n et \r avant de vérifier avec la regex.

Étape 1: Créer une application web Spring Boot avec Spring Initializr en incluant les dépendances Spring Security et Spring Web.

Étape 2: Créer un Controller qui affiche le texte This is a CVE-2022-22978 demo lorsqu'une requête est faite vers le chemin /admin/*

Étape 3: Mettre en place un mécanisme d'authentification à chaque accès utilisateur au chemin /admin/<quelconque> en utilisant regexMatchers("/admin/.*").authenticated(). C'est la vulnérabilité que les attaquants exploitent pour voir le contenu des pages /admin/<quelconque> sans authentification.

Étape 4: Dans le fichier de configuration, déclarer la version de Spring Security contenant la vulnérabilité. Ici, je choisis la version 5.6.3.

Étape 5: Exécuter l'application avec la commande gradlew bootRun, le programme utilise par défaut Apache Tomcat sur le port 8080. Accéder au chemin /admin/xyz (n'importe quel chemin sous /admin/).

Le résultat renvoie un code 403 Forbidden, signifiant que je ne peux pas accéder car non authentifié.
À ce moment, en exploitant la vulnérabilité de la fonction regexMatchers dans Spring Security (version 5.6.3) qui ne correspond pas aux caractères de nouvelle ligne comme \r(%0d) et \n(%0a), je peux accéder au chemin ci-dessus sans authentification en utilisant le payload /admin/%0dxyz

De même avec le payload /admin/%0axyz

Ainsi, nous avons exploité avec succès la vulnérabilité CVE-2022-22978 avec un payload très simple.
5.7.1
Tester l'attaque avec le même payload : /admin/%0dxyz

Cette fois, l'application ne renvoie pas la réponse attendue par l'attaquant.
git clone https://github.com/ducluongtran9121/CVE-2022-22978-PoC.git
cd CVE-2022-22978-PoC
gradlew bootRun
Java 18
Gradle 7.4.1