打开题目就得到了python代码
import flask
import os
#导包
app = flask.Flask(__name__)
#创建一个flask实例,
app.config['FLAG'] = os.environ.pop('FLAG')
#从操作系统的环境变量中读取名为FLAG的值,并将其存储在Flask的配置中,POP:读取后删除该环境变量@app.route('/')
#定义一个路由`/`,访问主页时触发这个函数
def index():return open(__file__).read()
#读取当前python脚本的源代码并返回@app.route('/shrine/<path:shrine>')
#动态路由,shrine变量代表传入的路径参数,允许传入包含`/`的url片段
def shrine(shrine):def safe_jinja(s):s = s.replace('(', '').replace(')', '')#将括号换成nullblacklist = ['config', 'self'] return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + sreturn flask.render_template_string(safe_jinja(shrine))#flask.render_template_string:将传入字符串作为Jinja2模板进行渲染,这个模板会经过safe_jinja(shrine)清理后再进行渲染if __name__ == '__main__':app.run(debug=True)#运行flask应用
由第二个路由可以知道可以传入一个形如/shrine/...的地址,最后也是成功测试出来了
而首先要明白的是这个题存在两个过滤,一个是括号()
,一个是config,self
,那么常用的注入方式就不管用了
而我们前面看到config,这里面应该会有个flag值
这里就要用到python里的内置函数了,如url_for,get_flashed_messages
注入{{url_for.__globals__}}
访问url_for函数的全局属性,查看里面的变量信息
输入{{url_for.__globals__['current_app'].config}}
,查看当前的配置信息,拿到flag