Drupal SA-CORE-2019-010 .开头文件名(如.htaccess) 文件上传
drupal .开头文件名 文件上传
通过diff 8.8.1的补丁,很容易发现修复点,位于core\modules\file\file.module
补丁在文件名两侧进行了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
路由文件可以发现相应的路由:
尝试上传.htaccess
果然受到了限制,下面调试跟进这个$validators是如何取值的。最终跟进core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php:getDefinitions()
方法,这里通过遍历所有module目录下的src/plugin/archiver/
下的所有php文件,然后解析这个php文件的annotation。调试后发现只有system模块下存在这个目录:
可以看到这里的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';
剩下的调用file_save_upload
的地方也都做了验证,没有可以利用的地方,都限制了文件后缀名。
第三方模块分析
看完所有调用点之后有点怀疑人生,会不会是类似于CVE-2018-7600那样,durpal6中虽然有漏洞,但是没找到错误的写法从而无法利用?通过再次阅读官方通告之后发现也许真是这样,但是幸运的是...
意思大概是通过第三方contributed模块可能导致.htaccess文件上传?
然后我尝试在第三方模块中寻找与文件上传相关的模块,找到了一个名为imce的文件/图片管理模块
IMCE is an image/file uploader and browser that supports personal directories and quota.
安装完毕之后直接访问路径/imce/public
即可获得一个管理界面(后台)。
上传.php文件会自动在后面加上.txt后缀。尝试上传.htaccess
然而这只是个前端过滤而已,通过抓包修改文件名即可成功上传。
通过阅读源码发现opUpload()
方法调用了file_save_upload()
进行文件上传。
public function opUpload(ImceFM $fm) {
...
$validators = [];
// Extension validator
$exts = $fm->getConf('extensions', '');
$validators['file_validate_extensions'] = [$exts === '*' ? NULL : $exts];
...
// Save files
if ($files = file_save_upload('imce', $validators, $destination, NULL, $replace)) {
其中后缀名$validators从$fm->getConf('extensions','')
获取。跟踪源码后发现,也是从config表中找到imce 模块的一些配置
由于$validators是*,即为不限制后缀名,从而造成.htaccess文件上传。
补丁
通过diff 8.8.1的补丁,很容易发现修复点,位于core\modules\file\file.module
补丁在文件名两侧进行了trim(..., '.')。
上传之后变成
参考
https://www.drupal.org/sa-core-2019-010
Drupal SA-CORE-2019-010 .开头文件名(如.htaccess) 文件上传的更多相关文章
- Asp.Net Core 轻松学-一行代码搞定文件上传 JSONHelper
Asp.Net Core 轻松学-一行代码搞定文件上传 前言 在 Web 应用程序开发过程中,总是无法避免涉及到文件上传,这次我们来聊一聊怎么去实现一个简单方便可复用文件上传功能:通过创建 ...
- Asp.Net Core 轻松学-一行代码搞定文件上传
前言 在 Web 应用程序开发过程中,总是无法避免涉及到文件上传,这次我们来聊一聊怎么去实现一个简单方便可复用文件上传功能:通过创建自定义绑定模型来实现文件上传. 1. 实现自定义绑定模型 1 ...
- 在 .NET Core项目中使用UEditor图片、文件上传服务
在.NET Framework中使用UEditor时,只需要将UEditor提供的后端服务,部署为一个子程序,即可直接使用文件上传相关的服务,但是UEditor官方并未提供.Net Core的项目,并 ...
- ASP.NET Core文件上传与下载(多种上传方式)
前言 前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了. 打算写个系列,但是还没想好目录,今天先来一篇,后面在整理吧. ASP.NET Core 2.0 发展到现在,已经 ...
- 用VSCode开发一个asp.net core2.0+angular5项目(5): Angular5+asp.net core 2.0 web api文件上传
第一部分: http://www.cnblogs.com/cgzl/p/8478993.html 第二部分: http://www.cnblogs.com/cgzl/p/8481825.html 第三 ...
- 通过jQuery和C#分别实现对.NET Core Web Api的访问以及文件上传
准备工作: 建立.NET Core Web Api项目 新建一个用于Api请求的UserInfo类 public class UserInfo { public string name { get; ...
- 循序渐进学.Net Core Web Api开发系列【5】:文件上传
系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇介绍通 ...
- Asp.Net Core 2.0 WebUploader FastDfs 文件上传 分段上传
功能点: 1. 使用.net core 2.0 实现文件上传 2. 使用webuploader实现单文件,多文件上传 3. 使用webuploader实现大文件的分段上传. 4. 使用webuploa ...
- ASP.NET Core MVC如何上传文件及处理大文件上传
用文件模型绑定接口:IFormFile (小文件上传) 当你使用IFormFile接口来上传文件的时候,一定要注意,IFormFile会将一个Http请求中的所有文件都读取到服务器内存后,才会触发AS ...
随机推荐
- WebLogic Developer版创建domain
1.直接在cmd命令窗口中运行%MW_HOME%目录下的configure.cmd文件,这个过程会解压一些jar文件,知道提示是否配置domain: 2.可以通过执行%MW_HOME%\oracle_ ...
- 博客同步到CSDN客户端
同步本人博客到CSDN客户端 http://blog.csdn.net/johnnyz1234
- seek方法补充
seek 默认模式是从文件的开始移动光标,一共有0.1.2三种模式 f=open('seek.txt','r',encoding='utf-8') print(f.tell()) f.seek(10, ...
- 泛圈科技Yottachain区块链云存储打破传统云迎来价值数据存储
随着物联网时代的发展,更多的数据随之产生.从智能设备到电脑再到视频游戏机,各种各样的信息从不同的电子产品源源不断地涌入.通常,人们将数据存储在本地驱动器中.但是,由于产生的数据量是无限的,超过了本地存 ...
- CodeForces - 1239A
推公式题,万万没想到斐波那契啊
- python实现上传文件到linux指定目录
今天接到一个小需求,就是想在windows环境下,上传压缩文件到linux指定的目录位置并且解压出来,然后我想了一下,这个可以用python试试写下. 环境:1.linux操作系统一台2.window ...
- $vjudge-dp$专题题解
因为感觉题解写不了多少,,,就懒得一道道题目慢慢写了,汇总了算了$QAQ$ 昂然后因为我估计以后还会有些什么$dp$专题啊$balabala$的,,,然后谢总肯定又会建一堆小组啥的,,,所以还是放个链 ...
- ObserverPattern(观察者模式)-----Java/.Net
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).比如,当一个对象被修改时,则会自动通知它的依赖对象.观察者模式属于行为型模式
- vs2017编译installer项目提示缺少visualstudio2010shell(Integrated)-CHN
这个问题折腾我一天,欲仙欲死啊~~~~~~! 国内的网站各种百度,都不行. 还是Google大神比较强,在stackoverflow.com找到了解决方法,说来也简单,难者不会,会者不难! ----- ...
- Java后台创建Socket服务接收硬件终端发送的数据
最近项目中有遇到后台接收硬件终端发送的数据并解析存储的需求,代码总结如下(有时间再来一一讲解,最近比较忙): @Override public void start() { ExecutorServi ...