[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}}
posted on 2021-01-27 15:32  猪猪侠的哥哥  阅读(109)  评论(0)    收藏  举报