

1. 접속하면 my page로 404Error, robots.txt가 있다.
둘 다 접속하면 Page Not Found가 뜬다.
template = '''
<div class="center">
<h1>Page Not Found.</h1>
<h3>%s</h3>
</div>
''' % (request.path)
return render_template_string(template), 404
2. 문제 코드 중 핵심 부분을 살펴보겠다.
- request.path (사용자 제어값, URL 경로)이 파이썬의 문자열 포맷으로 템플릿 내부에 그대로 삽입된다.
- 삽입된 전체 문자열을 render_template_string()으로 Jinja 템플릿 엔진이 렌더링한다.
* Jinja 템플릿이란? 간단한 문법으로 html에서 {}, {{}} 등의 규칙을 이용하여 python 프로그래밍이 가능한 것을 말한다. - 따라서 {{ ... }} 같은 Jinja 표현식을 request.path로 주면, 서버가 그 표현식을 서버 측에서 실행한다.
이는 SSTI (Server-Side Template Injection) 으로 이어진다.
따라서 먼저 간단한 표현식을 넣어 템플릿 렌더링이 되는지 확인 후 플래그 시도를 해보았다.

3. 간단한 표현식 '{{7*7}}' 을 넣어 404 페이지의 <h3> 안에 49가 보이는지 확인했다. 이는 템플릿이 평가된다는 것을 의미한다. 이어서 문제 코드에서 app.secret_key = FLAG로 설정해뒀으므로 '{{config.SECRET_KEY}}'를 입력했다.

4. 플래그나 나왔다.
5. 간략하게 풀이 방법을 정리해보겠다.
- 문제 코드에서 FLAG = open('./flag.txt').read()로 플래그를 읽고 app.secret_key = FLAG로 설정해 두었다.
- app.secret_key = ...는 내부적으로 app.config['SECRET_KEY']에 값을 저장한다.
- 404 핸들러가 request.path(사용자 제어값)을 render_template_string(...)에 넣어 Jinja가 평가하도록 했다.
- 사용자가 URL에 {{config.SECRET_KEY}}를 넣으면 Jinja가 config 객체를 찾아 SECRET_KEY 값을 평가해 템플릿 출력으로 반환한다.
- 그 결과 404 페이지 안에 SECRET_KEY(=FLAG)가 그대로 노출되었다.

풀이 완👊🏻
'SWUFORCE 워게임👊🏻' 카테고리의 다른 글
| [Dreamhack] LEVEL1 ; reversing ; Happy New Year! (0) | 2026.01.13 |
|---|---|
| [워게임 실습] Simple-ssti ; web (0) | 2025.11.04 |
| [Dreamhack] TOP secret! ; crypto (0) | 2025.10.28 |
| [워게임 실습] Heartbeat (1) | 2025.09.24 |
| [Dreamhack] LEVEL1 ; web ; Disgusting Ads (0) | 2025.09.23 |