Destoon B2B CMS 20180827版本Getshell漏洞分析利用

  • A+
所属分类:网络安全文章

Destoon B2B CMS 20180827版本Getshell漏洞分析利用

漏洞分析

漏洞发生在头像上传处。Destoon中处理头像上传的是 module/member/avatar.inc.php 文件。在会员中心处上传头像时抓包,部分内容如下:

Destoon B2B CMS 20180827版本Getshell漏洞分析利用

对应avatar.inc.php代码如下:

  1. <?php
  2. defined('IN_DESTOON') or exit('Access Denied');
  3. login();
  4. require DT_ROOT.'/module/'.$module.'/common.inc.php';
  5. require DT_ROOT.'/include/post.func.php';
  6. $avatar = useravatar($_userid, 'large', 02);
  7. switch($action) {
  8.     case 'upload':
  9.         if(!$_FILES['file']['size']) {
  10.             if($DT_PC) dheader('?action=html&reload='.$DT_TIME);
  11.             exit('{"error":1,"message":"Error FILE"}');
  12.         }
  13.         require DT_ROOT.'/include/upload.class.php';
  14.         $ext = file_ext($_FILES['file']['name']);
  15.         $name = 'avatar'.$_userid.'.'.$ext;
  16.         $file = DT_ROOT.'/file/temp/'.$name;
  17.         if(is_file($file)) file_del($file);
  18.         $upload = new upload($_FILES, 'file/temp/', $name, 'jpg|jpeg|gif|png');
  19.         $upload->adduserid = false;
  20.         if($upload->save()) {
  21.             ...
  22.         } else {
  23.             ...
  24.         }
  25.     break;

这里通过$_FILES['file']依次获取了上传文件扩展名$ext、保存临时文件名$name、保存临时文件完整路径$file变量。之后通过new upload();创立一个upload对象,等到$upload->save()时再将文件真正写入。

upload对象构造函数如下,include/upload.class.php:25:

  1. <?php
  2. class upload {
  3.     function __construct($_file, $savepath, $savename = '', $fileformat = '') {
  4.         global $DT, $_userid;
  5.         foreach($_file as $file) {
  6.             $this->file = $file['tmp_name'];
  7.             $this->file_name = $file['name'];
  8.             $this->file_size = $file['size'];
  9.             $this->file_type = $file['type'];
  10.             $this->file_error = $file['error'];
  11.         }
  12.         $this->userid = $_userid;
  13.         $this->ext = file_ext($this->file_name);
  14.         $this->fileformat = $fileformat ? $fileformat : $DT['uploadtype'];
  15.         $this->maxsize = $DT['uploadsize'] ? $DT['uploadsize']*1024 : 2048*1024;
  16.         $this->savepath = $savepath;
  17.         $this->savename = $savename;
  18.     }
  19. }

这里通过foreach($_file as $file)来遍历初始化各项参数。而savepath、savename则是通过__construct($_file, $savepath, $savename = '', $fileformat = '')直接传入参数指定。

因此考虑上传了两个文件,第一个文件名是1.php,第二个文件是1.jpg,只要构造合理的表单上传

  1. $ext = file_ext($_FILES['file']['name']); // `$ext`即为`php` 
  2. $name = 'avatar'.$_userid.'.'.$ext; // $name 为 'avatar'.$_userid.'.'php'
  3. $file = DT_ROOT.'/file/temp/'.$name; // $file 即为 www/cesafe/com/cesafe.php

而在upload类中,由于多个文件上传,$this->file、$this->file_name、$this->file_type将foreach在第二次循环中被置为jpg文件。测试如下:

Destoon B2B CMS 20180827版本Getshell漏洞分析利用

回到avatar.inc.php,当进行文件保存时调用$upload->save(),include/upload.class.php:50:

  1. <?php
  2. class upload {
  3.     function save() {
  4.         include load('include.lang');
  5.         if($this->file_error) return $this->_('Error(21)'.$L['upload_failed'].' ('.$L['upload_error_'.$this->file_error].')');
  6.         if($this->maxsize > 0 && $this->file_size > $this->maxsize) return $this->_('Error(22)'.$L['upload_size_limit'].' ('.intval($this->maxsize/1024).'Kb)');
  7.         if(!$this->is_allow()) return $this->_('Error(23)'.$L['upload_not_allow']);
  8.         $this->set_savepath($this->savepath);
  9.         $this->set_savename($this->savename);
  10.         if(!is_writable(DT_ROOT.'/'.$this->savepath)) return $this->_('Error(24)'.$L['upload_unwritable']);
  11.         if(!is_uploaded_file($this->file)) return $this->_('Error(25)'.$L['upload_failed']);
  12.         if(!move_uploaded_file($this->file, DT_ROOT.'/'.$this->saveto)) return $this->_('Error(26)'.$L['upload_failed']);
  13.         $this->image = $this->is_image();
  14.         if(DT_CHMOD) @chmod(DT_ROOT.'/'.$this->saveto, DT_CHMOD);
  15.         return true;
  16.     }
  17. }

先经过几个基本参数的检查,然后调用$this->is_allow()来进行安全检查 include/upload.class.php:72:

  1. <?php
  2.     function is_allow() {
  3.         if(!$this->fileformat) return false;
  4.         if(!preg_match("/^(".$this->fileformat.")$/i", $this->ext)) return false;
  5.         if(preg_match("/^(php|phtml|php3|php4|jsp|exe|dll|cer|shtml|shtm|asp|asa|aspx|asax|ashx|cgi|fcgi|pl)$/i", $this->ext)) return false;
  6.         return true;
  7.     }

可以看到这里仅仅对$this->ext进行了检查,如前此时$this->ext为jpg,检查通过。

接着会进行真正的保存。通过$this->set_savepath($this->savepath); $this->set_savename($this->savename);设置了$this->saveto,然后通过move_uploaded_file($this->file, DT_ROOT.'/'.$this->saveto)将file保存到$this->saveto ,注意此时的savepath、savename、saveto均以php为后缀,而$this->file实际指的是第二个jpg文件。

漏洞利用

综上,上传两个文件,其中第一个文件以php为结尾如1.php,用于设置后缀名为php;第二个文件为1.jpg,jpg用于绕过检测,其内容为php一句话木马(图片马)。

Destoon B2B CMS 20180827版本Getshell漏洞分析利用

访问 http://www.cesafe.com/file/temp/avatar1.php 即可。其中1是自己的_userid

不过实际利用上会有一定的限制。

第一点是destoon使用了伪静态规则,限制了file目录下php文件的执行。

第二点是avatar.inc.php中在$upload->save()后,会再次对文件进行检查,然后重命名为xx.jpg。

因此要利用成功就需要条件竞争了。

CE安全网
网络安全宣传推广

发表评论

您必须登录才能发表评论!