SSTI

개념

서버사이드 템플릿에 페이로드를 주입하여 서버측에서 임의 코드를 실행하거나 민감한 정보를 노출하게 할 수 있는 취약점이다.

템플릿 엔진은 고정된 템플릿과 휘발성 데이터를 결합하여 웹 페이지를 동적으로 생성한다. SSTI는 사용자의 입력이 데이터로서 전달되지 않고, 템플릿에 직접 연결될 때 발생할 수 있다. 즉, 템플릿 자체가 사용자의 입력에 의해 조작될 수 있을 때 발생할 수 있다. SSTI는 서버 측에서 실행되므로 일반적인 CSTI보다 잠재적으로 더 위험하다.

Impact

  • RCE
  • 백엔드 서버를 완전히 제어하고 이를 통해 내부 인프라에 대한 다른 공격을 수행할 수도 있다.
  • 서버의 민감한 데이터 읽기
  • XSS

SSTI 공격 짜기

크게 다음 절차를 거친다.

  1. Detect
  2. Identify
  3. Exploit
  4. Read
  5. Explore
  6. Attack

Detect

서버사이드 템플릿을 이용하는 곳을 찾는다. 초기 접근 방식으로는 ${{<%[%'"}}%\ 문자를 이용해 퍼징한다. 예외가 발생한다면 입력값이 어떤식으로든 템플릿으로 해석될 가능성이 있다고 볼 수 있다.

Plain context와 Code context 두 가지 관점으로 찾아보아야 한다. 위 퍼징에 걸리지 않더라도 이런 접근을 해보는 것이 좋다.

Plain context

대부분의 템플릿 언어는 HTML 태그를 직접 사용하거나, 템플릿의 구문을 사용하여 컨텐츠를 자유롭게 입력할 수 있다. 서버사이드 템플릿은 렌더링을 서버에서 하여 HTTP Response로 주기에 XSS 등에 이용할 수 있다.

Code context

greeting = getQueryParameter('greeting')
engine.render("Hello {{"+greeting+"}}", data)

예를 들어 위와 같은 코드가 있고, http://vulnerable-website.com/?greeting=data.username 와 같이 파라미터를 지정한다고 하자. 이 때, data.username은 변수 이름이다.

이 경우 우리의 입력값이 변수 이름으로 해석되므로 직관적으로 XSS 취약점으로 보이지는 않는다.

템플릿 종류별 공격 예

ERB template

ruby에서 사용하는 템플릿 엔진이다.

참고 문제: Portswigger-Basic server-side template injection

Django template engine

python의 django 프레임워크에서 사용하는 템플릿 엔진이다.

참고 문제: Portswigger-Server-side template injection with information disclosure via user-supplied objects

참고 링크: Django-Templates-Server-Side-Template-Injection

Tornado template

python에서 사용하는 템플릿 엔진이다.

참고 문제: Portswigger-Basic server-side template injection (code context)

FreeMaker template

Java에서 사용하는 템플릿 엔진이다.

참고 문제: Portswigger-Server-side template injection using documentation

Handlebars template

nodejs에서 사용하는 템플릿 엔진이다. 임의 코드를 실행하기 위해서는 약간 더 복잡한 페이로드를 짜야한다.

참고 문제: Portswigger-Server-side template injection in an unknown language with a documented exploit

참고 링크

참고


tags: web hacking, erb, freemaker, handlebars