热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

某CMS20180827版前端存在GETShell漏洞分析

2018年9月21日,Destoon官方发布了安全更新,修复了一个由用户“索马里的海贼”报告的前端GETShell漏洞。该漏洞存在于20180827版本的某CMS中,攻击者可以通过构造特定的HTTP请求,利用该漏洞在服务器上执行任意代码,从而获得对系统的控制权。此次更新建议所有用户尽快升级至最新版本,以确保系统的安全性。

前言

2018年9月21日,Destoon官方发布安全更新,修复了由用户“索马里的海贼”反馈的一个漏洞。

某CMS 20180827版本 前台getshell

漏洞分析

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

某CMS 20180827版本 前台getshell

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

adduserid = false;

        if($upload->save()) {
            ...
        } else {
            ...
        }
    break;

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

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

file = $file['tmp_name'];
            $this->file_name = $file['name'];
            $this->file_size = $file['size'];
            $this->file_type = $file['type'];
            $this->file_error = $file['error'];

        }
        $this->userid = $_userid;
        $this->ext = file_ext($this->file_name);
        $this->fileformat = $fileformat ? $fileformat : $DT['uploadtype'];
        $this->maxsize = $DT['uploadsize'] ? $DT['uploadsize']*1024 : 2048*1024;
        $this->savepath = $savepath;
        $this->savename = $savename;
    }
}

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

因此考虑上传了两个文件,第一个文件名是 1.php ,第二个文件是 1.jpg ,只要构造合理的表单上传(参考: https://www.cnblogs.com/DeanChopper/p/4673577.html),则在avatar.inc.php中

$ext = file_ext($_FILES['file']['name']); // `$ext`即为`php` 
$name = 'avatar'.$_userid.'.'.$ext; // $name 为 'avatar'.$_userid.'.'php'
$file = DT_ROOT.'/file/temp/'.$name; // $file 即为 xx/xx/xx/xx.php

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

某CMS 20180827版本 前台getshell

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

file_error) return $this->_('Error(21)'.$L['upload_failed'].' ('.$L['upload_error_'.$this->file_error].')');

        if($this->maxsize > 0 && $this->file_size > $this->maxsize) return $this->_('Error(22)'.$L['upload_size_limit'].' ('.intval($this->maxsize/1024).'Kb)');

        if(!$this->is_allow()) return $this->_('Error(23)'.$L['upload_not_allow']);

        $this->set_savepath($this->savepath);
        $this->set_savename($this->savename);

        if(!is_writable(DT_ROOT.'/'.$this->savepath)) return $this->_('Error(24)'.$L['upload_unwritable']);
        if(!is_uploaded_file($this->file)) return $this->_('Error(25)'.$L['upload_failed']);
        if(!move_uploaded_file($this->file, DT_ROOT.'/'.$this->saveto)) return $this->_('Error(26)'.$L['upload_failed']);

        $this->image = $this->is_image();
        if(DT_CHMOD) @chmod(DT_ROOT.'/'.$this->saveto, DT_CHMOD);
        return true;
    }
}

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

fileformat) return false;
        if(!preg_match("/^(".$this->fileformat.")$/i", $this->ext)) return false;
        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;
        return true;
    }

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

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

漏洞利用

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

某CMS 20180827版本 前台getshell

然后访问 http://127.0.0.1/file/temp/avatar1.php 即可。其中 1 是自己的 _userid

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

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

某CMS 20180827版本 前台getshell

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

省略...
$img = array();
$img[1] = $dir.'.jpg';
$img[2] = $dir.'x48.jpg';
$img[3] = $dir.'x20.jpg';
$md5 = md5($_username);
$dir = DT_ROOT.'/file/avatar/'.substr($md5, 0, 2).'/'.substr($md5, 2, 2).'/_'.$_username;
$img[4] = $dir.'.jpg';
$img[5] = $dir.'x48.jpg';
$img[6] = $dir.'x20.jpg';
file_copy($file, $img[1]);
file_copy($file, $img[4]);
省略...

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

补丁分析

某CMS 20180827版本 前台getshell

在upload的一开始,就进行一次后缀名的检查。其中is_image如下:

function is_image($file) {
    return preg_match("/^(jpg|jpeg|gif|png|bmp)$/i", file_ext($file));
}

某CMS 20180827版本 前台getshell

__construct() 的foreach中使用了break,获取了第一个文件后就跳出循环。

is_allow() 中增加对 $this->savename 的二次检查。

最后

嘛,祝各位大师傅中秋快乐!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 我们


推荐阅读
  • 在CodeIgniter框架中集成新库文件的过程中,我遇到了一些困惑。具体来说,在跟随nettuts的认证教程时,对于在Welcome控制器中添加的构造函数代码,特别是关于Session的验证部分,我感到不太理解。这部分内容涉及如何确保Session已经初始化并具备相应的功能,这对于实现用户认证至关重要。为了更好地掌握这一知识点,我计划深入研究CodeIgniter的官方文档,并参考更多相关资源,以确保能够正确地集成和使用新库文件。 ... [详细]
  • 深入解析 Vue 中的 Axios 请求库
    本文深入探讨了 Vue 中的 Axios 请求库,详细解析了其核心功能与使用方法。Axios 是一个基于 Promise 的 HTTP 客户端,支持浏览器和 Node.js 环境。文章首先介绍了 Axios 的基本概念,随后通过具体示例展示了如何在 Vue 项目中集成和使用 Axios 进行数据请求。无论你是初学者还是有经验的开发者,本文都能为你解决 Vue.js 相关问题提供有价值的参考。 ... [详细]
  • 在PHP的设计中,预定义了9个超级全局变量、8个魔术变量和13个魔术函数,这些变量和函数无需声明即可在脚本的任意位置使用。这些特性在PHP开发中极为常见,能够显著提升开发效率和代码的灵活性。相比之下,Java并没有类似的内置机制,但通过其他方式如上下文对象和反射机制,也可以实现类似的功能。本文将详细探讨这两种语言中这些特殊变量和函数的使用方法及其应用场景。 ... [详细]
  • Spring框架的核心组件与架构解析 ... [详细]
  • 解决lib-flexible安装过程中遇到的错误问题
    在安装 lib-flexible 时,遇到了 `saveError ENOENT: No such file or directory` 错误,具体表现为无法打开 `E:\Github\SDIO\package.json` 文件。解决此问题的关键在于确保项目根目录下存在 `package.json` 文件,并且在正确的项目路径中执行安装命令。建议先检查项目结构,确认文件是否存在,然后再尝试重新安装依赖。 ... [详细]
  • 推荐:利用Dapper.SimpleCRUD扩展Dapper功能以简化CRUD操作
    Dapper作为广受欢迎的ORM框架之一,虽然灵活性极高,但在处理基本的CRUD操作时仍需手动编写SQL语句,这无疑增加了开发工作量。为了解决这一问题,Dapper.SimpleCRUD扩展库应运而生。该扩展库通过提供简洁的方法,显著简化了数据访问层的开发流程,使开发者能够更加高效地进行读取、插入、更新和删除操作。此外,Dapper.SimpleCRUD还支持事务管理和批量操作,进一步提升了开发效率和代码可维护性。 ... [详细]
  • 本文介绍了UUID(通用唯一标识符)的概念及其在JavaScript中生成Java兼容UUID的代码实现与优化技巧。UUID是一个128位的唯一标识符,广泛应用于分布式系统中以确保唯一性。文章详细探讨了如何利用JavaScript生成符合Java标准的UUID,并提供了多种优化方法,以提高生成效率和兼容性。 ... [详细]
  • Golomb 编码是一种高效的变长编码技术,专门用于整数的压缩。该方法通过预定义的参数 \( M \) 将输入整数分解为商 \( q \) 和余数 \( r \) 两部分。具体而言,输入整数除以 \( M \) 得到商 \( q \) 和余数 \( r \),其中商 \( q \) 采用一元编码表示,而余数 \( r \) 则使用二进制编码。这种编码方式在数据压缩和信息传输中具有显著的优势,特别是在处理具有特定概率分布的数据时表现出色。 ... [详细]
  • PHP中函数名、常量名和变量名大小写转换及规范详解
    在PHP编程中,初学者常常会遇到关于函数名、常量名和变量名大小写的问题。本文详细解析了PHP中这些名称的大小写敏感性及其命名规范,帮助开发者更好地理解和使用PHP。具体而言,文章探讨了PHP中的常量名是否区分大小写,自定义函数名的大小写敏感性,以及类名的大小写规则。此外,还提供了实用的代码示例和最佳实践,以确保代码的可读性和一致性。 ... [详细]
  • 如何在Lua中调用C语言编译的动态链接库
    本文介绍了如何在Lua中调用C语言编译的动态链接库。通过详细步骤和示例代码,帮助开发者理解和掌握这一技术。参考了《Lua编程入门》一书中的相关内容,并结合实际操作经验,提供了更加清晰和实用的指导。此外,还探讨了在不同操作系统下编译和链接Lua的方法,为跨平台开发提供了有价值的参考。 ... [详细]
  • 本文深入探讨了 hCalendar 微格式在事件与时间、地点相关活动标记中的应用。作为微格式系列文章的第四篇,前文已分别介绍了 rel 属性用于定义链接关系、XFN 微格式增强链接的人际关系描述以及 hCard 微格式对个人和组织信息的描述。本次将重点解析 hCalendar 如何通过结构化数据标记,提高事件信息的可读性和互操作性。 ... [详细]
  • 揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节
    揭秘腾讯云CynosDB计算层设计优化背后的不为人知的故事与技术细节 ... [详细]
  • 掌握PHP编程必备知识与技巧——全面教程在当今的PHP开发中,了解并运用最新的技术和最佳实践至关重要。本教程将详细介绍PHP编程的核心知识与实用技巧。首先,确保你正在使用PHP 5.3或更高版本,最好是最新版本,以充分利用其性能优化和新特性。此外,我们还将探讨代码结构、安全性和性能优化等方面的内容,帮助你成为一名更高效的PHP开发者。 ... [详细]
  • 大家好,我是梅巴哥er。本文将深入探讨Redux框架中的第三个实战案例,具体实现每两秒自动点击按钮以触发颜色变化的功能。该案例中,一个关键点在于是否需要使用异步操作来处理定时任务,我们将详细分析其必要性和实现方式。通过这一实例,读者可以更好地理解Redux在实际项目中的应用及其异步处理机制。 ... [详细]
  • 初探设计模式之代理模式:原理与应用解析
    在设计模式中,代理模式通过一个代理对象来控制对真实对象的访问。UML图展示了代理类(如MathProxy)维护了一个引用,使得代理能够访问实际的主题对象。代理模式不仅能够延迟初始化昂贵的对象,还能在访问前后添加额外的操作,如权限检查或日志记录。这种模式在远程服务调用、虚拟代理和智能引用等方面有广泛应用。 ... [详细]
author-avatar
Q小泓别_431
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有