본문 바로가기

SWUFORCE 워게임👊🏻

[Dreamhack] LEVEL1 ; web ; Simple-ssti

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)가 그대로 노출되었다.

 

풀이 완👊🏻