一次奇特的Facebook图片缓存泄露漏洞——10000美金

iso60001  2076天前

22.jpg

介绍

一年前,大概在2018年2月,我正在测试Facebook Messenger的Android客户端会如何处理已损坏的GIF图像。我之所以会做这项研究是因为受到了Imagemagick处理gif图片时出现的“未初始化内存泄露”漏洞的启发,其漏洞PoC为gifoeb

我发现Messenger在处理gifoeb生成的恶意图像时只会崩溃,而Facebook并不认为这是DoS漏洞,拒绝给我漏洞奖励。

好吧。让我深入研究一下,看看怎样才能获得赏金。

基本的GIF图像

我发现了GIF图像格式的清晰描述,主标题应如下所示:

偏移量    长度      内容
  0      3 bytes  "GIF"
  3      3 bytes  "87a" or "89a"
  6      2 bytes  <逻辑屏幕宽>
  8      2 bytes  <逻辑屏幕高>
 10      1 byte   bit 0:    全局颜色表标记 (GCTF)
                  bit 1..3: 颜色分辨率
                  bit 4:    全局颜色表排序标志
                  bit 5..7: 全局颜色表大小: 2^(1+n)
 11      1 byte   <背景颜色索引>
 12      1 byte   <像素长宽比>
 13      ? bytes  <全局颜色表(0..255 x 3 bytes) if GCTF is one>
         ? bytes  <数据块>
         1 bytes  <Trailer> (0x3b)

如果你想深入了解,可点击:http://www.onicos.com/staff/iz/formats/gif.html#header。

我决定先创建一个最短小的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  <逻辑屏幕宽度>
f.write(struct.pack('<h', screenWidth))

#   8  2 bytes  <辑屏幕高度>
f.write(struct.pack('<h', screenHeight))

#  10  1 byte   bit 0:全局颜色表标志 (GCTF)
#               bit 1..3: 颜色分辨率
#               bit 4:全局颜色表排序标志
#               bit 5..7: 全局颜色表大小: 2^(1+n)
bits = int('00000010', 2)
f.write(struct.pack('<b', bits))

#  11  1 byte   <背景颜色索引>
f.write(struct.pack('<b', 0))

#  12  1 byte   <像素长宽比>
f.write(struct.pack('<b', 1))

#  13  ? bytes  <全局颜色表(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()

需要注意的是,我的这张图片啥内容都没有,只是为了测试而已。

Facebook Messenger

我开始用我生成的GIF文件测试Facebook Messenger的Android版本(我试了很多不同大小的变图片),不断传输这张图片,看看会发生什么。但很可惜,我没看到发生任何奇怪的事情......但是,当我在笔记本电脑上打开Messenger时,发现我上传的图片变成如下所示:

33.png

等等,我的GIF是没有任何内容的,那么我现在看到的图像是什么?

我改变了GIF文件尺寸,再次测试,这次看到一个白噪声图像,嗯?很奇怪:

44.png

真奇怪,我再次上​​传了相同的文件并观察到:

55.png

好像两次图像有点不同?我明明上传了相同的GIF文件啊?

在我把这个奇怪的图像拉大后点击播放时:

66.png

于是,我开始生成不同长宽比的图片,上传测试。

最终,我看到了这个画面:

77.png

我意识到我的这个GIF图像获取了一些缓存信息,因为我的图像本该什么都没有。

视频链接:https://v.youku.com/v_show/id_XNDA5NTQ5MzUyOA==.html?spm=a2h3j.8428770.3416059.1

88.png

时间线

2018年2月26日:向Facebook团队报告

2018年3月1日:确认中

2018年3月9日:修复

2018年3月21日:10000美元奖励

本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://www.vulnano.com/2019/03/facebook-messenger-server-random-memory.html

最新评论

昵称
邮箱
提交评论