문제는 다음과 같다.
존재하지 않는 페이지 방문시 404 에러를 출력하는 서비스입니다. SSTI 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다. |
문제 정보를 확인한 뒤,
가상환경에 진입하면 다음과 같이 나온다!
해당 두 개의 링크 중 위로 들어가게 되면
404 에러를 출력하는 /404Error 페이지가 나오고,
밑에 robots.txt 링크를 클릭하면
해당 경로와 Page Not Found 페이지가 나오게 된다.
이렇게 두 경로의 페이지만으로는 정확히 알기가 어렵다.
우선, SSTI 취약점이 무엇인지 살펴보자!
다음 내용은 이글루 시큐리티를 참고하였다.
SSTI 취약점이란?
SSTI(Server Side Template Injection) 취약점은 웹 템플릿 엔진에
공격자의 공격코드가 템플릿에 포함된 상태에서
서버에서 템플릿 인젝션이 발현되는 공격을 의미한다고 설명이 나와있다.
위의 내용에서 나오는 웹 템플릿 엔진은
브라우저에서 출력되는 웹 문서를 위한 템플릿 엔진이라고 한다.
예로 들면, 네비게이션 바와 같이 같은 내용을 반복적으로 작업을 수행하여
작업을 최소화할 수 있는 것을 바로 웹 템플릿 엔진이라고 할 수 있다.
즉, 반복되는 요소를 템플릿화하여 동적으로 변경되는 데이터 부분만 결합하여
개발자가 소스코드를 효율적으로 관리하고 직관적인 확인이 가능해진다.
출처에 나온 템플릿 엔진이 적용된 소스코드를 살펴보았을 때,
navbar.html을 작성해두고 파이썬 프레임워크(플라스크, 장고)의 템플릿 태그로하여,
{% block content %} {% endblock %} 및 {% block script %} {% endblock %}으로
네비게이션 바를 효율적으로 관리하고 있는 모습을 보여주고 있다.
나는 장고를 간단하게 공부해봤기 때문에 수월하게 이해할 수 있었다.
하지만, 이러한 편리함도 잠시 SSTI는 웹 템플릿 엔진을
공격하는 행위이기 때문에 위험하다고 볼 수 있다.
이러한 템플릿 태그 코드에 공격자가 템플릿 구문을 이용한 악성 페이로드를 삽입하게 되면
공격자가 원하는 액션을 수행하도록 할 수 있는 것이 바로 SSTI 취약점이다.
또한, SSTI는 XSS, CSRF 뿐만 아니라
RCE, SSRF 공격으로도 연결될 수 있어서 위험도가 높다고 한다.
이러한 SSTI 취약점을 점검하기 위해서는 템플릿 별 문법을 숙지하고 있어야 한다.
해당 취약점 대응방안으로 render_template_string() 함수가 아닌,
render_template() 함수를 사용하여 대처하는 등의 대응방안이 존재한다.
또는, Input Validation 으로 특수문자 구문들을 escape 처리한다.
어쩌다보니, SSTI 취약점 공부시간으로 가게 되었는데
이번에는 문제의 코드를 살펴보자!!
app = Flask(__name__)
try:
FLAG = open('./flag.txt', 'r').read()
except:
FLAG = '[**FLAG**]'
app.secret_key = FLAG
@app.route('/')
def index():
return render_template('index.html')
@app.errorhandler(404)
def Error404(e):
template = '''
<div class="center">
<h1>Page Not Found.</h1>
<h3>%s</h3>
</div>
''' % (request.path)
return render_template_string(template), 404
app.run(host='0.0.0.0', port=8000)
인덱스 경로에는 볼게 없는것 같고,
Error404 함수에서는 errorhandler404를 핸들링해주고 있는 모습이다.
이때, 위에서 살펴본 SSTI 취약점인 render_template_string 함수를 사용하고 있는 것을
볼 수가 있다. (이걸 위해 공부한것인가..!!!)
또한, 렌더링되고 있는 html에 %s 문자열을 받고 있고 request.path를 받고 있다.
그렇다면 우리는 /flag.txt를 출력해야하고, 현재 /robots.txt가 입력되어있던것처럼
값을 조작하게 된다면..?
바로 행동에 옮겨보자.
h3 태그로 받고 있는 곳이 request.path이고 해당 내용을 조작하기위해
host.dreamhack.games:port/404Error URL의 파라미터 값을 조작하게 된다면?
어림도 없다.
왜냐하면, FLAG는 app.secret_key에 저장되어 있기 때문이다.
여기서 템플릿 언어를 사용하여 secret_key를 출력하는 방법은 다음과 같다.
해당 app.py는 플라스크로 작성되어있고,
중요 설정 내용들은 config에 들어있기에 {{config}}를 작성해주면 된다!!
그럼 다음과 같이 config 설정 내용들이 출력되고,
FLAG 값이 출력된다!!
Clear.
'CTF > 웹해킹' 카테고리의 다른 글
[Dreamhack] session (0) | 2022.09.14 |
---|---|
[Dreamhack] web-misconf-1 (0) | 2022.09.13 |
[Dreamhack] php-1 (0) | 2022.09.01 |
[Dreamhack] proxy-1 (0) | 2022.08.30 |
[Dreamhack] pathtraversal (0) | 2022.08.29 |