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仍受影响
- 目前尚未修复
技术细节:
- 触发漏洞后会在
templates_c目录生成两个模板编译文件 - 第一个文件调用
content_[hash1]函数 - 第二个文件调用
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. 漏洞代码位置
-
CVE-2021-26120:
libs/sysplugins/smarty_internal_compile_function.phpSmarty_Internal_Compile_Function->compile()方法
-
CVE-2021-29454:
libs/plugins/function.math.phpsmarty_function_math函数
5. 防御建议
- 及时升级到最新修复版本
- 对用户输入进行严格过滤
- 避免在模板中直接使用用户可控数据
- 禁用危险函数如
eval() - 限制Smarty的权限和可访问目录
6. 参考资料
- Smarty GitHub仓库
- 官方漏洞公告
- PHP安全编程指南