dedecms v5.7 sp2 文件上传漏洞[CVE-2019-8362]

简介

织梦内容管理系统(DedeCms) ,是国内最知名的PHP开源网站管理系统,也是使用用户最多的PHP类CMS系统,在经历多年的发展,DedeCms的主要目标用户锁定在个人站长,功能更专注于个人网站或中小型门户的构建,当然也不乏有企业用户和学校等在使用该系统。

原理分析

漏洞位于dede/album_edit.php或dede/album_add.php中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    /*---------------------
function _getformzip()
从ZIP文件中获取新图片
---------------------*/
if($formzip==1)
{
include_once(DEDEINC."/zip.class.php");
include_once(DEDEADMIN."/file_class.php");
$zipfile = $cfg_basedir.str_replace($cfg_mainsite,'',$zipfile);
$tmpzipdir = DEDEDATA.'/ziptmp/'.cn_substr(md5(ExecTime()),16);
$ntime = time();
if(file_exists($zipfile))
{

@mkdir($tmpzipdir,$GLOBALS['cfg_dir_purview']);
@chmod($tmpzipdir,$GLOBALS['cfg_dir_purview']);
$z = new zip();
$z->ExtractAll($zipfile,$tmpzipdir);
$fm = new FileManagement();
$imgs = array();
$fm->GetMatchFiles($tmpzipdir,"jpg|png|gif",$imgs);
$i = 0;
foreach($imgs as $imgold)
{
$i++;
$savepath = $cfg_image_dir."/".MyDate("Y-m",$ntime);
CreateDir($savepath);
$iurl = $savepath."/".MyDate("d",$ntime).dd2char(MyDate("His",$ntime).'-'.$adminid."-{$i}".mt_rand(1000,9999));
$iurl = $iurl.substr($imgold,-4,4);
$imgfile = $cfg_basedir.$iurl;
copy($imgold,$imgfile);
unlink($imgold);
if(is_file($imgfile))
{
$litpicname = $pagestyle > 2 ? GetImageMapDD($iurl,$cfg_ddimg_width) : $iurl;
$info = '';
$imginfos = GetImageSize($imgfile,$info);
$imgurls .= "{dede:img ddimg='$litpicname' text='' width='".$imginfos[0]."' height='".$imginfos[1]."'} $iurl {/dede:img}\r\n";

//把图片信息保存到媒体文档管理档案中
$inquery = "
INSERT INTO #@__uploads(title,url,mediatype,width,height,playtime,filesize,uptime,mid)
VALUES ('{$title}','{$iurl}','1','".$imginfos[0]."','".$imginfos[1]."','0','".filesize($imgfile)."','".$ntime."','$adminid');
";
$dsql->ExecuteNoneQuery($inquery);
if(!$hasone && $ddisfirst==1
&& $litpic=="" && !empty($litpicname))
{
if( file_exists($cfg_basedir.$litpicname) )
{
$litpic = $litpicname;
$hasone = true;
}
}
}
}
if($delzip==1)
{
unlink($zipfile);
}
$fm->RmDirFiles($tmpzipdir);
}
}

此段代码的功能是从zip文件中获取图片,GetMatchFiles函数获取符合规则的图片(由传入参数知道是png,jpg,gif),
跟进GetMatchFiles函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function GetMatchFiles($indir, $fileexp, &$filearr)
{
$dh = dir($indir);
while($filename = $dh->read())
{
$truefile = $indir.'/'.$filename;
if($filename == "." || $filename == "..")
{
continue;
}
else if(is_dir($truefile))
{
$this->GetMatchFiles($truefile, $fileexp, $filearr);
}
else if(preg_match("/\.(".$fileexp.")/i",$filename))
{
$filearr[] = $truefile;
}
}
$dh->close();
}

问题就出在:

1
2
3
4
else if(preg_match("/\.(".$fileexp.")/i",$filename))
{
$filearr[] = $truefile;
}

只要文件名中包含”.jpg”、”.png”、”.gif”即可被上传。因此可以在zip文件中创建包含这几个字符串的php文件然后上传。

利用过程

创建一个zip文件,其中包含一个php文件名称为”1.jpg.php”

然后访问dede/album_edit.php,选择”从ZIP压缩包中解压文件”,然后上传准备好的zip文件。

然后查看图集即可访问上传的php文件