
Spring Security 프레임워크의 CVE-2022-22978 취약점 PoC
제가 조사한 정보에 따르면, 이 취약점은 Spring Security 프레임워크의 RegexRequestMatcher 클래스와 관련이 있습니다. 구체적으로, 정규 표현식에 마침표(.)가 포함된 RegexRequestMatcher를 사용하는 애플리케이션은 \r(%0a) , \n(%0d) 문자를 사용하여 우회될 수 있습니다. 이로 인해 공격자는 인증 없이 허용되지 않은 경로에 접근할 수 있습니다.
취약한 Spring Security 프레임워크 버전:
5.5.x 이전 5.5.75.6.x 이전 5.6.4이 취약점을 정적으로 분석하기 위해 Spring Security의 소스 코드에 접근해야 합니다. 여기서는 Github에서 취약한 버전 5.6.3과 수정된 버전 5.6.4 간의 커밋 비교 기능을 사용합니다. 다음 링크를 참조하세요: 5.6.3...5.6.4 비교 · spring-projects/spring-security (github.com)

RegexRequestMatcher 클래스의 변경 사항을 확인합니다. 버전 5.6.4에서는 기본 . 대신 Pattern.DOTALL을 사용하는 것을 볼 수 있습니다.
여기서:
Pattern: java.util.regex 패키지에 있는 세 클래스 중 하나로, 정규 표현식을 처리하는 기능을 합니다.Pattern.DOTALL: 이 플래그를 사용하면 정규 표현식의 "."이 \n , \r과 같은 줄바꿈 문자를 포함한 모든 문자와 일치합니다.Pattern.CASE_INSENSITIVE: 대소문자를 구분하지 않습니다.
기본적으로 정규 표현식의 .은 \n, \r과 같은 줄바꿈 문자를 제외한 모든 문자와 일치합니다. 따라서 어떤 문자열의 패턴을 검증하는 정규식 함수가 있는 경우, 해당 문자열에 줄바꿈 문자가 포함되어 있으면 정규식이 일치하지 않습니다. 이를 방지하기 위해 Pattern.DOTALL 플래그를 사용할 수 있습니다.
하지만 누군가 의도적으로 \n 대신 %0d를 사용하거나 \r 대신 %0a를 사용하면 위의 정규식은 여전히 일치하지 않습니다. 따라서 버전 5.6.4에서는 RegexRequestMatcherTests.java에 이 경우를 추가로 확인하는 코드가 추가되었습니다. 구체적으로, %0d와 %0a를 각각 \n과 \r로 변환한 후 정규식으로 확인합니다.

1단계: Spring Initializr를 사용하여 Spring Security와 Spring Web 두 가지 종속성이 포함된 Spring Boot 웹 애플리케이션을 생성합니다.

2단계: /admin/* 경로로 요청이 들어오면 This is a CVE-2022-22978 demo 문자열을 출력하는 Controller를 생성합니다.

3단계: 사용자가 /admin/<any> 경로에 접근할 때마다 인증 메커니즘을 설정합니다. regexMatchers("/admin/.*").authenticated()를 사용합니다. 이것이 공격자가 인증 없이 /admin/<any> 페이지의 내용을 보기 위해 악용하는 취약점입니다.

4단계: 구성 파일에서 취약점이 포함된 Spring Security 버전을 선언합니다. 여기서는 버전 5.6.3을 선택합니다.

5단계: gradlew bootRun 명령어로 애플리케이션을 실행합니다. 기본적으로 Apache Tomcat이 포트 8080에서 수신 대기합니다. /admin/xyz 경로에 접속합니다 (/admin/으로 시작하는 모든 경로 가능).

결과로 403 Forbidden 코드가 반환되며, 인증되지 않았기 때문에 접근할 수 없습니다.
이때 Sping Security(버전 5.6.3)의 regexMatchers 함수가 \r(%0d) 및 \n(%0a)와 같은 줄바꿈 문자를 일치시키지 못하는 취약점을 이용하여, /admin/%0dxyz 페이로드로 인증 없이 위 경로에 접근할 수 있습니다.

마찬가지로 /admin/%0axyz 페이로드도 가능합니다.

이와 같이 매우 간단한 페이로드만으로 CVE-2022-22978 취약점을 성공적으로 악용할 수 있었습니다.
5.7.1 등 수정된 버전 사용
동일한 페이로드인 /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