微擎 0.8 后台任意文件删除
=========================

一、漏洞简介
------------

二、漏洞影响
------------

微擎 0.8

三、复现过程
------------

漏洞入口文件为 web/source/site/category.ctrl.php ，我们可以看到下图 14行
处调用了 file\_delete
函数，而这是一个文件删除相关操作，我们可以看一下该函数的具体定义。下图是入口文件代码：

![1.png](./resource/微擎0.8后台任意文件删除/media/rId24.png)

file\_delete 这一函数可以在 framework/function/file.func.php
文件中找到，该方法功能用于检测文件是否存在，如果存在，则删除文件。但是查看上下文发现，程序并没有对文件名
\$file 变量进行过滤，所以文件名就可以存在类似 ../
这种字符，这样也就引发任意文件删除漏洞，file\_delete 函数代码如下：

![2.png](./resource/微擎0.8后台任意文件删除/media/rId25.png)

现在我们在回溯回去，看看 \$file 变量从何处来。实际上，上图的 \$file
变量对应的是 \$row\[\'icon\'\] 的值，也就是说如果我们可以控制
\$row\[\'icon\'\] 的值，就可以删除任意文件。那么我们来看看 \$row
变量从何而来。该变量就在我们刚刚分析的第一张图片中(
web/source/site/category.ctrl.php 文件)，该值为变量 \$navs
中的元素值，具体代码如下：

![3.png](./resource/微擎0.8后台任意文件删除/media/rId26.png)

我们再往上看，即可找到 \$navs 变量的取值情况。可以看到 \$navs
变量的是是重数据库 site\_nav 表中取出的，包含了 icon 和 id
两个字段，具体代码如下：

    $navs = pdo_fetchall("SELECT icon, id FROM ".tablename('site_nav')." WHERE id IN (SELECT nid FROM ".tablename('site_category')." WHERE id = {$id} OR parentid = '$id')", array(), 'id');

现在我们要做的，就是找找看数据库中的这两个字段是否可以被用户控制。我们继续往前查找，发现了如下代码：

![4.png](./resource/微擎0.8后台任意文件删除/media/rId27.png)

site\_nav 表中的数据，对应的是 \$nav 变量。我们继续往上寻找 \$nav
变量，发现 \$nav\[\'icon\'\] 变量是从 \$\_GPC\[\'iconfile\'\]
来的，即可被用户控制( 下图 第21行 )。这里的 \$nav\[\'icon\'\]
变量，其实就是我们文章开头分析的传入 file\_delete
函数的参数，具体代码如下：

![5.png](./resource/微擎0.8后台任意文件删除/media/rId28.png)由于 \$nav\[\'icon\'\]
变量可被用户控制，程序有没有对其进行消毒处理，直接就传入了 file\_delete
函数，最终导致了文件删除漏洞。至此，我们分析完了整个漏洞的发生过程，接下看看如何进行攻击。

\#\#漏洞验证

访问url，点击管理公众号：

    http://www.0-sec.org/web/index.php?c=account&a=display

![6.jpg](./resource/微擎0.8后台任意文件删除/media/rId29.jpg)

找到分类设置，点击添加文章分类。这里对应的url为：http://www.0-sec.org/web/index.php?c=site&a=category，实际上表示
site 控制器的 category 模块，即对应 category.ctrl.php 文件。

![7.jpg](./resource/微擎0.8后台任意文件删除/media/rId30.jpg)

选择对应的内容，进入 if(\$isnav) 判断：

![8.jpg](./resource/微擎0.8后台任意文件删除/media/rId31.jpg)

在上传图标位置输入要删除文件的路径

![9.jpg](./resource/微擎0.8后台任意文件删除/media/rId32.jpg)

我们建立 delete.txt 文件，用于测试任意文件删除：

![10.jpg](./resource/微擎0.8后台任意文件删除/media/rId33.jpg)

![11.jpg](./resource/微擎0.8后台任意文件删除/media/rId34.jpg)

我们点击删除时，就会调用 file\_delete
函数，同时就会删除掉我们插入到数据库中的图片名：

![12.jpg](./resource/微擎0.8后台任意文件删除/media/rId35.jpg)

这个类型任意文件删除有点类似于二次注入，在添加分类时先把要删除的文件名称插入到数据库中，然后点击删除分类时，会从数据库中取出要删除的文件名。
