
PoC уязвимости CVE-2022-22978 в фреймворке Spring Security
Согласно полученной информации, это уязвимость, связанная с классом RegexRequestMatcher в фреймворке Spring Security. В частности, приложения, использующие RegexRequestMatcher, в регулярных выражениях которых содержится точка (.), могут быть обойдены с помощью символов \r(%0a) , \n(%0d); таким образом, злоумышленники могут получать доступ к запрещенным путям без аутентификации.
Уязвимые версии фреймворка Spring Security:
5.5.x до 5.5.75.6.x до 5.6.4Нам нужно обратиться к исходному коду Spring Security для статического анализа этой уязвимости. В частности, я использую функцию сравнения коммитов между версиями 5.6.3 (уязвимая) и 5.6.4 (исправленная) на Github. Смотрите по ссылке: Comparing 5.6.3...5.6.4 · spring-projects/spring-security (github.com)

Я проверил изменения в классе RegexRequestMatcher. Можно заметить, что в версии 5.6.4 этот класс использует Pattern.DOTALL вместо точки . по умолчанию, как в версии 5.6.3.
Где:
Pattern : один из трех классов в пакете java.util.regex, предназначенный для обработки регулярных выражений.Pattern.DOTALL : При использовании этого флага точка “.” в регулярном выражении будет соответствовать всем символам, включая символы новой строки, такие как \n , \r.Pattern.CASE_INSENSITIVE: игнорирует регистр букв.
По умолчанию точка . в регулярном выражении соответствует всем символам, кроме символов новой строки, таких как \n, \r. В таком случае, если существует функция regex для проверки шаблона некоторой строки, то эта функция не сработает, если в строке есть символы новой строки. Чтобы избежать этого, можно использовать флаг Pattern.DOTALL.
Однако если кто-то намеренно использует %0d вместо \n или %0a вместо \r, то вышеуказанное regex все равно не сработает. Поэтому в версии 5.6.4 была добавлена дополнительная проверка этого случая в RegexRequestMatcherTests.java. А именно, он преобразует %0d и %0a в \n и \r соответственно, а затем проверяет с помощью regex.

Шаг 1: Создайте веб-приложение Spring Boot с помощью Spring Initializr с двумя зависимостями: Spring Security и Spring Web.

Шаг 2: Создайте контроллер, который выводит текст This is a CVE-2022-22978 demo при запросе к пути /admin/*

Шаг 3: Настройте механизм аутентификации каждый раз, когда пользователь обращается к пути /admin/<любой> с помощью regexMatchers("/admin/.*").authenticated(). Именно эту уязвимость используют злоумышленники для просмотра содержимого страниц /admin/<любой> без аутентификации.

Шаг 4: В файле конфигурации объявите версию Spring Security, содержащую уязвимость. Здесь я выбрал версию 5.6.3.

Шаг 5: Запустите приложение с помощью команды gradlew bootRun, программа по умолчанию использует Apache Tomcat, прослушивающий порт 8080. Перейдите по пути /admin/xyz (любой путь, начинающийся с /admin/).

В результате возвращается код 403 Forbidden, что означает, что доступ невозможен из-за отсутствия аутентификации.
Теперь, используя уязвимость функции regexMatchers в Spring Security (версия 5.6.3), которая не сопоставляет символы новой строки, такие как \r(%0d) и \n(%0a), мы можем получить доступ к указанному пути без аутентификации с помощью payload /admin/%0dxyz

Аналогично с payload /admin/%0axyz

Таким образом, мы успешно использовали уязвимость CVE-2022-22978 с помощью очень простого payload.
5.7.1
Попробуйте атаковать веб-приложение тем же payload: /admin/%0dxyz

Теперь приложение не возвращает ответ, ожидаемый злоумышленником.
git clone https://github.com/ducluongtran9121/CVE-2022-22978-PoC.git
cd CVE-2022-22978-PoC
gradlew bootRun
Java 18
Gradle 7.4.1