DedeCMS common.func.php 远程命令执行漏洞

漏洞描述

DocCMS flink.php 文件存远程命令执行漏洞,攻击者通过漏洞可以执行任意命令

漏洞影响

DedeCMS v5.81 beta 内测版

FOFA

"DedeCMS_V5.8.1"

漏洞复现

产品页面

image-20220518145134124

image-20220518145134124

查看文件 include/common.func.php 的 ShowMsg方法

image-20220518145203093

image-20220518145203093

function ShowMsg($msg, $gourl, $onlymsg = 0, $limittime = 0)
{
    if (empty($GLOBALS['cfg_plus_dir'])) {
        $GLOBALS['cfg_plus_dir'] = '..';
    }
    if ($gourl == -1) {
        $gourl = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
        if ($gourl == "") {
            $gourl = -1;
        }
    }

    $htmlhead = "
    <html>\\r\\n<head>\\r\\n<title>DedeCMS提示信息</title>\\r\\n
    <meta http-equiv=\\"Content-Type\\" content=\\"text/html; charset={dede:global.cfg_soft_lang/}\\" />
    <meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\\">
    <meta name=\\"renderer\\" content=\\"webkit\\">
    <meta http-equiv=\\"Cache-Control\\" content=\\"no-siteapp\\" />
    <link rel=\\"stylesheet\\" type=\\"text/css\\" href=\\"{dede:global.cfg_assets_dir/}/pkg/uikit/css/uikit.min.css\\" />
    <link rel=\\"stylesheet\\" type=\\"text/css\\" href=\\"{dede:global.cfg_assets_dir/}/css/manage.dede.css\\">
    <base target='_self'/>
    </head>
    <body>
    " . (isset($GLOBALS['ucsynlogin']) ? $GLOBALS['ucsynlogin'] : '') . "
    <center style=\\"width:450px\\" class=\\"uk-container\\">
    
    <div class=\\"uk-card uk-card-small uk-card-default\\" style=\\"margin-top: 50px;\\">
        <div class=\\"uk-card-header\\"  style=\\"height:20px\\">DedeCMS 提示信息!</div>

    <script>\\r\\n";
    $htmlfoot = "
    </script>
    
    
    </center>
    
    <script src=\\"{dede:global.cfg_assets_dir/}/pkg/uikit/js/uikit.min.js\\"></script>
	<script src=\\"{dede:global.cfg_assets_dir/}/pkg/uikit/js/uikit-icons.min.js\\"></script>
    </body>\\r\\n</html>\\r\\n";

    $litime = ($limittime == 0 ? 1000 : $limittime);
    $func = '';

    if ($gourl == '-1') {
        if ($limittime == 0) {
            $litime = 3000;
        }

        $gourl = "javascript:history.go(-1);";
    }

    if ($gourl == '' || $onlymsg == 1) {
        $msg = "<script>alert(\\"" . str_replace("\\"", "“", $msg) . "\\");</script>";
    } else {
        //当网址为:close::objname 时, 关闭父框架的id=objname元素
        if (preg_match('/close::/', $gourl)) {
            $tgobj = trim(preg_replace('/close::/', '', $gourl));
            $gourl = 'javascript:;';
            $func .= "window.parent.document.getElementById('{$tgobj}').style.display='none';\\r\\n";
        }

        $func .= "var pgo=0;
      function JumpUrl(){
        if(pgo==0){ location='$gourl'; pgo=1; }
      }\\r\\n";
        $rmsg = $func;
        $rmsg .= "document.write(\\"<div style='height:130px;font-size:10pt;background:#ffffff'><br />\\");\\r\\n";
        $rmsg .= "document.write(\\"" . str_replace("\\"", "“", $msg) . "\\");\\r\\n";
        $rmsg .= "document.write(\\"";

        if ($onlymsg == 0) {
            if ($gourl != 'javascript:;' && $gourl != '') {
                $rmsg .= "<br /><a href='{$gourl}'>如果你的浏览器没反应,请点击这里...</a>";
                $rmsg .= "<br/></div>\\");\\r\\n";
                $rmsg .= "setTimeout('JumpUrl()',$litime);";
            } else {
                $rmsg .= "<br/></div>\\");\\r\\n";
            }
        } else {
            $rmsg .= "<br/><br/></div>\\");\\r\\n";
        }
        $msg = $htmlhead . $rmsg . $htmlfoot;
    }
    
    $tpl = new DedeTemplate();
    $tpl->LoadString($msg);
    $tpl->Display();
}

/**
 *  获取验证码的session值
 *
 * @return string
 */

image-20220518145232032

image-20220518145232032

这里注意到 当 $gourl 变量为 -1 时调用 ShowMsg方法, 则请求参数 Referer 为用户可控参数

image-20220518145245750

image-20220518145245750

向下看,可以发现可控的变量传入两个方法

$tpl = new DedeTemplate();
$tpl->LoadString($msg);
$tpl->Display();

追踪方法来到 include/dedetemplate.class.php 文件

image-20220518145306926

image-20220518145306926