Depthfirst 在 FFmpeg 中中发现 21 个零日漏洞
概述
Depthfirst 使用专门的自主安全智能体发现并在 FFmpeg 中发现了 21 个零日漏洞。这些发现包括 8 个已分配 CVE 的问题和 13 个内部跟踪 ID,涵盖了从堆缓冲区溢出到整数下溢等多种类型。值得注意的是,这项研究表明,AI 驱动的安全智能体能够以比以往的 AI 驱动尝试显著更低的成本,识别出经过加固的、遗留的 C 代码库中的关键缺陷——其中一些缺陷已潜伏了 20 多年。
Depthfirst 安全智能体方法
与专注于功能实现的标准编码智能体不同,depthfirst 的安全智能体是为对抗性分析而设计的。该系统通过对代码库进行威胁建模来识别暴露的解析器和协议处理器,然后将数据流从攻击者控制的输入映射到脆弱的汇聚点(sinks)。
为了最大限度地减少误报,该智能体采用验证循环:它不仅仅是报告理论上的漏洞,而是会自动生成具体的、可重现的漏洞证明(PoC)输入。这一过程通过实际执行来确认缺陷,从而确保每个报告的漏洞都是可达的且具有可操作性的。
漏洞摘要
发现的 21 个漏洞跨越了多个组件,包括 TS demuxer、VP9 decoder 和各种 RTP depacketizers。
已分配 CVE 的漏洞
| CVE | 类型 | 组件 | 描述 |
|---|---|---|---|
| CVE-2026-39210 | 堆缓冲区溢出 | TS demuxer | 在读取两个字节之前缺少长度边界检查(引入于 2010 年)。 |
| CVE-2026-39211 | 整数溢出 | swscale | 尺寸因子公式缺乏上限,允许任意大的缩放(引入于 2010 年)。 |
| CVE-2026-39212 | 栈缓冲区溢出 | ffmpeg_opt.c |
预设文件中的递归选项解析没有深度限制(2025 年 7 月回归问题)。 |
| CVE-2026-39213 | 堆缓冲区溢出 | yuv4mpegenc | 未能根据数据包大小验证维度(引入于 2023 年)。 |
| CVE-2026-39214 | 栈缓冲区溢出 | SDT 实现 | 写入服务条目时未跟踪剩余空间(引入于 2003 年)。 |
| CVE-2026-39215 | 堆缓冲区溢出 | update_mb_info() |
逻辑错误导致允许在分配的缓冲区之外进行 12 字节的写入(引入于 2012 年)。 |
| CVE-2026-39216 | 堆缓冲区溢出 | img2enc.c |
使用无界的维度派生尺寸,而不是安全的色度尺寸(引入于 2012 年)。 |
| CVE-2026-39217 | 堆缓冲区溢出 | VP9 decoder | 重构的尺寸更新函数导致 tile thread 缓冲区错过了重新分配(2025 年 3 月回归问题)。 |
| CVE-2026-39218 | 堆缓冲区溢出 | DASH demuxer | 未能拒绝负的持续时间值,导致负的分片数组索引(引入于 2017 年)。 |
其他已识别的漏洞
由 depthfirst 识别的其他缺陷包括:
DFVULN-127 (堆缓冲区溢出): AV1 RTP depacketizer;发生在跳过 Temporal Delimiter OBUs 时未分配空间。
DFVULN-126 (堆缓冲区溢出): swscale graph code;错误处理交错的 YUV420P→NV12 转换。
DFVULN-125 (栈缓冲区溢出): RTP JPEG depacketizer;无界的
qtable_len允许溢出 1024 字节的栈缓冲区。DFVULN-124 (堆缓冲区溢出): AVIF overlay path;无符号数回绕导致在仅一字节分配的内存上发生越界读取。
DFVULN-123 (Integer Overflow): RTP LATM depacketizer;有符号 32 位加法溢出允许
memcpy读取约 1 GB 超过缓冲区末尾的内容。DFVULN-122 (Heap Buffer Overflow): RTP MPEG-4 depacketizer;接受 AU-headers-length 为 0,导致一字节分配的内存被当作四字节字段读取(引入于 2005 年)。
DFVULN-121 (Heap Buffer Underflow): CAF demuxer;使用
av_index_search_timestamp()的返回值作为数组索引,而未检查 -1。DFVULN-120 (Integer Underflow): AVI demuxer;在未验证
size >= 4的情况下进行size - 4计算,导致约 2 GB 的分配(DoS)。DFVULN-119 (Heap Buffer Overflow): Option parser; stray increment 导致负向映射循环在
AVStream**数组之前进行读取。DFVULN-118 (Heap Buffer Overflow): RTSP server path; 负的
Content-Length被视为有效,导致越界写入。DFVULN-117 (Heap Buffer Overflow): RTMP client;
in_size < 3检查而非< 8允许memcpy读取超出缓冲区。DFVULN-116 (Heap Buffer Overflow): RTSP SDP parsing; 对空字符串使用
strlen会导致size_t回绕至SIZE_MAX。
深度解析:AV1 RTP Depacketizer 中的 RCE (DFVULN-127)
最关键的发现之一是在 libavformat/rtpdec_av1.c 中的堆缓冲区溢出,它可以实现远程代码执行 (RCE)。该漏洞可以通过标准的 RTSP 流 (ffmpeg -i rtsp://attacker/stream) 触发,无需特殊标志。
根本原因
AV1 RTP depacketizer 使用一个游标 pktpos 来跟踪输出数据包中的写入位置。当 depacketizer 遇到 Temporal Delimiter (TD) OBU 时,它被设计为忽略并移除它。然而,代码在调用 av_grow_packet 分配必要内存之前,就根据攻击者控制的 obu_size 推进了 pktpos。
这造成了两个关键失效点:
- 被污染的写入游标:
pktpos被推向了未分配的内存区域。 - 输入指针停滞: 输入指针
buf_ptr没有推进。下一次循环迭代会重新解析 TD 自身的字节作为新的 OBU,允许攻击者控制在被污染的偏移量处写入的数据。
利用路径
通过仔细调整 obu_size 和随后伪造的 OBU,攻击者可以触发一个针对 AVBuffer 管理结构的堆缓冲区溢出。具体来说,该溢出可以覆盖 AVBuffer.free 函数指针,偏移量为 152。
为了触发被劫持的指针,攻击者会嵌入第三个伪造的 OBU,强制 av_buffer_realloc 分配一个新缓冲区并释放旧缓冲区。这会调用被损坏的 free 回调,从而将指令指针的控制权转移给攻击者。
社区洞察与不同观点
行业专家和社区成员针对这些发现提出了以下几个关键结论:
- 沙箱化的必要性: 鉴于 FFmpeg 的内存损坏漏洞历史,共识是处理不受信任的内容时,绝不应在沙箱之外运行 FFmpeg。
Ffmpeg is absolutely not something you should be running outside of a sandbox if you're touching any untrusted or user-supplied content.
RCE 的可行性: 有人指出,虽然该原语(primitive)功能强大,但在现代环境中实现任意 RCE 仍需要绕过 ASLR 并寻找可写/可执行的内存页。
在安全领域的 AI 角色: 虽然发现这些漏洞是 LLM 能力的展示,但也有人认为,行业目前过于关注漏洞报告,而不够关注自动化补丁(PR 生成)环节。
术语语境: 一些批评者认为“零日漏洞”一词使用得过于宽泛,因为这些漏洞是在遗留代码中发现的并已向维护者报告以进行修复,而非在公开披露之前进行攻击。