FFmpeg文件读取漏洞

CVE-2017-9993

Posted by songjiu on March 16, 2019

介绍

来自i春秋 网址:https://www.ichunqiu.com/course/59111?f=1

FFmpeg是一个完整的跨平台解决方案,用于记录、转换流式传输音频和视频,可用于预览生成和视频转换的视频编码软件。目前有非常多的视音频软件或是视频网站、手机APP都采用了这个库,但是这个库历史上曝出的漏洞也非常之多。 此次漏洞利用了FFmpeg可以处理HLS播放列表的特性,而播放列表可以引用外部文件。通过在AVI文件中添加自定义的包含本地文件引用的HLS播放列表,可以触发该漏洞并在该文件播放过程中显示本地文件的内容。经验证该漏洞可导致读取本地任意文件,危害较大.经研究人员验证,Google,Yahoo,Youtube等门户、视听网站以及支持流转码服务的业务已被爆出存在该漏洞。

简单地说,类似一个ssrf漏洞,通过播放视频的方式可以访问内网服务器当中的敏感文件如passwd等。

流程

来自freebuf 网址:https://www.freebuf.com/column/142775.html 这个漏洞实际上也是利用了ffmpeg在处理 HLS 播放列表文件的过程中,由于支持非常多的协议,如http、file、concat等等,导致可以构造恶意的url造成 SSRF 攻击和本地文件泄露。 HLS(HTTP Live Streaming)是苹果公司针对iPhone、iPod、iTouch和iPad等移动设备而开发的基于HTTP协议的流媒体解决方案。HLS需要索引文件m3u8,根据这个m3u8索引文件去寻找真正的视频文件,这里的资源是一个URI,但是没有验证。也就是这里会出现一个SSRF问题。 生成payload后打开如下所示(payload由下文python脚本生成) 其中的GAB2为嵌入字幕的开始位,而EXTM3U则为m3u8的开始。

上文出现的标签含义

(来自freebuf)

#EXT-X-MEDIA-SEQUENCE:每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号+1, 一个media URI并不是必须要包含的,如果没有,默认为0。 #EXTINF: duration 指定每个媒体段(ts)的持续时间(秒),仅对其后面的URI有效。 #EXT-X-KEY表示怎么对mediasegments进行解码。其作用范围是下次该tag出现前的所有mediaURI,属性为NONE或者 AES-128。对于AES-128的情况,URI属性表示一个key文件,通过URI可以获得这个key,如果没有IV(Initialization Vector),则使用序列号作为IV进行编解码;如果有IV,则将改值当成16个字节的16进制数。 那么上面几行代码包括了两个segment,每一个 segment 都需要使用 AES-128进行解密,密文是从/dev/zero这个 url获取的16个字节,其实就是16个’\0′, key 也是从/dev/zero这个url获取的16个字节,16个’\0′,IV是自己指定的一串十六进制数。ffmpeg对第一个 segment 进行解密后的结果是b’XBIN\x1a \x00\x0f\x00\x10\x04\x01\x00\x00\x00\x00′, 和漏洞作者在注释中给出的一样。前四个字节 XBIN 就是 XBIN 的文件头。从而使得ffmpeg判定这个播放列表的格式是 XBIN。

也就是说这个头部利用一个巧妙的AES加密的方式生成了特定的字符XBIN(这是一种很老的视频格式,因为单纯的m3u8仅仅是一个索引,必须要存在一个视频文件。),由于这是第一个segment,判定的列表播放格式就为XBIN格式。最后,fmpeg把 playlist 的所有 segment 的内容连接在一起,因为只有/etc/passwd这个文件是实际存在的,所以最后的内容就是/etc/passwd文件的内容。

payload生成

来自GitHub
gen_xbin_avi.py