前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DedeCMS v5.8.1_beta未授权远程命令执行漏洞分析

DedeCMS v5.8.1_beta未授权远程命令执行漏洞分析

原创
作者头像
Deen_
发布2021-11-12 01:06:23
4.2K0
发布2021-11-12 01:06:23
举报
文章被收录于专栏:Deen的代金券日记

0x00 背景

深信服公众号前几天发了Dedecms未授权RCE的漏洞通告。地址是这个: 【漏洞通告】DedeCMS未授权远程命令执行漏洞

看内容描述,

影响范围 : 正式版:< v5.7.8(仅SQL注入),内测版:= v5.8.1_beta

这篇推送好像更新过,括号里的"(仅SQL注入)"我原来是没看到的,如果没记错的话。

由于没给poc,网上也搜不到啥相关详情,仔细看了下描述。

该漏洞是由于DedeCMS存在变量覆盖漏洞,攻击者可利用该漏洞在未授权的情况下,构造恶意代码配合模板文件包含功能造成远程命令执行攻击,最终获取服务器最高权限。

起因是变量覆盖,然后利用变量覆盖进行恶意操作。

0x01 审计代码

这是dedecms在github的地址: https://github.com/dedecms/DedeCMS

在releases的tag里,我们找到6.8.1 beta下载下来。

https://github.com/dedecms/DedeCMS/releases/tag/v5.8.1

既然是变量覆盖,使用IDE搜索关键字 "$$",可以找到有这几处:

  • dede/module_make.php
  • inclue/common.inc.php

dede是管理员后台的目录,自然不是。至于inclue/common.inc.php,主要代码如下:

代码语言:txt
复制
    function CheckRequest(&$val)
    {
        if (is_array($val)) {
            foreach ($val as $_k => $_v) {
                if ($_k == 'nvarname') {
                    continue;
                }

                CheckRequest($_k);
                CheckRequest($val[$_k]);
            }
        } else {
            if (strlen($val) > 0 && preg_match('#^(cfg_|GLOBALS|_GET|_POST|_COOKIE|_SESSION)#', $val)) {
                exit('Request var not allow!');
            }
        }
    }

    //var_dump($_REQUEST);exit;
    CheckRequest($_REQUEST);
    CheckRequest($_COOKIE);

    foreach (array('_GET', '_POST', '_COOKIE') as $_request) {
        foreach ($$_request as $_k => $_v) {
            if ($_k == 'nvarname') {
                ${$_k} = $_v;
            } else {
                ${$_k} = _RunMagicQuotes($_v);
            }

        }
    }

可以看到主要功能就是将用户请求里的变量进行一个转化,但是这里哟一个CheckRequest函数,不知道是否做了安全防护。

虽然这里有变量覆盖,但是有个很头疼的问题,这个文件几乎被所有控制路由包含了,那么触发点在哪呢?.....还是相当于大海捞针。

也就是说,单单靠这个漏洞通告里的内容,是很难准确找到洞的。

dedecms在github有地址,那看他更新了啥不就好了?

一开始我也是这么想的,但是一看.....更新了两千多个文件....基本等于所有文件都更新了,就是怕你发现端倪...好套路啊.....

0x02 朋友找的POC

这是flink.php的主要内容,

代码语言:txt
复制
if ($dopost == 'save') {
    $validate = isset($validate) ? strtolower(trim($validate)) : '';
    $svali = GetCkVdValue();
    if ($validate == '' || $validate != $svali) {
        ShowMsg('验证码不正确!', '-1');
        exit();
    }
    $msg = RemoveXSS(dede_htmlspecialchars($msg));
    $email = RemoveXSS(dede_htmlspecialchars($email));
    $webname = RemoveXSS(dede_htmlspecialchars($webname));
    $url = RemoveXSS(dede_htmlspecialchars($url));
    $logo = RemoveXSS(dede_htmlspecialchars($logo));
    $typeid = intval($typeid);
    $dtime = time();
    $query = "INSERT INTO `#@__flink`(sortrank,url,webname,logo,msg,email,typeid,dtime,ischeck)
                    VALUES('50','$url','$webname','$logo','$msg','$email','$typeid','$dtime','0')";
    $dsql->ExecuteNoneQuery($query);
    ShowMsg('成功增加一个链接,但需要审核后才能显示!', '-1', 1);
}

简单查看了下,最后锁定关键函数——ShowMsg。位于include/common.func.php文件。

再看POC的输出点,

代码语言:txt
复制
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(\"";

这个变量是用户可控的。

所以.....变量覆盖在哪......无语....

复现
复现

0x03 官方修复

官方修复
官方修复

将$gourl的赋值进行了删除。并去掉了模板渲染,改成echo。

去掉模板渲染
去掉模板渲染

我对这个洞的影响范围表示好奇,下载了5.7的源码,发现并没有这个问题,只影响 v5.8.1_beta,颇有一股官方投毒的意思,再想起织梦今天官方的通告——《关于提醒办理DEDECMS产品商业使用授权的通告》。

细思恐极。

0x04 由点及面,尝试挖掘其他漏洞

从showmsg入手

再回到ShowMsg触发那里,也就是说,当如下代码,$msg是可控时,LoadString就是一个危险函数。

代码语言:txt
复制
$tpl = new DedeTemplate();

$tpl->LoadString($msg);

$tpl->Display();

再进入LoadString,发现变量$str赋值给sourceString,

代码语言:txt
复制
    public function LoadString($str = '')
    {
        $this->sourceString = $str;
        $hashcode = md5($this->sourceString);
        $this->cacheFile = $this->cacheDir . "/string_" . $hashcode . ".inc";
        $this->configFile = $this->cacheDir . "/string_" . $hashcode . "_config.inc";
        $this->ParseTemplate();
    }

通过IDE查找 sourceString赋值。

未果。

从项目整体入手

plus目录是外部不用登录就可以访问的。逐一审计。

发现一些问题,但是利用有限。

后台shell, /plus/ad_js.php包含文件

从数据库里取出来,然后写文件。

如果能进后台,就能利用这里。

0x05 最后

这个项目代码比较混乱,没啥价值,除了国内用的站点比较多外。那个模板的处理流程可以深究一下,看起来有点繁琐。先这样吧。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 背景
  • 0x01 审计代码
  • 0x02 朋友找的POC
  • 0x03 官方修复
  • 0x04 由点及面,尝试挖掘其他漏洞
    • 从showmsg入手
      • 从项目整体入手
        • 后台shell, /plus/ad_js.php包含文件
    • 0x05 最后
    相关产品与服务
    验证码
    腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档