Wolf CMS 新旧两个版本中的文件上传漏洞分析

一、Wolfcms简介

Wolf CMS是一款内容管理系统(CMS),是在GNUGeneral Public License v3下发布的免费软件。Wolf CMS是由PHP语言编写,是Frog CMS的一个分支。在2010年Packet Publishing开源项目评奖的“Most Promising Open Source Project”分类中杀进了决赛。

软件的官网为:https://www.wolfcms.org/

二、Wolfcms 0.8.2中存在任意文件上传漏洞

2.1 Wolf CMS 0.8.2版本中漏洞概述

早在2015年4月,Wolf CMS就被发现其后台存在任意文件上传漏洞,攻击者可以利用这个漏洞上传恶意的PHP文件,最终的结果是系统被攻击者控制,可以执行任意的指令。此漏洞具体是出现在文件管理功能中,这个功能原本是提供一个接口让管理员管理文件。

在此版本的代码中,对于允许上传的文件类型没有做任何的限制。因此攻击者可以上传一个PHP shell文件,文件中的代码是恶意的,导致系统被完全控制。

2.2 Wolf CMS 0.8.2版本漏洞利用过程

在本地搭建了网站环境,复现了攻击过程,如下:

在“Files”选项卡中点击右下角的“Upload file”选项可以执行上传操作

选择要上传的一句话木马文件,本例中它的名字是“ma2.php”

可以看到这个webshell文件被成功地上传到了网站中。

系统还提供了编辑文件的功能,在这里我们可以查看一下刚才所上传webshell的代码。

通过一句话木马客户端去连接这个木马,发现可以执行,因此证明此漏洞可以被攻击者所利用来完全控制网站。

2.3 漏洞源码分析

漏洞点出现在:/wolf/plugins/file_manager/FileManagerController.php

从第302行到339行是实现上传功能的函数upload()。

我们来逐条解读一下代码的功能,首先

if (!AuthUser::hasPermission('file_manager_upload')) {
    Flash::set('error', __('You do not have sufficient permissions to upload a file.'));
    redirect(get_url('plugin/file_manager/browse/'));
}

是验证用户是否拥有上传文件的权限,如果没有的话打印警告信息,并且将浏览器重定向到‘plugin/file_manager/browse/‘位置。

随后是检查CSRF的token,通过标签的方式防止CSRF攻击的发生。

if (isset($_POST['csrf_token'])) 
{
   $csrf_token = $_POST['csrf_token'];
   if (!SecureToken::validateToken($csrf_token, BASE_URL.'plugin/file_manager/upload')) {
       Flash::set('error', __('Invalid CSRF token found!'));
       redirect(get_url('plugin/file_manager/browse/'));
   }
}
else {
   Flash::set('error', __('No CSRF token found!'));
   redirect(get_url('plugin/file_manager/browse/'));
}

这段代码首先检查csrf_token这个变量是否在POST请求中被设置,如果被设置的话,那么将这个值赋值给$csrf_token,随后通过SecureToken::validateToken函数验证token的有效性,如果未通过验证,则打印警告信息,并且将浏览器重定向到‘plugin/file_manager/browse/‘

如果POST请求中没有token被传递过来,则也执行类似的操作。接下来的操作是关键:

$data = $_POST['upload'];
$path = str_replace('..', '', $data['path']);
$overwrite = isset($data['overwrite']) ? true : false;

这里面首先删除了路径中的切换字符“..”

$filename = preg_replace('/ /', '_', $_FILES['upload_file']['name']);
$filename = preg_replace('/[^a-z0-9_\-\.]/i', '', $filename);

随后删除了文件名中的空格,并且只保留小写字母从a~z,数字0~9,下划线,短横线以及点号,剩下的字符一律删除。

if (isset($_FILES)) {
   $file = $this->_upload_file($filename, FILES_DIR . '/' . $path . '/', $_FILES['upload_file']['tmp_name'], $overwrite);
   if ($file === false)
       Flash::set('error', __('File has not been uploaded!'));
}

最后执行upload_file函数将文件上传到系统中,纵观整个过程,并没有对上传的文件类型进行安全检查,导致了攻击者可以上传webshell。

三、Wolfcms 0.8.3.1中存在任意文件上传漏洞

3.1 Wolf CMS 0.8.3.1版本中漏洞概述

最近由于工作原因,我需要挖一些Web漏洞。于是想起了Wolf CMS 0.8.2中的文件上传漏洞,也就是本文的第二部分介绍的。查看目前Wolf CMS的版本,已经发布了0.8.3.1版本。出于好奇,我查看了一下此文件上传漏洞是否已经被修补,结果是:系统对上传的文件后缀名做了黑名单检查,但是众所周知,这也并不安全,可被绕过。

3.2 Wolf CMS 0.8.2版本漏洞利用过程

在本地搭建了网站环境,复现了攻击过程,如下:

仍旧是在“Files”标签下的右下角“Upload file”处触发上传文件操作。

这次我们的客户端环境是在ubuntu下,因为我们在这里可以命名webshell文件名为“ma2.php.”(注意文件名最终是以点号结束),在windows系统下则不允许这样命名。

由于服务器端是搭建在windows操作系统中,上传这个文件后,webshell文件名最后的点号会被自动删除。

查看此文件的源码,可见我们上传的确实是一句话木马。

仍旧利用一句话木马客户端去连接,结果表明连接成功。证明新版本虽然做了一些安全措施但是可被绕过。

2.3 漏洞源码分析

漏洞点出现在:/wolf/plugins/file_manager/FileManagerController.php

从第310行到354行是实现上传功能的函数upload()

我们可以看到大部分的代码与之前的0.8.2版本是一致的,不同之处在第340至345行。

 $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
 $ext_arr = array('php', 'php3', 'php4', 'inc');
 if (in_array($ext, $ext_arr)) {
    Flash::set('error', __('Not allowed to upload files with extension :ext', $ext));
    redirect(get_url('plugin/file_manager/browse/'));
 }

这部分代码首先取出用户所上传文件后缀名并且转换为小写。

随后定义了一个数组,数组中定义了不允许上传的后缀名。

检查用户上传文件的后缀名是否在数组中,如果在的话则打印报警信息,并且将浏览器重定向到路径‘plugin/file_manager/browse/‘下。

我们上传的文件名为“ma2.php.”后缀名不在黑名单数组中,因此允许上传,由于服务端安装在windows系统上,因此会自动删除最后那个点号,因此这个一句话木马文件成为了可执行的文件。攻击成功。

四、总结

通过上述内容再次证实了那个众所周知的道理:利用文件后缀名黑名单的方法是无法有效地修补文件上传漏洞。一般来讲,有效的防御方法有:

1.将文件上传的目录设置成不可执行; 2.通过白名单而非黑名单的方法决定哪些类型的文件是允许被上传的; 3.使用随机数改写文件名或者文件路径。 4.如果上传的是图片文件,则可以进行二次渲染。

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2017-07-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏散尽浮华

DNS之BIND使用小结(Forward转发)

之前详细介绍了DNS及其在linux下的部署过程,今天再说下DNS的BIND高级特性-forwarder转发功能。比如下面一个案例: 1)已经在测试环境下部署了...

7663
来自专栏C/C++基础

shell脚本实例

检查脚本书写完成后,需要crontab来定期执行该脚本,意在每隔多长时间去检测一次。crontab命令选项如下:

1222
来自专栏追不上乌龟的兔子

用.NET Core构建安全的容器化的微服务

微服务热潮正在如火如荼地进行,也有着充分的理由。它不是每个问题的银弹,但它无疑成为企业软件系统中可扩展性和弹性的实用解决方案。

4054
来自专栏技术之路

将某个Qt4项目升级到Qt5遇到的问题[转]

该Qt4项目以前是使用Qt4.7.4 MSVC2008开发的,因为使用到了OWC10(Office Web Components),使用MSVC编译器的话无法正...

2439
来自专栏张首富-小白的成长历程

saltstack的key认证过程

将192.168.56.11作为master,将192.168.56.12作为minion

2165
来自专栏非著名程序员

你可能不知道的10款Android开发辅助工具

1XAppDbg XAppDbg是一个可以在运行中改变代码中参数的一个应用开发工具。这个工具可以为你省下大量的时间,因为你不用为应用的每次小改变而重新编译运行你...

1967
来自专栏信安之路

Powershell绕过执行及脚本混淆

为什么需要 powershell ?存在必然合理。微软的服务器操作系统因为缺乏一个强大的 Shell 备受诟病。而与之相对,Linux 的 Shell 可谓丰富...

2150
来自专栏博岩Java大讲堂

Java日志体系(log4j2)

4399
来自专栏非著名程序员

10款你可能不知道的Android开发辅助工具

1、XAppDbg XAppDbg是一个可以在运行中改变代码中参数的一个应用开发工具。这个工具可以为你省下大量的时间,因为你不用为应用的每次小改变而重新编译运...

2286
来自专栏FreeBuf

无招胜有招: 看我如何通过劫持COM服务器绕过AMSI

? 在Windows 10中,Microsoft的反恶意软件扫描接口(AMSI)被作为新功能被引入,作为标准接口,该功能可以让反病毒引擎将特征规则应用于机器的...

3197

扫码关注云+社区

领取腾讯云代金券