cmseasy{easy through CMS}v5. 5 arbitrary file upload vulnerability in the simple analysis of reference using the method-vulnerability warning-the black bar safety net

2013-05-13T00:00:00
ID MYHACK58:62201338738
Type myhack58
Reporter 风井
Modified 2013-05-13T00:00:00

Description

Yesterday found someone storm out of a cmseasy v5. 5 arbitrary file upload vulnerability, it also comes with the exp. Exploit the vulnerability can directly Upload a webshell and other malicious files, the harm is huge and currently the official has not been any patches here to do some simple vulnerability analysis.

Use the inlet is located at:

http://www.site.com/editor/editor/dialog/imageuser_mt_mt.php/index.php?case=user&act=log

!

Through this page you can upload any file to the server.

See imageuser_mt_mt. php code:

$_GET=array('case'=>'user','act'=>'fckupload'); the include_once dirname(dirname(dirname(dirname(FILE)))).'/ index.php';

Includes index. php and specify the case and the act, because cmseasy implement various functions of the files are in the\lib\default\directory to the directory found under the user_act. php file and navigate to the fckupload function:

function fckupload_action() { $uploads=array(); if(is_array($_FILES)) { $upload=new upload(); foreach($_FILES as $name=>$file) { $uploads[$name]=$upload->run($file); } $this->view->uploads=$uploads; } $this->render('../admin/system/fckupload.php'); exit; }

Enter into the run()function(位于 \lib\tool\front_class.php): the

class upload { public $path; public $type=array('jpg','gif','png','doc','flv','rar'); public $max_size=2 0 4 8 0 0 0; public $min_size=0; public $dir='images'; function run($attachment) { $this->max_size=config::get('upload_max_filesize') * 1 0 2 4 0 0 0; if (! isset($this->url_pre)) $this->url_pre='upload/'.$ this->dir.'/'. date('Ym'); $this->path=ROOT.'/'.$ this->url_pre; tool::mkdir($this->path); if (!$ attachment['name']) { return false; } $new_name=$new_name_gbk=str_replace('.',", Time::getMicrotime()).'.'. end(explode('.',$ attachment['name'])); $content=file_get_contents($attachment['tmp_name']); if (! front::checkstr($content)) { return false; } if (strlen($content) >$this->max_size) { return false; } move_uploaded_file($attachment['tmp_name'],$this->path.'/'.$ new_name_gbk); $this->save_path=$this->path.'/'.$ new_name_gbk; if ($_GET['site'] != 'default') { $ftp=new nobftp(); $ftpconfig=config::get('website'); $ftp->connect($ftpconfig['ftpip'],$ftpconfig['ftpuser'],$ftpconfig['ftppwd'],$ftpconfig['ftpport']); $ftperror=$ftp->returnerror(); if ($ftperror) { exit($ftperror); } else { $ftp->nobchdir($ftpconfig['ftppath']); $ftp-> nobput($ftpconfig['ftppath'].'/'.$ this->url_pre.'/'.$ new_name,$this->save_path); } } return $this->url_pre.'/'.$ new_name; } }

You can see the class at the beginning of it defines the allowed upload types

public $type=array(‘jpg’,'gif’,'png’,'doc’,'flv’,'rar’);

But after the process was not used, directly through the move_uploaded_file to put the upload of the temporary file is saved to the corresponding directory.

The entire process has been obviously can not again obvious, feeling this exploit is more like someone leaving a hidden back door. it.

Finally gives patch recommendations:

In the\lib\tool\front_class. php file, the first 2 6 6 5 the left and right of the move_uploaded_file function on the top add the following statement:

if (!$ new_name ||! preg_match('/\. (jpg|gif|png|bmp)$/',$new_name)) { return false; }