漏洞学习记录第一天:ffmpeg漏洞理解

来源:互联网 发布:ug编程如何加工t型槽 编辑:程序博客网 时间:2024/04/29 14:31

好,现在进入主题,今天分享的漏洞是ffmpeg产生的漏洞。

首先对ffmpeg做介绍,讲漏洞之前我先介绍一下技术背景,方便大家理解漏洞的原理。什么是FFmpeg呢?FFmpeg是能够将音频和视频转化为流的开源程序。什么是音频视频流呢?我们日常中所看到的视频,音频,封装在一个文件里面,可视化的一个文件,实际上其本质是由数据组成的,就像积木一样,可以垒起来不同的形状,不同的样子,但是实际上就是由同样的东西组成的,我们把这些小的以字符或者说字节为单位的数据的集合称之为数据流,就像塌了的积木,是没有结构的文件。那么FFmpeg又是怎么把有结构的文件转化为无结构的数据流呢?大家可以来看看这个图,由于多媒体文件,其实是包含音频,视频,字幕在整个文件中,是分开压缩的,而且压缩的算法不一样,压缩算法不一样,解码算法也不一样,但在整个多媒体中,是捆绑在一起的,所以ffmpeg就做了这样的工作,把捆绑在一起的音频视频分开,也就是传说中的解复用,然后进行解码,之所以要解码,肯定是因为之前做过编码,之所以做编码,是因为传输过程中,为了减少数据量,是要进行压缩处理的。这样可以给我们网络带宽的一种高效的保护行为。所以实际上ffmpeg就做了这样一件事情。

现在我们已经有了流文件了,那么怎么样传输这个流文件能够高效,快速呢?实际上传输流文件的时候会基于一种流媒体通信协议,HLSHTTP LIVE STREAMING,这个基本原理就是把流文件分割成很多很小很小很小的ts流文件,然后通过http下载,每次下载一点点,这个一点点呢就是ts流文件。每次传输一个视频之前,客户端都会先下载一个m3u8文件,这个m3u8文件相当于一个列表,可以理解为一个菜单。我们来看看这个图,最大的相当于一个主菜单,这个主菜单里面有三个小的菜单,相当于肉菜素菜甜点,然后每一个菜单下面都有对应的菜品,也就是我们前面提到的每次http请求下载的小的流文件的请求信息,包括地址啊时间啊。根据解析出来的最后一层的这个信息,就可以发送请求,去资源处获取资源了。这个图就是最后一层的m3u8文件的内容,可以看得到里面有一些标签,文件头,媒体长度6秒,版本,流文件长度6http请求然后最后文件结束。这是m3u8的最基本的标签,但是这里存在一个问题,FFmpeg去根据请求ts流文件的时候,不会判断里面的流地址是否合法或者说是否正确,而是直接请求,所以我们可以伪造一个m3u8文件,里面放着我们想要的东西的地址。简单的来说就是,我给你一个菜单,你照着菜单去拿菜,你也不知道厨房在哪,所以你只会照着我给你的地址去拿相应的东西。这里就已经能够造成ssrf漏洞了。还有就是FFmpeg支持很多的扩展协议,在2.8.5版本之前,其中一个最重要的就是concat协议,这个协议可以合并多个URL并访问资源。我们可以来看看这个图,标红框的地方就是一个m3u8文件,我们可以看到这个concat字段,这一句的意思是向这个地址解析,这个地址也是一个m3u8文件,也就是最底层的含有ts流文件的地址信息的m3u8,也就是解析到这一句,就获取了url地址,而后面跟着的东西,ffmpeg就会去读取这个地址的文件的第一行拼接到刚刚前面得到的url后面,比如这个地址的文件第一行的东西是abc,那就会在刚刚得到的url后面加上url,再加上FFmpeg支持多种协议的输入流,也就是支持httpfilesmb等等,就是如果把http协议换成ftp协议就可以读取本地文件了。也就是说我们可以读取内网任意文件的内容拼接到url后面。再加上ffmpeg支持数据偏移截取,也就是start what what end what what 就是从第一个字节到第几个字节截取,我们现在只要这样构造,伪造的m3u8文件解析的最后一层是一个我的网站,后面拼接上我想要的资源,ffmpeg解析完就会向拼接完了的地址发送请求,也就是向我的网站发送请求,当然我肯定没有这样的目录给它访问,但是我的日志就能记录下这样的访问请求,而请求中就会带着我想要的信息。所以说根据这个问题,就能够造成任意文件读取了。这个问题在ffmpeg2.8.5以后被修复了,也就是在ffmeg2.8.5之前的库都存在这个问题。官方呢对这个漏洞的修做了两项工作,其一就是把我们刚刚提到的concat协议,合并url协议给删除了给去掉了,也就是不能再拼接url。其二就是在结构体中加入了黑名单和白名单的域,也就是说程序员可以设定指定的域才能够被合法访问。

然而聪明的地球人又想出了什么办法呢,176月又同样是对ffmpeg的漏洞被发现了,这个漏洞呢是指在avi视频中,有一个数据块是可以定义字幕的,叫做GAB2,有趣的是,将m3u8插入到这中间,ffmpeg依旧会对这个做hls处理。然而没有了concat又怎么去读取任意文件呢,有一种有趣的思路就是通过xbin的方式,之前说过m3u8实际上不是真正的视频资源,真正的视频资源是ts流文件,如果要播放的话,必须在m3u8中嵌入一个可播放的视频资源,而xbin呢就是一种古老的媒体格式,它具备显示图片文本的功能,如果用xbin绘制成字符,是可以作为合法的可播放的视频文件进行观看的。嵌套之后大概是如下图这样的方式这个样子的形式。但是由于ffmpeg会对非法字符串进行检查,而申明xbin格式的前缀是data:会被过滤。所以不能直接的对xbin格式进行申明,但是m3u8支持AES加密,所以最后得到的文件应该是这样子的。关于这个漏洞的补丁呢,限制了允许的拓展名,也就是不允许xbin等古老的媒体格式的存在。Ffmpeg作为目前最广泛的多媒体框架,适配了尽可能多的媒体格式,所以关于ffmpeg会带来很多不一样的可能性,关于媒体处理的组件或者软件应该还会暴露出更多的问题。