개념정리
SSTI에 대한 개념을 간단하게 짚고 넘어가자.
○ SSTI
SSTI(Server Side Template Injection)취약점은 웹 어플리케이션에 적용된 웹 템플릿 엔진(Web Template Engine)에 공격자의 공격 코드가 템플릿에 포함된 상태에서 서버 측에서 템플릿 인젝션 되는 공격
SSTI 취약점은 서버 측에 Template이 구성되어 있고 사용자 입력이 기존 Template에 삽입되는 경우 공격자는 Template 구문을 이용해 악성 페이로드를 삽입하여 공격자가 원하는 액션을 수행하도록 하는 공격이다.
[그림]의 SSTI 공격 구성도와 같이 공격자가 kw에 {{ 2*2 }}
라는 Template 구문을 입력하면 사칙연산 결과인 4라는 값이 리턴되면서 공격자가 삽입한 Template구문이 실행되는 과정을 확인할 수 있다.
SSTI가 발생하는 경우에는 Server-Side 측의 웹 문서 로드 시 동작하는 렌더링에 관여할 수 있기 때문에, 단순히 Client-Side 취약점 공격(XSS, CSRF) 뿐만 아니라, Server-Side 취약점 공격(RCE, SSRF)으로도 연결될 수 있어서 위험도가 높다.
SSTI에 대한 점검 시 사용하는 악성 페이로드는 Template마다 구문이 상이해서 Template 별로 문법을 숙지하고 있어야한다.
문제분석
My Pages에 하이퍼링크(404Error, robots.txt)가 걸려있는 것을 볼 수 있다.
[404Erorr]를 누르면 /404Erorr
페이지에 접속되고 에러 페이지가 나온다.
SSTI가 발생하는 부분은 위와 같다.
요청 시, 전달 받은 request.path
를 template
에 넣어 render_template_string()
로 랜더링한다.
이 과정에서 request.path
에 대한 검증을 수행하지 않고 render_template_string()
을 사용하고 있으므로 {{}}
형태의 템플릿 코드를 입력한다면, 템플릿 코드가 실행되면서 서버 내부의 정보를 가져올 수 있다.
문제풀이
{{cycler.__init__.__globals__}}
SSTI payload는 템플릿 환경에 맞게 다양하게 구성할 수 있지만, Flask Jinja template
으로 랜더링하는 환경이므로 cycler object
를 이용해서 SSTI payload를 구성했다.
[그림]은 cycler object
를 통해 globals
에 접근해서 글로벌로 선언된 모듈을 확인한 결과다.
RCE를 수행해야하므로 중요한 모듈은 os
다.
○ payload
{{cycler.__init__.__globals__.os.popen('cat flag*').read()}}
os 모듈의 popen()
을 이용하면 파일을 읽고 출력할 수 있다. flag.txt
를 읽고 출력하는 템플릿 코드를 작성했다.
전송해보자.
대응방안
○ Sanitization
사용자의 입력값을 통해 template을 생성하는 서비스를 구성하지 말아야한다.
만약, 사용자의 입력값을 받아야하는 상황이라면 template에서 제공하는 파라미터를 통해 입력값을 처리하도록 해야한다.
예를 들어, Jinja Template
경우에는 render_template_string()
가 아닌 render_template()
를 사용하면 사용자가 입력한 Template 구문을 명령어가 아닌 문자열로 해석한다.
즉, {{5*5}}
를 입력했다면, 25라는 결과가 나오는 것이 아니라 {{5*5}}
가 그대로 출력된다는 뜻이다.
○ Input Validation
"{", "[", "<", "%", "#", "@"
등 SSTI exploit 과정에서 사용할 수 있는 특수문자들에 대한 검증을 수행한다.
○ Sandboxing
사용자 입력 값을 기반으로 Template을 생성하고 렌더링해야 하는 경우 어쩔 수 없이 사용자 입력으로 Template을 처리할 수 밖에 없다. 이때, 사용자 입력으로부터 받는 Template은 샌드박싱하여 공격코드가 실제로 영향을 끼칠 수 없도록 제한하는 방법으로도 대응할 수 있다.
reference
https://dohunny.tistory.com/20
https://www.hahwul.com/cullinan/ssti/