导语:在本文中,我们主要对ImageMagick的内存泄漏漏洞进行分析。

概述

在本文中,我们主要对ImageMagick的内存泄漏漏洞进行分析。

ImageMagick是用于创建、编辑、转换位图图像的软件,它可以读取和写入超过200种格式的图像,包括PNG、JPEG、GIF、HEIC、TIFF、DPX、EXR、WebP、Postscript、PDF和SVG。使用ImageMagick还可以对图像进行调整大小、翻转、镜像、旋转、扭曲、剪裁和变换,可以调整图像颜色、应用各种特殊效果,可以绘制文本、线条、多边形、椭圆和Bézier曲线。

这是一个具有丰富功能的图像处理库,如果我们在搜索引擎中查找“如何在PHP中调整图片大小”和“如何剪裁图像”,那么很可能会搜到关于使用ImageMagick的建议。然而,这个库长期存在安全问题,我们本次对一个新发现的漏洞进行分析,同时会回顾一些此前发现的漏洞。

CVE-2018-16323的PoC生成工具(通过ImageMagick中的XBM图像实现内存泄漏)请参考:https://github.com/ttffdd/XBadManners

内存泄漏漏洞分析

在过去两年中,几乎每个月都会爆出一个ImageMagick库的漏洞。幸运的是,其中的许多漏洞都是某种不适用的DoS漏洞,并不会造成严重的安全问题。但是最近,我们注意到一个有趣的漏洞,其编号是CVE-2018-16323。

这一漏洞听起来很简单,但我们没有找到关于此漏洞利用的任何信息。

我们引用CVE的提交内容:

1.png

如果像素的十六进制值为负,则XBM编码器会将十六进制图像数据保留为未初始化的模式。

接下来,我们对XBM文件格式进行分析,常见的XBM图像如下所示:

2.png

这与C语言代码非常相似。这是一种非常老的格式,在X Window System中用于存储X GUI中使用的光标和图标位图。keyboard16_bits数组中的每个值都代表8个像素,每个像素是一个比特,其中编码黑色或白色这两种颜色中的一种。所以,并没有值为负的像素,因为一个像素只有两个可能的值。在下文中,我们将该数组称为XBM主体数组(XBM Body Array)。

我们分析ImageMagick的代码,并尝试找出“像素为负”具体代表什么含义。在这里,需要ReadXBMImage()函数,该函数用于读取图像,并准备用于图像处理的数据。似乎变量image中包含正在处理的图像数据(第225行)。

接下来,在第344-348行的位置是内存分配,并且指针数据现在指向所分配的存储器的起始地址,指针p也指向了同一地址。

3.png

接下来的第352-360行和第365-371行,代码相同,但它们分别负责处理不同版本的XBM图像。从提交中可以看出,两个分支都存在相同的漏洞,因此我们仅选取其中一个进行分析。XBM主体数组的读取过程发生在函数XBMInteger()中,它将int返回给变量c。此外,在第358行,存储在变量c中的值被赋值给p指针指向的变量,然后该指针将递增。

4.png

根据提交,我们看到先前版本中,会检查变量c是否为负值。如果c为负值,那么将会中断循环过程,这也就是内存泄漏的原因。如果XBM主体数组的第一个值为负,那么所有分配的内存都将保持未初始化,并且其中可能包含来自内存的敏感数据,这些数据将会进一步处理,以生成新的图像。在修复后版本中,这一问题已经被修复,现在如果XBM主体数组的值为负,那么ImageMagick将会抛出错误。

5.png

接下来,我们认真分析XBMInteger()函数。该函数将指针图像和指针hex_digits作为参数。后者是在第305行初始化的数组。该函数允许将值保存为XBM主体数组中的十六进制值。XBMInteger()读取XBM主体数组中定义的下一个字节,并将其赋值给无符号INT型变量。这一函数读取十六进制字符,直至出现停止标记。这也就意味着,我们可以指定任意长度的十六进制值,而不是char类型的0-255之间的预期长度范围。我们可以设置任何无符号INT值,它将存储在变量中,并且随后会将该变量值转换为有符号的INT类型。

6.png

所以,我们只要为XBM主体数组设置一个特定值(大于2147483647,或十六进制的0x80000000),该数组将转换为INT类型负数值。PoC如下:

#define test_width 500
#define test_height 500
static char test_bits[] = {
0x80000001, };

泄露的内存数量取决于攻击者设置高度和宽度参数的方式。如果设置为500×500,那么将会泄露31250(500*500/8)字节!但实际上,这取决于应用程序如何使用ImageMagick,它可能会将图像剪裁到一定的宽度和高度。

当我们在测试这个PoC时,遇到了一个问题。正如CVE的漏洞细节中所描述的那样,并非在7.0.8-9之内的所有ImageMagick版本都易受攻击。我们发现了一个用于修复另一个漏洞(CVE-2017-14175,XBM图像处理过程中DoS漏洞)的提交版本,正是这个特定的提交版本才将漏洞引入到代码中。

接下来,让我们尝试运行PoC。我们首先安装一个易受攻击的版本(例如6.9.9-51)。接下来,运行poc.xbm到poc.png的转换过程,我们将在xbm.c文件中调用处理XBM图像,从而调用存在漏洞的代码。

生成的图像如下所示:

7.png

我们可以在生成的图像中,看到一些噪点,这些噪点就是泄露的内存内容,每个黑色或白色像素实际上都是泄露内存中的一些信息。如果我们重复转换过程,可能会得到另一个图像,因为会捕获另一个内存块。

那么,我们如何提取泄露的内存字节呢?

只需要将其转换回来,将poc.png转换为leak.xbm。现在,就能在XBM主体数组中找到泄露的内存字节,这种格式非常易于解析,我们进行解压缩,即可获取到泄露的内存字节。

所以,总结一下我们的攻击思路:

1、生成PoC;

2、在存在漏洞的应用上,将PoC上传到头像;

3、保存生成的PNG/JPG/GIF图像;

4、从图像中提取数据。

Ttffdd为这个名为XBadManners的漏洞编写了一个简单易用的工具,该工具会生成PoC,并且从图像中恢复泄露的数据。

注意,ImageMagick是一个比较智能的库,我们可以将包含XBM图像数据的poc.png上传到服务器,如果没有正确检查图像类型,那么ImageMagick会将poc.png作为XBM图像处理。因此,如果只将上传文件的后缀名改为“*.png”,那么可能将无法实现漏洞利用。

ImageMagick安全性分析

CVE-2018-16323并不是ImageMagick软件中发现的第一个严重漏洞。该软件此前曾经发现过大量漏洞,目前已经有近500个已经修复的漏洞。每个月可能都会发现一些难以利用或不适用的新漏洞,每年都会发现一些具有较大影响的严重漏洞。

ImageMagick最严重的漏洞包括远程代码执行漏洞、SSRF漏洞、svg和mvg文件本地文件读取/移动/删除漏洞。这些漏洞在2016年4月由stewie和Nikolay Ermishkin发现。

· CVE-2016-3714 远程代码执行漏洞

· CVE-2016-3718 SSRF漏洞

· CVE-2016-3715 文件删除漏洞

· CVE-2016-3716 文件移动漏洞

· CVE-2016-3717 本地文件读取漏洞

在ImageMagick的6.9.3-9(2016年4月30日发布)版本中,已经实现补丁的修复。这一漏洞广泛受到漏洞赏金猎人的欢迎。

· Yahoo ImageTragick:https://www.zdnet.com/article/yahoos-polyvore-vulnerable-to-imagemagick-flaw-researcher-receives-little-reward/

· HackerOne ImageTragick:https://hackerone.com/reports/135072

· Facebook ImageTragick 2017:https://4lemon.ru/2017-01-17_facebook_imagetragick_remote_code_execution.html

CVE-2017-15277是由Emil Lerner在2017年7月发现,该漏洞是GIF图像处理过程中存在内存泄漏漏洞。如果不存在全局调色板或局部调色板,那么ImageMagick会将调色板保持在未初始化的状态,从而导致内存泄漏在调色板的位置发生。这一漏洞同样受到赏金猎人的欢迎。

· HackerOne:https://hackerone.com/reports/302885

· Twitter:https://hackerone.com/reports/315906

· MailRu:https://hackerone.com/reports/251732

GhostScript类型混淆远程代码执行漏洞(CVE-2017-8291)是在2017年5月发现的,它并不是ImageMagick的漏洞,但该漏洞会影响ImageMagick,因为ImageMagick使用GhostScript来处理PostScript的某些类型的图像,例如EPS、PDF文件。

· Metasploit模块:https://www.rapid7.com/db/modules/exploit/unix/fileformat/ghostscript_type_confusion

CVE-2018-16509是GhostScript中的另一个远程代码执行漏洞,在2018年8月被发现,同样影响ImageMagick。

· Google Project Zero对该漏洞的分析:https://bugs.chromium.org/p/project-zero/issues/detail?id=1640

· 漏洞细节:https://medium.com/@NumbShiva/imagemagic-rce-f364a9f50a14

· ExploitDB:https://www.exploit-db.com/exploits/45369/

到底有多少严重的安全漏洞我们仍然未知?我们并不清楚。但是,根据已经发现的漏洞,我们绘制了一个ImageMagick的安全漏洞时间轴。

8.png

如何以安全的方式使用ImageMagick

当然,最安全的方式是停止使用ImageMagick。但作为负责任的安全人员,我们不会向用户提出这样的建议,而是建议用户以安全的方式来运行该程序,从而降低安全风险。

大家已经注意到,ImageMagick有很多漏洞接连出现,因此它也会经常进行更新。如果使用ImageMagick,请留意新版本更新,并确保始终使用最新版本,需要注意的是,ImageMagick并不会在官方存储库中频繁更新,因此其中可能包含旧的存在漏洞版本,因此最好能从源代码安装稳定的ImageMagick版本。

但是,如之前看到的,修复旧的漏洞可能会产生新的漏洞。因此,仅更新到最新版本可能无法确保安全。

在这种情况下,我们建议用户在Docker这类隔离环境中运行ImageMagick,并设置使用ImageMagick服务所需的最小权限,将其放置于具有最小网络权限的隔离网段中,并且仅使用这一隔离环境来执行使用ImageMagick处理自定义用户图像的特定任务。

此外,ImageMagick也配置了一些安全策略:https://imagemagick.org/source/policy.xml

在这里,可以找到关于ImageMagick安全性的详细开发人员指南:https://imagemagick.org/script/security-policy.php

源链接

Hacking more

...