Post

Spring View Name Manipulation Exploit (Thymeleaf SSTI)

Spring View Name Manipulation Exploit



1
2
3
4
5
6
7
8
9
@Controller
public class HelloController {

    @GetMapping("/")
    public String index(Model model) {
        model.addAttribute("message", "happy birthday");
        return "welcome";
    }
}


위와 같은 코드가 있다고 가정할 때, 위의 코드에서 @Controller@GetMapping("/") annotation이 있는데, 이를 통해 “/”로의 매 HTTP 요청마다 메소드가 호출될 것이다.

루트 url은 어떠한 매개변수도 받지 않으며, 단순히 “welcome”을 리턴할 뿐이다.

Spring Framework는 “welcome”을 View Name으로 해석을 하여, resources/templates/welcome.html을 찾으려 할 것이다.

찾았다면, 렌더링한 후 클라이언트에게 보내준다.


1
2
3
4
@GetMapping("/path")
public String path(@RequestParam String lang) {
    return "user/" + lang + "/welcome"; //template path is tainted
}


위에서 리턴 값은 View Name으로 해석된다고 했다.

그럼 user/{lang}/welcome이라는 파일을 resources/template 같은 템플릿이 들어있는 경로 내에서 찾게 될 것이다.

그러나 파일 시스템에서 템플릿을 렌더링 하기 전에 아래와 같은 코드를 거친다고 하는데, 여기서 취약점이 발생한다.


1
2
3
4
try {
   // By parsing it as a standard expression, we might profit from the expression cache
   fragmentExpression = (FragmentExpression) parser.parseExpression(context, "~{" + viewTemplateName + "}");
}


리턴 값인 View Name이 바로 viewTemplateName 값이 되는데, 코드를 보면 ~{}로 감싸져 있다.

만약 리턴 값에 다른 Thymeleaf expression (e.g ${}가 포함되어 있다면 ~{ ${} }가 되어 ${7*7} 같은 값이 49로 처리가 되어 리턴이 되는데, 이러한 파일은 경로에 없으므로 에러가 발생하게 된다.

에러가 발생하면 페이지를 보여주는 등 하게 되는데, 그 에러 페이지에 에러 문구로 값이 출력이 되어있으므로 SSTI 취약점이 발생하는 것이다.


기본 Payload로 ${T(java.lang.Runtime).getRuntime().exec('calc') 등이 있다.






참고 자료



Link
github.com/veracode-research/spring-view-manipulation
pulsesecurity.co.nz/articles/EL-Injection-WAF-Bypass






This post is licensed under CC BY 4.0 by the author.