RSS Feed
更好更安全的互联网

Drupal 8 配置文件下载漏洞分析

2016-09-29

Author: p0wd3r (知道创宇404安全实验室)

Date: 2016-09-22

0x00 漏洞概述

1.漏洞简介

Drupal ( https://www.drupal.org )是一个自由开源的內容管理系统,近期研究者发现在其8.x < 8.1.10的版本中发现了三个安全漏洞,其中一个漏洞攻击者可以在未授权的情况下下载管理员之前导出的配置文件压缩包config.tar.gz。Drupal官方在9月21日发布了升级公告( https://www.drupal.org/SA-CORE-2016-004 )。

2.漏洞影响

未授权状态下下载管理员之前导出的配置文件

3.影响版本

8.x < 8.1.10

0x01 漏洞复现

1. 环境搭建

Dockerfile(来自Docker Hub)

 

 

2.漏洞分析

首先我们进入后台把配置文件导出,默认导出到了/tmp/config.tar.gz

export
然后看代码,我们在 core/modules/system/system.routing.yml 可以看到这样一个路由项:

admin

这是访问管理员页面时的路由,可以看到 requirements._permission 指定了需要管理员权限。

然后我们再看这一项:

router

可以看到并没有设置 _permission ,并且 _access=TRUE ,也就是说在未授权的情况下是可以访问这个功能的。

接下来我们跟进它的controller,在 core/modules/system/src/FileDownloadController.php 第41-68行的 download 函数:

函数获取了我们传入的 file 参数,与 $scheme 拼接后检测文件是否存在。我们访问 http://xxx/system/temporary/?file=config.tar.gz 然后下断点动态调试,执行到该函数时各变量的值如下:

uri

也就是说 $scheme 的值是 temporary 。然后程序进入了 file_stream_wrapper_valid_scheme 函数检查协议有效性,动态跟进直到 core/lib/Drupal/Core/StreamWrapper/LocalStream.php 中第495-506行的 url_stat 函数:

path

可以看到 temporary://config.tar.gz 被映射到了 /tmp/config.tar.gz ,也就是我们刚备份到的位置,所以也就通过了 file_exists

通过检查后回到 download 函数中,接下来执行了如下语句:

 

跟进 invokeAll 函数,在 core/lib/Drupal/Core/Extension/ModuleHandler.php 中第397-409行:

 

 

动态调试情况如下图:

funcs

implementations 的值有 config ,  file , image ,遍历这三个值并调用相应函数:

config_file_download
file_file_download
image_file_download

首先调用的是 config_file_download ,位于 core/modules/config/config.module 第64-78行:

可以看到当且仅当文件是 config.tar.gz 时设置响应头以供下载,最后当返回到 download 函数时,执行如下语句:

将最终的响应返回给了用户,从而触发了下载漏洞。

download

到这里有一个想法,我们可不可以传入 ../../etc/passwd\x00config.tar.gz 这样的参数来截断并且跳到别的目录呢?

我们看一下在 core/lib/Drupal/Core/StreamWrapper/LocalStream.php 中第120到144行的 getLocalPath() 函数,它在上面提到的 url_stat 函数中被调用:

可以看到路径中的 ../ realpath 过滤,跳出 /tmp 的目的也就不能达到了。

另外还有一个方面, config_file_download 函数比较苛刻,只允许下载  config.tar.gz ,而 image_file_download 是为了下载图片,那么 file_file_download 函数能否供我们利用以下载系统的敏感文件呢?

file_file_download 函数在 core/modules/file/file.module 中第582-633行:

 

 

有以下三点:

- 根据注释可以看到该函数是根据 uri 来查询数据库中的文件记录再进行下载
- 我们请求中的 $schemetemporary ,在 file_stream_wrapper_valid_scheme($scheme) && file_exists($uri) 限制了我们只能下载 /tmp 目录下存在的文件
- 默认 /tmp 下除了 config.tar.gz 只有 .htaccess

综合这三点来看 file_file_download 函数是不存在下载漏洞的。

所以总的来说该漏洞只能在管理员导出备份的情况下下载 /tmp/config.tar.gz

3.补丁分析

patch

增加了权限验证,使未授权用户不能下载 cnofig.tar.gz

0x02 修复方案

升级Drupal到8.1.10

0x03 参考

作者:rungobier | Categories:技术分享 | Tags:

发表评论