
PoC der Schwachstelle CVE-2022-22978 im Spring Security Framework
Nach meinen Recherchen handelt es sich um eine Schwachstelle in der Klasse RegexRequestMatcher im Spring-Security-Framework. Konkret können Anwendungen, die RegexRequestMatcher mit einem regulären Ausdruck verwenden, der einen Punkt (.) enthält, mithilfe der Zeichen \r(%0a) und \n(%0d) umgangen werden; dadurch können Angreifer ohne Authentifizierung auf nicht erlaubte Pfade zugreifen.
Von der Schwachstelle betroffene Versionen des Spring-Security-Frameworks:
5.5.x vor 5.5.75.6.x vor 5.6.4Wir müssen in den Quellcode von Spring Security schauen, um diese Schwachstelle statisch zu analysieren. Konkret habe ich die Commit-Vergleichsfunktion von GitHub zwischen Version 5.6.3 (verwundbar) und Version 5.6.4 (behoben) verwendet. Siehe folgenden Link: Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

Ich habe die Änderungen in der Klasse RegexRequestMatcher untersucht. Man sieht, dass diese Klasse in Version 5.6.4 Pattern.DOTALL verwendet, anstatt wie in Version 5.6.3 den Standard-Punkt . zu nutzen.
Dabei gilt:
Pattern: ist eine der drei Klassen im Paket java.util.regex und dient zur Verarbeitung regulärer Ausdrücke.Pattern.DOTALL: Mit diesem Flag matcht „.“ in einem regulären Ausdruck alle Zeichen, einschließlich Zeilenumbruchzeichen wie \n , \r.Pattern.CASE_INSENSITIVE: ignoriert Groß- und Kleinschreibung.
Standardmäßig matcht der Punkt . in einem regulären Ausdruck alle Zeichen außer Zeilenumbruchzeichen wie \n, \r. Wenn also eine Regex-Funktion das Muster einer Zeichenkette validiert, matcht diese Regex nicht, wenn die Zeichenkette Zeilenumbruchzeichen enthält. Um dies zu vermeiden, kann das Flag Pattern.DOTALL verwendet werden.
Wenn jedoch jemand absichtlich %0d statt \n oder %0a statt \r verwendet, kann die obige Regex immer noch nicht matchen. Deshalb wurde in Version 5.6.4 in RegexRequestMatcherTests.java eine zusätzliche Prüfung für diesen Fall hinzugefügt. Konkret werden %0d und %0a der Reihe nach in \n und \r konvertiert, bevor die Regex-Prüfung erfolgt.

Schritt 1: Erstelle eine Spring-Boot-Webanwendung mit Spring Initializr mit den beiden Abhängigkeiten Spring Security und Spring Web.

Schritt 2: Erstelle einen Controller, der bei einer Anfrage an den Pfad /admin/* den Text This is a CVE-2022-22978 demo ausgibt.

Schritt 3: Richte einen Authentifizierungsmechanismus ein, der greift, wenn ein Benutzer auf einen Pfad /admin/<beliebig> zugreift, indem du regexMatchers("/admin/.*").authenticated() verwendest. Genau diese Schwachstelle nutzen Angreifer aus, um Inhalte der Seiten /admin/<beliebig> ohne Authentifizierung anzusehen.

Schritt 4: Deklariere in der Konfigurationsdatei die verwundbare Version von Spring Security. Hier habe ich Version 5.6.3 gewählt.

Schritt 5: Starte die Anwendung mit dem Befehl gradlew bootRun. Das Programm verwendet standardmäßig Apache Tomcat, der auf Port 8080 lauscht. Wir rufen den Pfad /admin/xyz auf (jeder Pfad ist möglich, solange er mit /admin/ beginnt).

Die Antwort mit dem Code 403 Forbidden bedeutet, dass ich nicht zugreifen kann, weil ich nicht authentifiziert bin.
Jetzt nutze ich die Schwachstelle der regexMatchers-Funktion in Spring Security (Version 5.6.3), die Zeilenumbruchzeichen wie \r(%0d) und \n(%0a) nicht matcht. Dadurch kann ich mit dem Payload /admin/%0dxyz ohne Authentifizierung auf den obigen Pfad zugreifen.

Analog mit dem Payload /admin/%0axyz.

Damit haben wir die Schwachstelle CVE-2022-22978 mit einem äußerst einfachen Payload erfolgreich ausgenutzt.
5.7.1.
Teste den Angriff auf die Webanwendung mit demselben Payload wie zuvor: /admin/%0dxyz

Diesmal gibt die App nicht die vom Angreifer erwartete Antwort zurück.
git clone https://github.com/ducluongtran9121/CVE-2022-22978-PoC.git
cd CVE-2022-22978-PoC
gradlew bootRun
Java 18
Gradle 7.4.1