news 2026/10/3 1:55:38

VLC 3.0.23 VP9 分辨率切换越界写崩溃 PoC 深度解析:64x64 → 64x8192 帧高突变触发陈旧 slice-thread entries 分配

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VLC 3.0.23 VP9 分辨率切换越界写崩溃 PoC 深度解析:64x64 → 64x8192 帧高突变触发陈旧 slice-thread entries 分配
  • 网络安全
  • 渗透测试
  • 示例工程

【免费下载链接】exploitarium

A single archive of public exploit PoCs and vulnerability research writeups. At the time I post these, none have been reported. Feel free to report them yourself and take credit for the CVE if handed out lulz. Please do not abuse these. I do this so to allure people into the field, and I've always found this is the most efficient way.

项目地址:https://gitcode.com/GitHub_Trending/ex/exploitarium
点击查看免费下载

本篇技术指南围绕仓库内 vlc-vp9-reschange-crash-poc 这一紧凑型崩溃复现器展开:它用纯标准库 Python 生成一个仅 405 字节的 VP9 IVF 媒体样本,在 VLC 3.0.23(Windows x64)内置的 FFmpeg VP9 解码器中稳定触发 slice-thread 进度数组的越界零写。读完本文,你将掌握该崩溃条件的完整成因链条(sb_rows计算、陈旧分配与重置循环)、样本的二进制结构与校验方式,以及如何在本地用 VLC 二进制安全重放并解读崩溃码。

概述:一个 405 字节的崩溃复现器

该 PoC 的核心是一份嵌入 Python 脚本中的 VP9 IVF 样本,包含两帧关键数据:

  • 第 1 帧:64x64
  • 第 2 帧:64x8192

两帧保持相同的 VP9 tile-column 布局(样本文件名中的tc0即 tile columns = 0),但第二帧的帧高从 64 突变到 8192。正是"帧高变化而 tile-column 数量不变"这一组合,使 VLC 3.0.23 附带的 FFmpeg VP9 解码器在解码第二帧时命中了陈旧(stale)的 slice-thread 进度分配。

复现器本身极小:poc.py依赖 Python 标准库(argparse、base64、hashlib、json、subprocess、pathlib),无需任何第三方包,生成样本后以 JSON 输出路径、SHA256 哈希与大小,并可选地拉起本地 VLC 进程进行重放。需要强调的是,README 明确标注其研究状态为"不完整、持续进行中"(Research status: incomplete and continuing),它定位为崩溃复现器而非完整利用链。

漏洞机理:slice-thread 进度数组的陈旧分配

entries 数组按当前帧的超级块行数分配

VP9 解码器以切片(slice)并行方式解码,需要一个逐行记录各切片解码进度的数组,README 中称为entries。关键点在于:该数组的分配大小由当前帧的超级块(superblock)行数决定,而超级块是固定64x64像素的块。

对于64x64的首帧:

sb_rows = (64 + 63) >> 6 = 1 entries allocation = 1 * sizeof(atomic_int) = 4 bytes

即首帧只需要 1 个atomic_int(4 字节)的进度槽。对于后续的64x8192帧:

sb_rows = (8192 + 63) >> 6 = 128

新帧需要 128 个进度槽。

分辨率改变为何不触发重新分配

正常情况下,分辨率变化会触发解码器内部状态的重置与重新分配;但该路径的特殊之处在于:当 tile-column 数量不发生变化时,entries数组不会被重新分配,仍然保留首帧按 1 行分配的 4 字节大小,形成陈旧分配。这解释了"必须同时满足帧高变化 + tile-column 稳定"才能复现的条件——若 tile-column 数量变化,分配路径会被刷新,越界条件也就不存在。

重置循环:对陈旧分配的固定模式零写

解码新帧时,VP9 的 slice-thread 重置循环按新帧的sb_rows逐行清零:

for (i = 0; i < s->sb_rows; i++) atomic_store(&s->entries[i], 0);

新帧sb_rows = 128,而entries仍是首帧的 4 字节分配,于是第二帧的解码过程变成一串 4 字节零写,持续越过原本的 4 字节分配边界。在 Windows 上的 VLC 3.0.23 进程中,具体结果取决于堆布局与运行时状态,观测到的表现包括:堆损坏终止(0xC0000374)与访问违规(0xC0000005)。

从样本到崩溃:IVF 容器与 VP9 帧结构

生成后的样本可在本地直接按 IVF 容器格式解析验证(解析逻辑与 poc.py 中内嵌样本的字节布局一致):

字段值说明
文件总大小405 字节与 README 声明一致
文件魔数DKIFIVF 容器标识
版本 / 头长0 / 32 字节标准 IVF 头
FourCCVP90VP9 编码
容器宽 / 高64 / 64IVF 头保留首帧尺寸
帧率rate=1, scale=1时间戳单位为 1s
帧数2第 0、1 帧

两帧在文件中的布局(偏移从 IVF 头 32 字节后开始):

帧帧载荷大小时间戳数据偏移
第 0 帧(64x64)94 字节032
第 1 帧(64x8192)255 字节1138

一个值得注意的细节:IVF 容器头部仍记录64x64(容器头不随帧更新),真正的分辨率变化是编码在 VP9 帧的比特流内部的——两帧的未压缩头前缀(0x82 0x49 0x83 0x42 ...)一致,差异体现在后续的帧尺寸与压缩头区域,这与 README"第二帧改变帧高、保持 tile-column 布局稳定"的描述吻合。

使用方式:生成与校验样本

生成默认的 IVF 样本(输出vp9_reschange_64x64_to_64x8192_tc0.ivf):

python poc.py

生成到自定义路径:

python poc.py -o sample.ivf

可选地拉起本地 VLC 重放:

python poc.py --vlc "C:\Path\To\VLC\vlc.exe"

脚本在写出样本前会先做内嵌数据的完整性校验:对 base64 解码后的字节计算 SHA256,若与EXPECTED_SHA256不符则直接抛出RuntimeError("embedded sample hash mismatch"),防止样本被篡改。预期哈希为:

F26BDEFBDFD0B44359E314E0BFDE7AEA979D29F80F598749DCCA68AB34F54649

脚本输出结构化的 JSON:

{ "sample": "/abs/path/vp9_reschange_64x64_to_64x8192_tc0.ivf", "sha256": "F26BDEFBDFD0B44359E314E0BFDE7AEA979D29F80F598749DCCA68AB34F54649", "size": 405, "vlc": { "...": "仅指定 --vlc 时出现" } }

CLI 参数一览(见 poc.py 的argparse定义):

参数默认值说明
-o, --outputvp9_reschange_64x64_to_64x8192_tc0.ivf样本输出路径
--vlc无可选,vlc.exe绝对路径,用于本地重放
--timeout8(秒)VLC 子进程超时,超时判定为timeout

VLC 重放:命令行参数逐一解析

当传入--vlc时,poc.py 的run_vlc()会构造一套适合无人值守重放的参数集,并在 VLC 所在目录(cwd=str(vlc.parent))启动子进程:

vlc.exe -I dummy --dummy-quiet --ignore-config --no-media-library --play-and-exit --run-time 2 --no-one-instance --no-qt-privacy-ask --no-qt-error-dialogs --no-crashdump --no-audio --vout dummy sample.ivf vlc://quit

各参数作用:

参数用途
-I dummy使用无界面 dummy 交互模块,便于自动化
--dummy-quiet抑制 dummy 模块输出
--ignore-config忽略用户配置,保证复现环境一致
--no-media-library禁用媒体库,避免干扰
--play-and-exit --run-time 2播放后退出,最多运行 2 秒
--no-one-instance允许多实例,不与既有 VLC 冲突
--no-qt-privacy-ask/--no-qt-error-dialogs关闭隐私询问与错误弹窗,防止进程挂起等待交互
--no-crashdump关闭崩溃转储弹窗
--no-audio/--vout dummy禁用音频、使用 dummy 视频输出,聚焦解码路径
vlc://quit播放结束后主动退出

子进程结束后,结果中会包含status(clean/crash:<类型>/nonzero/timeout)、returncode与十六进制形式returncode_hex、elapsed耗时,以及stdout_tail/stderr_tail(各取末尾 2000 字符)。

崩溃观测与分类

poc.py 内置了一张 Windows 崩溃码表,用于把子进程返回码映射为可读类型:

十六进制返回码含义分类结果
0xC0000005访问违规(access violation)crash:access_violation
0xC0000374堆损坏(heap corruption)crash:heap_corruption
0xC0000409栈缓冲区溢出(stack buffer overrun)crash:stack_buffer_overrun

返回码通过code32()做 32 位掩码归一化后参与分类;返回码为0判定clean,超时判定timeout,其余返回码归为nonzero。

README 还记录了本地插桩观测到的具体证据:在plugins/codec/libavcodec_plugin.dll中,陈旧重置循环位于 RVA0x698a5c,以固定零写模式对陈旧entries分配执行写入。针对64x64 -> 64x8192样本的直接存储追踪显示:

  • 共129次entries存储;
  • 其中127次越过请求的 4 字节分配;
  • 其中114次越过分配器原始可用块(raw usable block)。

可见越界写入规模远超分配本身,且已穿透到堆块的可用区域之外。README 同时提醒:在 Windows VLC 3.0.23 上,进程的具体表现(堆损坏终止或访问违规)取决于堆布局与运行时状态,并非每次重放都呈现同一崩溃码。

测试目标、适用前提与研究边界

README 声明该复现器针对以下环境验证:

  • VLC media player 3.0.23 for Windows x64
  • 解码模块:plugins/codec/libavcodec_plugin.dll
  • VP9 解码器源码谱系:FFmpeg 4.4.x 的 VP9 解码器

关键解码器行为是"分辨率变化但不改变 tile-column 数量时entries分配保持陈旧"。因此复现的有效性前提是:目标 VLC 附带的 libavcodec 模块保持上述分配/重置逻辑,且运行在 Windows 平台(堆损坏/访问违规的观测结果依赖平台堆行为)。

仓库同时明确界定:这是一个紧凑的崩溃复现器,关于该原语(primitive)完整可利用性的研究尚不完整、仍在继续。请在自有的本地测试环境中运行——生成媒体文件的唯一用途是复现并研究解码器故障路径,不应在生产环境或他人设备上使用。

延伸阅读

  • 复现器本体:poc.py
  • 原始研究说明:vlc-vp9-reschange-crash-poc/README.md
  • 网络安全
  • 渗透测试
  • 示例工程

【免费下载链接】exploitarium

A single archive of public exploit PoCs and vulnerability research writeups. At the time I post these, none have been reported. Feel free to report them yourself and take credit for the CVE if handed out lulz. Please do not abuse these. I do this so to allure people into the field, and I've always found this is the most efficient way.

项目地址:https://gitcode.com/GitHub_Trending/ex/exploitarium
点击查看免费下载

相关推荐

上一篇:终极测评:ast-grep多语言解析引擎如何实现极速代码搜索与重构
下一篇:Paper2GUI 代码覆盖率:提高代码质量的测试策略

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 1:55:27

IM未读数与红点方案选型:从服务端一致性到状态机设计

IM会话未读数和红点方案选型&#xff0c;这个话题我琢磨了挺久。凡是做过即时通讯&#xff08;IM&#xff09;客户端或服务端的同学&#xff0c;基本都绕不过这一关。未读数看起来是个简单的东西——无非就是数字加减、红点显隐&#xff0c;但真正落地的时候&#xff0c;你会发…

作者头像 李华
网站建设 2026/10/3 1:55:13

光伏制造企业SAP与金蝶云星空ERP集成方案与接口实现详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 1:51:42

知识表示与专家系统:用符号 AI 教计算机“理解“世界

教程人工智能机器学习深度学习 【免费下载链接】AI-For-Beginners 12 Weeks, 24 Lessons, AI for All! 项目地址&#xff1a; https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners 点击查看 免费下载 本文以 AI-For-Beginners 课程第 2 课&#xff08;lessons/2-Symboli…

作者头像 李华