环境搭建
- 下载超级CMS V2.39,下载地址
- 使用phpstudy搭建web环境
- 把下载好的源码放到网站根目录下,开启phpstudy,浏览器访问安装后即可
漏洞复现
上传点一
上传点二
上传点三
漏洞分析
存在漏洞的位置
file.class.php
文件中的getFileExtName
方法
public function getFileExtName($filename){
$filename = strtolower($filename);
$exts = explode('.',$filename);
$ext = $exts[count($exts)-1];
if(strpos($ext,'?') >= 0){
$ext = explode('?',$ext);
return $ext[0];
}
else
return $ext;
}
取其中一个图片上传模块为例子,利用位于
webset.master.php
文件中的setweb
方法
private function setweb(){
$Lang=$this->G->loadLang();
if($_SESSION['input_token']!="" && $_SESSION['input_token']==$_POST['input_token']){
$_SESSION['input_token']='';
$dsw =$_POST['dsw'];
if($dsw){
if(is_uploaded_file($_FILES['file']['tmp_name'])){
$sfile=$_FILES["file"];
$dsw['web_logo']=$this->files->uploadFile($sfile,UPLOAD_PATH_IMG);
}
if(is_uploaded_file($_FILES['file_ewm']['tmp_name'])){
$sfile=$_FILES["file_ewm"];
$dsw['web_erweima']=$this->files->uploadFile($sfile,UPLOAD_PATH_IMG);
}
foreach($dsw as $k=>$v){
$this->webconfig->update(array('value'=>$v),array('varname'=>$k));
}
$message = array(
'CodeType' =>300,
"message" => $Lang['set']['UpdateSuccess'],
"callbackType" => 'forward',
"forwardUrl" => ADMIN_URL."webset"
);
$this->G->R($message);
}
}else{
$ListAll=$this->webconfig->getAll();
if($ListAll){
$ListOne=array();
foreach($ListAll as $k=>$v){
$ListOne[$v['varname']]=$v['value'];
}
$this->tpl->assign("FormTitle",$Lang['set']['FormTitle']);
$this->tpl->assign('ListOne',$ListOne);
$_SESSION['input_token'] = md5(rand(100,1000));
$this->tpl->assign("input_token",$_SESSION['input_token']);
$this->tpl->assign("FormAction",ADMIN_URL."webset-setweb");
$this->tpl->assign("Lang",$Lang);
$this->tpl->display('webset');
}
}
}
跟进uploadFile方法
public function uploadFile($file,$updir,$sExtension = NULL,$name = NULL){
if(!$sExtension)$sExtension = $this->getFileExtName($file['name']);
if(!$name)$name = time().rand(1000,9999);
if(!file_exists('.'.$updir))$this->mdir('.'.$updir);
$url = $updir.$name.'.'.$sExtension;
if(file_exists($url))unlink($url);
move_uploaded_file($file['tmp_name'],'.'.$url);
if (file_exists($url)){
$oldumask = umask(0);
chmod($url,0777);
umask($oldumask);
}
return $url;
}
我们发现,这里调用
getFileExtName
方法获取文件扩展名,但这里并没有做严格的过滤,所以导致可以通过直接上传1.jpg.php
来达到getshell的目的