### 简要描述:
KingCms最新版目录遍历及任意文件读取漏洞(无需截断)
### 详细说明:
朋友的公司想购买kingcms的授权,让我帮忙看下。发现kingcms很长一段时间没更新了,憋了一段时间放出了最新版的k9(2014-12-13更新),官网下下来学习一下。
在wooyun上看到了几个漏洞,如: [WooYun: kingcms最新版sql注入漏洞](http://www.wooyun.org/bugs/wooyun-2013-043520)
问题出在这里:/api/conn.php
先首需要说明的是,这里的目录遍历与文件读取并不是因为服务器配置不当等引起的,而是该cms的某些函数没过过滤+使用不当引起的。
0x00:先来看看如何目录遍历的。
```
无关代码
$get=$_GET;
if(empty($get['jsoncallback'])) exit('非法提交!');
$jsoncallback=$_GET['jsoncallback'];
if(empty($_GET['USERID'])) exit($jsoncallback.'('.json_encode(array('error'=>"用户ID不能为空,请求失败!")).')');
$str=new str;
$db=new db;
$file=new file;
if(empty($get['SIGN'])) exit($jsoncallback.'('.json_encode(array('error'=>'丢失密文,禁止解析!')).')');
//验证权限
$sign=$get['SIGN'];
unset($get['SIGN'],$get['_'],$get['jsoncallback']);
$arr=array();
foreach($get as $key => $val){
$arr[$key]=$key.'='.urlencode($val);
}
ksort($arr);
$param=implode('&',$arr);
$sign1=md5($param.kc_config('system.salt'));
if($sign!=$sign1) exit($jsoncallback.'('.json_encode(array('error'=>'审核失败,数据不一致!')).')');
$arr=array();
$get=array_map('base64_decode',$get);
foreach($get as $key=>$val){
if(substr($key,0,8)=='data_one'){
$arr[$key]=$db->get_one($val);
}elseif(substr($key,0,4)=='data'){
$arr[$key]=$db->get($val);
}elseif(substr($key,0,5)=='count'){
$res=$db->get($val);
$arr[$key]=empty($res[0]['c']) ? 0 : $res[0]['c'];
}elseif(substr($key,0,5)=='newid'){
list($table,$id)=explode('|',$val,2);
$arr[$key]=$db->newid($table,'',$id);
}elseif(substr($key,0,6)=='getdir'){
list($path,$filetype)=explode('|',$val,2);
if(empty($filetype)) $filetype='*';
$arr[$key]=$file->getDir($path,$filetype);
}elseif(substr($key,0,7)=='getfile'){
$arr[$key]=$file->get($val);
}elseif(substr($key,0,6)=='config'){
$arr[$key]=kc_config($val);
}elseif(substr($key,0,6)=='isfile'){
$arr[$key]=is_file(ROOT.$val)?1:0;
}
}
//判断url值,如果有这个值就有分页,count,rn和pid不能为空
if(!empty($get['url'])){
$url=$get['url'];
$rows=$arr['count'];
$pid=$get['pid'];
$rn=$get['rn'];
$arr['pagelist']=$str->pagelist($url, $rows, $pid, $rn,'<em>[count]</em>[standard][next]');
}
```
先来看看怎么绕过上面代码中的权限验证,也即要使得$sign1与$sign相等,其中$sing是用户输入的,$sign1的计算方法如下:
```
$arr=array();
foreach($get as $key => $val){
$arr[$key]=$key.'='.urlencode($val);
}
ksort($arr);
$param=implode('&',$arr);
$sign1=md5($param.kc_config('system.salt'));
```
计算过程中所用到的参数只有kc_config('system.salt')不是用户输入的,但是在kingcms中,这个参数全都是空的,也就是说$sing1完全由用户的输入参数按上述算法计算得来,因此,这里可以轻松绕过。然后执行到这句$arr[$key]=$file->getDir($path,$filetype);
跟进
```
function getDir($path='',$type='*',$ignore=array('.','..','.svn')){
if (!is_dir(ROOT.$path)) {
return array();
}
$dirs = $files = array();
$handle=opendir(ROOT.$path);
if($handle){
while (false !== ($file=@readdir($handle))){
$file=$this->encode($file);
if(!in_array($file,$ignore)){
if(is_dir(ROOT.$path.$file)){//如果是dir
if($type=='*'||$type=='dir')
$dirs[$path.$file]=$file;
}else{//文件
if($type=='*'||$type=='file'||preg_match("/^.+\.({$type})$/i",$file))
$files[$path.$file]=$file;
}
}
}
closedir($handle);
//sort($files);
//sort($dirs);
$union=array_merge($dirs,$files);
return $union;
}else{
kc_tip('找不到指定的目录<br/>'.$path);
}
}
```
直接把目录列出来了。路径是从根文件开始的,这里输入路径时,要base64 encode一下。成功列目录,如图
[<img src="https://images.seebug.org/upload/201503/222119317290bf86e677124981f735ea90c0d5cc.jpg" alt="列目录成功副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/222119317290bf86e677124981f735ea90c0d5cc.jpg)
0x01:再来看看如何实现任意文件读取的。
代码与上面第一段相同,这里就不贴出来了。看到这句$arr[$key]=$file->get($val);
跟进
```
public function get($filename){
$s='';
$filename=$this->encode($filename,1);
if(empty($GLOBALS['file_get_contents_array']))
$GLOBALS['file_get_contents_array']=array();
if(is_file(ROOT.$filename)){//如果存在则读取
$s='';
$fh = fopen(ROOT.$filename,"r");
while (!feof($fh)) {
$s.=fgets($fh);
}
fclose($fh);
}
return $s;
}
```
直接把文件读出并返回了,路径是从根文件开始的,这里输入文件名及路径时,要base64 encode一下。文件成功读取,如图
[<img src="https://images.seebug.org/upload/201503/222120043cc4f1104ae267dee1733c31ed1979ac.jpg" alt="读取过程副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/222120043cc4f1104ae267dee1733c31ed1979ac.jpg)
### 漏洞证明:
见 详细说明
暂无评论