Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-28609-matroska-pcm-oob — Proof-of-concept and instrumented reproduction harness for CVE-2026-28609, an out-of-bounds write in Android's MatroskaExtractor reachable via a crafted WebM file with a big-endian PCM audio track. | Kitploit
ツール/GitHubGitHub/devrodt2/cve-2026-28609-matroska-pcm-oob
Android SecurityMemory ForensicsVulnerability AnalysisExploitationReverse EngineeringFuzzingMobile SecurityBinary Exploitation

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
GitHub
devrodt2/cve-2026-28609-matroska-pcm-oob

CVE-2026-28609-matroska-pcm-oob

Proof-of-concept and instrumented reproduction harness for CVE-2026-28609, an out-of-bounds write in Android's MatroskaExtractor reachable via a crafted WebM file with a big-endian PCM audio track.

リポジトリを見る
615819日前未レビュー
要求された言語のコンテンツは利用できません。英語版を表示しています。

CVE-2026-28609 — Matroska PCM Out-of-Bounds Write

Proof-of-concept, instrumented reproduction harness, and technical write-up for CVE-2026-28609, an out-of-bounds write in Android's MatroskaExtractor reachable via a crafted WebM file with a big-endian PCM audio track.

At a glance

  • CVE ID: CVE-2026-28609
  • Vendor: Google / Android
  • Component: frameworks/av/media/module/extractors/mkv/MatroskaExtractor.cpp
  • Issue: Out-of-bounds write caused by improper casting
  • CWE: CWE-787 / CWE-704
  • Affected: Android 14, 15, 16, 16 QPR2
  • Severity: High
  • Impact: Potential remote code execution
  • AOSP issue: A-485377744
  • Patch: Addressed in the September 2026 Android security update

1. Summary

MatroskaSource::read() in Android's MatroskaExtractor contains a PCM big-endian byte-swap loop that casts a frame data pointer to uint16_t * before adding frame->range_offset(), a byte offset. Because C pointer arithmetic on a uint16_t * scales the offset by sizeof(uint16_t) = 2, the resulting pointer is 2 * range_offset bytes past the start of the buffer, not range_offset bytes.

When range_offset > 0, the loop reads and writes one or more bytes past the end of the frame's MediaBuffer. On a device without ASan the over-read succeeds silently and the over-write corrupts the byte immediately following the buffer.

The vulnerable line:

// 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]);
}

The upstream fix casts the pointer to uint8_t * before applying the offset:

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. What this repository demonstrates

A working, reproducible trigger for CVE-2026-28609, verified under AddressSanitizer on a real Android 14 device. The repository includes:

  1. A Python generator that produces a WebM file that drives the extractor into the vulnerable branch with a non-zero range_offset.
  2. A C-ABI harness that loads the extractor plugin via dlopen, invokes GETEXTRACTORDEF, and reads frames from the file.
  3. A set of build scripts that compile an ASan-instrumented copy of the vulnerable AOSP extractor and link it against the device's media framework libraries.
  4. A build configuration with auto-discovery of include directories, so the build adapts to any AOSP checkout.

The result, on a vulnerable device:

==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. Trigger mechanics

The vulnerable branch requires all of the following to be true:

ConditionSource
Track is PCMmType == PCM
Big-endianAMEDIAFORMAT_KEY_PCM_BIG_ENDIAN == 1
16-bit samplesAMEDIAFORMAT_KEY_BITS_PER_SAMPLE == 16
Frame has non-zero range_offsetSet by set_range(offset, ...)

The first three are satisfied by declaring the track with codec ID A_PCM/INT/BIG and bit depth 16. The fourth is the interesting one.

range_offset is set to a non-zero value only in MatroskaSource::setWebmBlockCryptoInfo(), which is called from readBlock() under the condition:

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

Therefore the trigger file must satisfy:

  • mIsWebm — the EBML DocType element must be "webm", not "matroska".
  • mEncrypted — the track must declare ContentEncodings with ContentEncodingType = 1 (Encryption) and a ContentEncKeyID.
  • Non-encrypted frames — each frame's first byte must be a signal byte whose low bit (0x1) is 0, indicating that the frame is unencrypted but content-encoded. This takes the else branch in setWebmBlockCryptoInfo, which calls set_range(1, len - 1).

After the strip, range_offset = 1 for every frame. The vulnerable branch then computes (uint16_t *)data + 1, which advances 2 bytes, and the loop reads/writes bytes [2, 2 + range_length) — one byte past the end of the 65-byte allocation (64-byte frame + 1-byte signal).

Byte layout of a triggering frame

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

The signal byte 0x00 is stripped by set_range(1, 64), leaving a 64-byte frame inside a 65-byte allocation. The vulnerable pointer arithmetic then writes at byte offset 2 through 65.


4. Repository layout

.
├── 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

Upstream dependencies, cloned by the user before building:

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. Prerequisites

  • Host: Linux or WSL2 with bash, python3, make
  • NDK: Android NDK r27+, set via $ANDROID_NDK_HOME
  • Device: Android 14, 15, 16, or 16-QPR2 with a security patch level before September 2026
  • ADB: adb on PATH (Linux, or adb.exe from WSL)
  • Disk: ~1.5 GB for the AOSP clones

6. Build

6.1 Clone upstream dependencies

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 ../..

If your AOSP tree uses the modular extractor layout (av/media/module/extractors/mkv/), no further adjustment is needed. If it uses the older layout (av/media/libstagefright/matroska/), see the build scripts for the MKV variable.

6.2 Pull device libraries

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 Configure

ツールをダウンロード