Drupal SA-CORE-2019-010 .开头文件名(如.htaccess) 文件上传

2023-12-25 17:18

本文主要是介绍Drupal SA-CORE-2019-010 .开头文件名(如.htaccess) 文件上传,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • drupal .开头文件名 文件上传
  • 原生模块分析
  • 第三方模块分析
  • 补丁
  • 参考

drupal .开头文件名 文件上传

小说网 https://www.198200.com

1077935-20200126135426315-2082193786.png

通过diff 8.8.1的补丁,很容易发现修复点,位于core\modules\file\file.module

1077935-20200126135442979-1857026228.png

补丁在文件名两侧进行了trim(..., '.'),结合漏洞通告可以知道应该是文件名过滤不严导致.开头的文件上传。

原生模块分析

漏洞点位于_file_save_upload_single函数

function _file_save_upload_single(\SplFileInfo $file_info, $form_field_name, $validators = [], $destination = FALSE, $replace = FileSystemInterface::EXISTS_REPLACE) {...// Begin building file entity.$values = ['uid' => $user->id(),'status' => 0,'filename' => $file_info->getClientOriginalName(),//'uri' => $file_info->getRealPath(),'filesize' => $file_info->getSize(),];$values['filemime'] = \Drupal::service('file.mime_type.guesser')->guess($values['filename']);$file = File::create($values);...// If we made it this far it's safe to record this file in the database.$file->save();...return $file;
}

全局搜索调用本函数的地方,发现只在core/modules/file/file.module:file_save_upload()中被调用。

由于此处不是控制器,无法直接调用,因此继续反向追踪调用此函数的位置。在多处找到调用,比如位于core/modules/update/src/Form/UpdateManagerInstall.php:submitForm(),这是update模块的updatemanagerinstall表单。

public function submitForm(array &$form, FormStateInterface $form_state) {$local_cache = NULL;$all_files = $this->getRequest()->files->get('files', []);if ($form_state->getValue('project_url')) {...}elseif (!empty($all_files['project_upload'])) {$validators = ['file_validate_extensions' => [$this->archiverManager->getExtensions()]];if (!($finfo = file_save_upload('project_upload', $validators, NULL, 0, FileSystemInterface::EXISTS_REPLACE))) {// Failed to upload the file. file_save_upload() calls// \Drupal\Core\Messenger\MessengerInterface::addError() on failure.return;}$local_cache = $finfo->getFileUri();}

这里的$validators通过$this->archiverManager->getExtensions()调用archiver管理器进行取值,由于这里设计很多内部成员变量,因此通过调试的方式来分析会快一些。下面就开始尝试构造路由到这个update模块。

通过在update模块根目录下的update.routing.yml路由文件可以发现相应的路由:

1077935-20200126135506827-462171736.png

1077935-20200126135521722-882303831.png

尝试上传.htaccess

1077935-20200126135537980-652002193.png

果然受到了限制,下面调试跟进这个$validators是如何取值的。最终跟进core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php:getDefinitions()方法,这里通过遍历所有module目录下的src/plugin/archiver/下的所有php文件,然后解析这个php文件的annotation。调试后发现只有system模块下存在这个目录:

1077935-20200126135550458-353069893.png

可以看到这里的annotation中限定了后缀名为{"tar", "tgz", "tar.gz", "tar.bz2"}

到这里就可以停止调试了,这个update模块由于限制了后缀名,无法满足我们的条件。下面再找一些$validators的值不是$this->archiverManager->getExtensions()的模块。

发现core/modules/image/src/Controller/QuickEditImageController.php:upload()

  public function upload(EntityInterface $entity, $field_name, $langcode, $view_mode_id) {$field = $this->getField($entity, $field_name, $langcode);$field_validators = $field->getUploadValidators();$field_settings = $field->getFieldDefinition()->getSettings();$destination = $field->getUploadLocation();// Add upload resolution validation.if ($field_settings['max_resolution'] || $field_settings['min_resolution']) {$field_validators['file_validate_image_resolution'] = [$field_settings['max_resolution'], $field_settings['min_resolution']];}// Create the destination directory if it does not already exist.if (isset($destination) && !$this->fileSystem->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY)) {return new JsonResponse(['main_error' => $this->t('The destination directory could not be created.'), 'errors' => '']);}// Attempt to save the image given the field's constraints.$result = file_save_upload('image', $field_validators, $destination);...

这里的$validators是通过$field->getUploadValidators()来取值的,跟之前的module同样的思路,先构造路由然后进行调试跟进。

访问quickedit/image/upload/node/1/field_image/en/full映射到本控制器,然后跟进getUploadValidators()。经过一系列跟进之后发现配置在config表中,sql语句大概是SELECT name, data FROM config WHERE collection = '' AND name ='field.field.node.article.field_image';

1077935-20200126135611084-2052744781.png

剩下的调用file_save_upload的地方也都做了验证,没有可以利用的地方,都限制了文件后缀名。

第三方模块分析

看完所有调用点之后有点怀疑人生,会不会是类似于CVE-2018-7600那样,durpal6中虽然有漏洞,但是没找到错误的写法从而无法利用?通过再次阅读官方通告之后发现也许真是这样,但是幸运的是...

1077935-20200126135625633-836619609.png

意思大概是通过第三方contributed模块可能导致.htaccess文件上传?

然后我尝试在第三方模块中寻找与文件上传相关的模块,找到了一个名为imce的文件/图片管理模块

IMCE is an image/file uploader and browser that supports personal directories and quota.

安装完毕之后直接访问路径/imce/public即可获得一个管理界面(后台)。

上传.php文件会自动在后面加上.txt后缀。尝试上传.htaccess

1077935-20200126135645338-734454980.png

然而这只是个前端过滤而已,通过抓包修改文件名即可成功上传。

1077935-20200126135706315-406294112.png

通过阅读源码发现opUpload()方法调用了file_save_upload()进行文件上传。

  public function opUpload(ImceFM $fm) {...$validators = [];// Extension validator$exts = $fm->getConf('extensions', '');$validators['file_validate_extensions'] = [$exts === '*' ? NULL : $exts];...// Save filesif ($files = file_save_upload('imce', $validators, $destination, NULL, $replace)) {

其中后缀名$validators从$fm->getConf('extensions','')获取。跟踪源码后发现,也是从config表中找到imce 模块的一些配置

1077935-20200126135720203-1458089766.png

由于$validators是*,即为不限制后缀名,从而造成.htaccess文件上传。

补丁

通过diff 8.8.1的补丁,很容易发现修复点,位于core\modules\file\file.module

1077935-20200126135731296-1521850903.png

补丁在文件名两侧进行了trim(..., '.')。

上传之后变成

1077935-20200126135741403-1018031497.png

参考

https://www.drupal.org/sa-core-2019-010

这篇关于Drupal SA-CORE-2019-010 .开头文件名(如.htaccess) 文件上传的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/536295

相关文章

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

把Python列表中的元素移动到开头的三种方法

《把Python列表中的元素移动到开头的三种方法》在Python编程中,我们经常需要对列表(list)进行操作,有时,我们希望将列表中的某个元素移动到最前面,使其成为第一项,本文给大家介绍了把Pyth... 目录一、查找删除插入法1. 找到元素的索引2. 移除元素3. 插入到列表开头二、使用列表切片(Lis

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

SpringBoot整合Sa-Token实现RBAC权限模型的过程解析

《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学... 目录前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备二、表结

GitLab文件的上传与下载方式

《GitLab文件的上传与下载方式》:本文主要介绍GitLab文件的上传与下载方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录GitLab 项目拉取到本地GitLab 项目上传方法方法 1:本地项目未初始化Git方法 2:本地项目已初始化GitGitLab 上

Nginx 413修改上传文件大小限制的方法详解

《Nginx413修改上传文件大小限制的方法详解》在使用Nginx作为Web服务器时,有时会遇到客户端尝试上传大文件时返回​​413RequestEntityTooLarge​​... 目录1. 理解 ​​413 Request Entity Too Large​​ 错误2. 修改 Nginx 配置2.1

无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案

《无法启动此程序因为计算机丢失api-ms-win-core-path-l1-1-0.dll修复方案》:本文主要介绍了无法启动此程序,详细内容请阅读本文,希望能对你有所帮助... 在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是"api-ms-win-core-path-l1-1-0.dll丢失