티스토리 뷰

웹 해킹/취약점

SSTI 취약점

삼전동해커 2020. 9. 24. 14:36

SSTI에 대해 알아보자.

출처:https://www.lanmaster53.com/2016/03/11/exploring-ssti-flask-jinja2-part-2/

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

SSTI란?

ssti란 Server-Side Template Injection이란 의미이다.
ssti를 이해하기 전에 정적/동적 웹페이지에 대해 알아야 한다. 

정적 웹 페이지는 간단한 html을 사용해 페이지를 만들고 서버에 저장해, 불러온 그대로의 모습을 보여주는 방식이다. 

동적 웹 페이지는 사용자가 작성하거나 선택한 이벤트에 따라 웹 페이지의 구성과 내용이 달라지는 방식이다. python의 flask나 자바스크립트 같은 다양한 언어가 있다.

그럼 템플릿 언어는 무엇일까? 
템플릿 언어란 언어의 변수 및 문법을 html 안에서 쓸수 있도록 제공해주는 언어이다.
django의 경우는 파이썬과 html을 같이 사용할 수 있다. 이런 템플릿을 이용하면 구성하기 간단하면서 동적인 페이지를 만들 수 있다.

그래서 SSTI란?

사용자와 동적으로 작동하는 템플릿의 방식의 취약점인 RCE(Remote Code Execution)이 템플릿에 들어가면 악의적인 행동이 발생할 수 있다.

flask의 jinja2 문법을 사용할 경우 {{...}} 이렇게 템플릿을 사용한다. 이 곳에 {{7*7}}과 같이 사용하면 49의 결과값을 출력한다.
이 말은 코드가 실행 된다는 점이다. 그래서 RCE 취약점이 나타난다.

예제를 만들어 보자.


위와 같이 템플릿을 만들었다.
class Secret을 만들고 __init__함수로 user와 password를 받아서 초기화 해준다.
secret이라는 객체를 만들어 username과 password를 전달한다.

페이지 접속 시, home()함수가 실행되어 title로 "this is title"이 전달되고,
content는 request.args.get으로 content값을 받아 저장한다.
thisistemp로 html구문을 입력하고, title이 들어갈 자리를 만들고,
get으로 입력한 content는 %s로 받아준다. 여기서 취약점이 발생한다.


일단 템플릿을 실행하면



그럼 content에 {{7*7}}을 주고 실행해 보자.



49도 같이 출력되었다.



이번엔 config.items()를 넣어보자.




이 객체는 딕셔너리 형태로 현재 설정되어 있는 config를 출력해준다.

여기서 대부분 중요한 설정들을 볼수 있다. 


config에 추가되는 객체는 객체의 타입이 변하지 않기 때문에 함수를 저장하면 함수가 그대로 실행된다.


그럼 {{config.from_object('os')}}*를 search에 넣어주어 os라이브러리에 있던 config들을 추가시켜본다.



이렇게 한 후,

다시 config.items()를 열어보면



뭐가 더 생겼다. os라이브러리에 설정되어 있던 config가 추가된 것이다.


os라이브러리를 추가하는것에 대해서 원문에서는 단지 os 라이브러리의 변수명이 대문자인 객체들을 추가해주기 위해서. 라고 나와있다. 

여기서는 사용되지 않는걸 보니 그냥 객체를 추가하는 방법을 설명하는거라 생각된다.



파이썬의 __mro__는 클래스의 튜플로 base classes를 찾을 때 사용된다.

__subclass__는 상속을 받는 클래스가 어떻게 구성되어 있는지 출력한다.

2개의 메소드를 사용해서 부모클래스와 자식클래스에뭐가 있는지를 확인할 수 있다.


먼저 {{''.__class__.__mro__}}를 넣어보자.

__mro__를 사용하여 root클래스에 접근해보자.




''을 사용해 타입str을 리턴하고, __mro__을 사용해 root 클래스에 접근할 수 있다.

str 타입이 0번째 인덱스이고 object타입이 1번째 인덱스이니 1인덱스를 사용해 object타입을 선택하자. 현재 우리의 위치가 root 객체이니, __subclasses__를 이용해 상속받은 클래스가 뭔지 알아보자.


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

이렇게 넣어보면



엄청 많은 클래스가 상속되어 출력된다.

여기서 필요한 클래스가 있으면 인덱스를 찾아 사용하면 된다.


Popen클래스를 찾아보자.



여기의 위치가 어디인지 모르니 대충 짐작으로 400번째라고 해보자.

슬라이싱을 이용해


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

이렇게 입력해 보면



408번째 인덱스에 위치해 있다.

Popen을 활용해 다음과 같이 ls 명령어를 구성했더니

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




진짜 내 디렉토리에 있는 목록이 출력되었다.



ssti에 대해 설명 해놓은 자료가 없어서 영문 찾아서 혼자 공부했다.


'웹 해킹 > 취약점' 카테고리의 다른 글

NOSQL - mongoDB  (0) 2021.07.20
SIP 취약점  (0) 2021.04.29
파이썬 pickle을 이용한 serialize 취약점  (0) 2020.09.21
type juggling  (0) 2020.09.18
eval 함수  (0) 2020.09.15
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함