- 网络安全
- 渗透测试
- 示例工程
【免费下载链接】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.
本篇技术指南围绕仓库内 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 声明一致 |
| 文件魔数 | DKIF | IVF 容器标识 |
| 版本 / 头长 | 0 / 32 字节 | 标准 IVF 头 |
| FourCC | VP90 | VP9 编码 |
| 容器宽 / 高 | 64 / 64 | IVF 头保留首帧尺寸 |
| 帧率 | rate=1, scale=1 | 时间戳单位为 1s |
| 帧数 | 2 | 第 0、1 帧 |
两帧在文件中的布局(偏移从 IVF 头 32 字节后开始):
| 帧 | 帧载荷大小 | 时间戳 | 数据偏移 |
|---|---|---|---|
| 第 0 帧(64x64) | 94 字节 | 0 | 32 |
| 第 1 帧(64x8192) | 255 字节 | 1 | 138 |
一个值得注意的细节: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, --output | vp9_reschange_64x64_to_64x8192_tc0.ivf | 样本输出路径 |
--vlc | 无 | 可选,vlc.exe绝对路径,用于本地重放 |
--timeout | 8(秒) | 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.
相关推荐
Exploitarium 深度解析:Pillow 12.3.0 ImageCms 可变 `output_mode` 绕过导致的堆越界写入 PoC
Exploitarium 深度解析:Pillow 12.3.0 ImageCms 可变 output_mode 绕过导致的堆越界写入 PoC 本篇技术指南围绕
网络安全渗透测试示例工程创维E900V21E 刷 Armbian 后有线网卡连不上?3 步底包修复指南
创维E900V21E 刷 Armbian 后有线网卡连不上?3 步底包修复指南 创维 E900V21E(Amlogic S905L2 芯片)装了 Armbian
嵌入式开发工具构建工具操作系统objdump DLX ELF 后端越界写漏洞 PoC 深度解析:从 `objdump -g` 崩溃到计算器执行的完整复现指南
objdump DLX ELF 后端越界写漏洞 PoC 深度解析:从 objdump g 崩溃到计算器执行的完整复现指南 本文以开源仓库 objdump dlx
网络安全渗透测试示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考