freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

Drupal XSS漏洞(CVE-2019-6341)原理解析
Deutsh 2022-09-21 07:53:18 231347
所属地 江西省

影响软件:Drupal

版本号:8.5.0

方式:通过文件模块或者子系统上传恶意文件触发XSS漏洞

效果:JS代码执行(Cookies 资料窃取、会话劫持、钓鱼欺骗、网页挂马等)

漏洞测试环境:KALI + vulhub

原理解析:何为Drupal

[**Drupal**]

Drupal | Wikiwand

是用PHP编写以GNU许可形式发布的开源免费的可自由使用的CMS。

Drupal核心

当您下载并安装的Drupal,要正安装的文件通常被称为Drupal核心。核心相当于一个基本网站的“引擎”功能,与其他应用的现成功能一起,创建功能相对完善的网站。 Drupal核心的主要组件功能包括创建和管理

内容

文件上传/下载

菜单

用户帐户

角色和权限

分类

论坛

次提取并以各种形式如列表和表显示内容

基于所见即所得内容编辑器

Drupal核心还包括一个功能丰富的搜索引擎,多语言功能,以及记录和错误报告。

Drupal的特殊机制

function file_create_filename($basename, $directory) {
  // Strip control characters (ASCII value < 32). Though these are allowed in
  // some filesystems, not many applications handle them well.
  $basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);
  if (substr(PHP_OS, 0, 3) == 'WIN') {
    // These characters are not allowed in Windows filenames
    $basename = str_replace([':', '*', '?', '"', '<', '>', '|'], '_', $basename);
  }

  // A URI or path may already have a trailing slash or look like "public://".
  if (substr($directory, -1) == '/') {
    $separator = '';
  }
  else {
    $separator = '/';
  }

  $destination = $directory . $separator . $basename;

  if (file_exists($destination)) {
    // Destination file already exists, generate an alternative.
    $pos = strrpos($basename, '.');
    if ($pos !== FALSE) {
      $name = substr($basename, 0, $pos);
      $ext = substr($basename, $pos);
    }
    else {
      $name = $basename;
      $ext = '';
    }

    $counter = 0;
    do {
      $destination = $directory . $separator . $name . '_' . $counter++ . $ext;
    } while (file_exists($destination));
  }

  return $destination;
}

对于早期版本的Drupal其出现问题的特殊机制在于其对上传文件的命名机制,对上传文件进行重命名并不是一个罕见的机制,但Drupal却没有直接重命名这么彻底,而是对于同名文件会在其后接上"_ + 序号",例如我们连续上传3张命名相同的照片,则在Drupal中存储这三张照片的命名则是:

https://image.3001.net/images/20220920/1663680354_6329bf62271ed29b2c2ee.png!small

该机制本身没有什么问题,然而问题出现在了preg_replace()函数的处理机制

我们先看代码第一行:$basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);

此处代表会将 小于 0x20 的字符转化为_,原因在于小于 0x20 的字符大多都是(ASCII)控制字符,所以在文件名中并不应该出现他们

但再仔细看着一句,**最后加了/u说明其将主题字符串视为UTF-8,以确保对UTF-8的兼容性(ASCII可以看成是UTF-8的子集,在0x00 ~ 0x7F二者一致)**我们找来官方对于/u更进一步的解释

1image.png

在综合代码中,对于出错后的处理机制

对于preg_replace()函数,在出现错误后,会返回NULL,再综合下述的拼接语句

$destination = $directory . $separator . $name . '_' . $counter++ . $ext;

会产生"_ + 序号"的文件名,没有后缀,后续就可以直接被我们调用利用构造XSS了

构造特殊无效utf-8字符

这里遵循上述截图中的提示,可以构造多种无效utf-8字符

比如说依据最后一句Five and six octet UTF-8 sequences are regarded as invalid.

我们可以构造出这样的非法文件名:�����.gif``������.gif

2image.png

成功

亦或是一些特殊的字符(包括但不限于)

3image.png

4image.png

5image.png

  • æ

  • å

  • ÿ

其他的我们就不测试了,总体来说,不合法的UTF-8有如下特征:

不合法UTF-8字符


1:UTF-8 单字节字符超出范围。开头字节不能是 254、255 或 128 和 191 之间(含)的任何字符


2:字节序列中的结尾字节的值超出范围。连续字节必须在 128 和 191 之间(含)


3:UTF-8 字节序列不完整。COPY 在字符串结束之前没有找到多字节字符所需数量的连续字节


4:UTF-8 字符作为代理保留。代理码位 (U+D800 - U+DFFF) 无效


5:字节序列超出最大 UTF-8 码位


7:UTF-8 字节序列没有匹配的码位


注意

此处我们不可以将文件名改为UTF-8编码后的格式,比如说\xe2\x28\xa1.gif这样的,因为默认会过滤掉最后一个\前的所有路径

https://image.3001.net/images/20220920/1663680788_6329c1146d86552a29f07.png!small

寻找上传点

该漏洞需要利用drupal文件模块上传文件的漏洞,伪造一个图片文件,上传,文件的内容实际是一段HTML代码,内嵌JS,这样其他用户在访问这个链接时,就可能触发XSS漏洞

文件存储位置

通过探索,发现两处存储上传照片的位置:

  • /var/www/html/sites/default/files/pictures/2022-09
    此处用于存放用户信息中,用户头像信息的照片,包括新建用户、更改原用户

  • /var/www/html/sites/default/files/inline-images/2022-09
    此处用于存放,用户评论文章的照片、管理者回复编辑照片的路径

两处中的照片,均可通过上述机制重新命名为不带文件后缀的版本

上传点

以下附上了一些相关验证的截图

经测试,以下几处均存在上传点,且可成功上传到上述两处文件存储目录之一

http://127.0.0.1:8080/admin/people/create

6image.png

http://127.0.0.1:8080/user/1/edit

7image.png

http://127.0.0.1:8080/user/register

9image.png

http://127.0.0.1:8080/node/1#comment-form

8image.png

http://127.0.0.1:8080/node/1/edit

http://127.0.0.1:8080/comment/1/edit

https://image.3001.net/images/20220920/1663681162_6329c28ab0b055dd89266.png!small

其中带有参数的,比如说 1 表示当前是管理员用户登录的场景,注意区分

完成

至此最重要的步骤已经完成了,接下来我们只需构建XSS代码上传访问即可

<html>
<head>
</head>
  <body>
  <a id='a' href="http://127.0.0.1/drupal-8.6.2/sites/default/files/2022-09/_0" type="text/html">123</a>

  <script type="text/javascript">
    var a  = document.getElementById('a')
    a.click()
  </script>
  </body>
</html>

参考文章

Vulhub

Drupal 1-click to RCE 分析

Zero Day Initiative - A Series of Unfortunate Images: Drupal 1-click to RCE Exploit Chain Detailed

PHP: Possible modifiers in regex patterns - Manual

Drupal | Wikiwand

多字节字符加载错误

例如无效的utf8字符串? - 问答 - 腾讯云开发者社区-腾讯云

preg_replace PREG_BAD_UTF8_ERROR

PHP preg_replace() 函数

# 漏洞 # 渗透测试 # web安全 # 漏洞分析
本文为 Deutsh 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
WEB安全相关
Deutsh LV.5
欢迎来我的博客 www.shtwo.top
  • 45 文章数
  • 36 关注者
File Structure 基础 && PUTS 流程分析
2023-01-30
Linux 堆内存结构分析(中)| PWN
2022-12-30
Canary补充 - TLS && Canary原始值在内存中的位置
2022-12-21
文章目录