从一道ctf题谈SmartySSTi
字数 1073 2025-08-15 21:34:04
Smarty模板引擎SSTI漏洞分析与利用
1. Smarty简介
Smarty是一个PHP的模板引擎,提供前后端代码分离的功能。它比Laravel、ThinkPHP等主流框架更轻量,类似于Flask的模板系统。
2. SSTI漏洞确认
确认Smarty SSTI漏洞的方法:
- 输入
{$smarty.version}可以查看Smarty版本号 - 尝试注入简单表达式如
127.0.0{1+2},如果执行则存在SSTI
3. 漏洞环境分析
示例题目环境:
- Smarty版本:3.1.30
- PHP版本:7.x
- 漏洞代码:
<?php
require_once('./smarty/libs/' . 'Smarty.class.php');
$smarty = new Smarty();
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$smarty->display("string:".$ip);
}
4. 利用方式分析
4.1 传统方法失效
-
{php}{/php}标签:- 在Smarty 3中已废弃
- 仅在SmartyBC中可用
- 使用会报错
-
{literal}标签:- 用于让模板区域字符原样输出
- 在PHP5中可结合
<script language="php">phpinfo();</script>执行代码 - PHP7环境下失效
-
静态方法利用:
- 旧版Smarty可使用
{self::getStreamVariable("file:///etc/passwd")} - 3.1.30版本已删除该方法
- 会报错:"static class 'self' is undefined or not allowed by security setting"
- 旧版Smarty可使用
4.2 有效利用方法
4.2.1 使用{if}标签
Smarty的{if}条件判断:
- 语法与PHP的if相似
- 支持所有PHP条件表达式和函数
- 必须配对使用
{/if} - 可以使用
{else}和{elseif}
利用payload示例:
{if var_dump(file_get_contents('/flag'))}{/if}
4.2.2 实际利用步骤
- 通过可控的输入点注入Smarty标签
- 使用
{if}标签包裹PHP函数调用 - 常用函数:
file_get_contents()- 读取文件system()- 执行系统命令var_dump()- 输出变量信息
5. 防御措施
- 避免直接使用用户输入作为模板
- 对用户输入进行严格过滤
- 使用最新版本的Smarty
- 禁用不必要的Smarty功能
6. 总结
Smarty SSTI利用要点:
- 确认Smarty版本和PHP环境
- 在Smarty 3.1.30+环境中,
{if}标签是最可靠的利用方式 - 可以利用所有PHP函数执行任意代码
- 传统方法在较新版本中大多已失效
7. 参考资源
- Smarty官方文档
- [CISCN2019华东南赛区Web11]题目
- Smarty 3.1.30源代码分析