[WesternCTF2018]shrine
[WesternCTF2018]shrine
题目直接给出源代码
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.config['FLAG'] = os.environ.pop('FLAG')
这句表明讲系统中的flag变量付给了app.config的flag变量
所以我们本题就是要访问config
而有黑名单
def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
config和self都被禁了
所以我们要另辟蹊径来读取config
要读取config,不能直接读,要从全局变量那里读
而flask中全局变量有四个
current_app代表当前flask程序实例
g作为flask程序全局的临时变量
requests客户端发送的HTTP请求内容
session用户会话
所以一眼看过去就差不多知道,只有current_app和这道题有关
而全局变量是变量,既然是变量,那么必然在变量的集合函数中
所以我们要在____globals____中找current_app
他是python中所有变量集合
我们只能通过函数去调用
flask自带的函数中有url_for和get_flashed_messages()可以用
其他的我试了试不行,不知道为啥,可能时因为防火墙或者别的原因,有知道的师傅可以指教
最后playload
{{url_for.__globals__['current_app'].config}}
浙公网安备 33010602011771号