跳转至

(CVE-2018-20129)Dedecms前台文件上传漏洞

一、漏洞简介

管理员用户前台可以绕过限制上传shell

二、漏洞影响

三、复现过程

代码分析

漏洞在于用户发布文章上传图片处。处理文件在/include/dialog/select_images_post.php

而上传文件存在全局过滤/include/uploadsafe.inc.php

#/include/uploadsafe.inc.php
$cfg_not_allowall = "php|pl|cgi|asp|aspx|jsp|php3|shtm|shtml";
if(!empty(${$_key.'_name'}) && (preg_match("#\.(".$cfg_not_allowall.")$#i",${$_key.'_name'}) || !preg_match("#\.#", ${$_key.'_name'})) )
{
    if(!defined('DEDEADMIN'))
    {
        exit('Not Admin Upload filetype not allow !');
    }
}
$imtypes = array
    (
    "image/pjpeg", "image/jpeg", "image/gif", "image/png", 
    "image/xpng", "image/wbmp", "image/bmp"
);

if(in_array(strtolower(trim(${$_key.'_type'})), $imtypes))
{
    $image_dd = @getimagesize($$_key);
    if (!is_array($image_dd))
    {
        exit('Upload filetype not allow !');
    }
}

可以看到名字中不得有上述字符,且限制了content-type。按道理说直接限制不得存在的字符,似乎没有问题了,可在发布文章文件上传的处理文件select_images_post.php中存在如下代码:

$imgfile_name = trim(preg_replace("#[ \r\n\t\*\%\\\/\?><\|\":]{1,}#", '', $imgfile_name));

if(!preg_match("#\.(".$cfg_imgtype.")#i", $imgfile_name)) #$cfg_imgtype = 'jpg|gif|png';
{
    ShowMsg("你所上传的图片类型不在许可列表,请更改系统对扩展名限定的配置!", "-1");
    exit();
}

再次过滤了图片名,并且再次判断如上三种文件类型是否存在其中。这么一次过滤,直接粗暴的将一些特殊字符替换为空,那么我们就可以通过特殊字符绕过上面的全局文件名不能包含php字符的限制,比如文件名为1.jpg.p*hp

复现

登录并进入member/article_add.php发布文章,选择下面的富文本编辑器插入图片

选择好shell并上传抓包

向如上分析修改文件名与content-type,即可返回shell地址