Portswigger-Server-side template injection with information disclosure via user-supplied objects
풀이
SSTI 취약점이 있다. 이 취약점을 이용하여 민감한 데이터에 접근할 수 있다. content-manager:C0nt3ntM4n4g3r 계정으로 로그인할 수 있다. 프레임워크의 비밀키를 알아내어 등록하라.

로그인 한 뒤 아이템 상세 페이지에 접근하면 Edit template 이라는 버튼이 추가된다.

버튼을 누르면 템플릿 내용을 편집할 수 있는 페이지로 이동한다. {{product.name}} 과 같이 변수를 참조하는 듯한 내용이 보인다. preview 버튼을 누르면 위 내용을 서버사이드 템플릿을 이용해 내용을 채워넣어 준다.

{{7*7}} 과 같은 흔한 페이로드를 넣어보면 다음과 같은 에러메시지가 뜬다. 에러메시지를 통해 이 웹서버는 django로 만들어졌다는 것을 알 수 있다. 에러 발생 위치가 "/usr/local/lib/python2.7/dist-packages/django/template/base.py" 인 것으로 보아 django 기본 템플릿 엔진(Django Template Engine)에서 터진 것을 알 수 있다.
Django Template Engine은 {%%}로 둘러싸인 형태(템플릿 태그)와 {{}}로 둘러싸인 형태(변수)의 문법을 따른다. 템플릿 태그는 if문, for문 등 흐름을 제어하는 데 쓰이고, 변수는 출력하고 싶은 변수를 지정하는 데 쓰인다.

템플릿 태그는 미리 정의되어있는 것이 있는데, 그 중 {% debug %} 는 현재 컨텍스트 정보와 임포트된 모듈을 출력해준다. 이를 SSTI를 통해 띄웠다.

이 문제의 목표는 비밀키를 알아내는 것이다. settings 라는 변수에 민감한 데이터가 있을법하여 조사해보니 settings는 UserSettingsHolder 클래스 인스턴스라고 찍힌다. 이는 django의 setting 관련 클래스이다. django 프레임워크는 프로젝트를 생성하면 설정값 디폴트로 SECRET_KEY 라는 변수에 랜덤 문자열을 저장한다. 그리고 이를 토큰 등 랜덤값 생성 작업등에 사용한다. (따라서 이를 그대로 github에 올리면 취약점이 되기도 한다.)
이는 변수 settings.SECRET_KEY 로 접근할 수 있다.
- 참고

{{settings.SECRET_KEY}} 페이로드로 비밀키를 출력하였다. 이를 상단의 submit 란에 제출하면 성공한다.
이 취약점은 사용자가 입력한 값을 검증하지 않아서, SSTI 페이로드를 sanitize 하거나 인코딩하지 않고 처리했기에 발생했다.
tags: writeup, ssti, wstg-inpv-18, django, django-template-engine, web hacking