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.

عرض المستودع
6158منذ 19 أياملم تتم المراجعة بعد
المحتوى غير متوفر باللغة المطلوبة. عرض النسخة الإنجليزية.

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

تنزيل الأداة