Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2026-28609-matroska-pcm-oob — CVE-2026-28609에 대한 개념 증명 및 계측 재현 하네스로, 빅엔디언 PCM 오디오 트랙이 포함된 조작된 WebM 파일을 통해 도달 가능한 Android의 MatroskaExtractor에서 발생하는 범위를 벗어난 쓰기 취약점입니다. | 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

CVE-2026-28609에 대한 개념 증명 및 계측 재현 하네스로, 빅엔디언 PCM 오디오 트랙이 포함된 조작된 WebM 파일을 통해 도달 가능한 Android의 MatroskaExtractor에서 발생하는 범위를 벗어난 쓰기 취약점입니다.

저장소 보기
81881개월 전아직 검토되지 않음

CVE-2026-28609 — Matroska PCM 범위 초과 쓰기

CVE-2026-28609에 대한 개념 증명(Proof-of-concept), 계측된 재현 하네스 및 기술 분석 문서로, 빅엔디언 PCM 오디오 트랙을 포함한 조작된 WebM 파일을 통해 도달 가능한 Android의 MatroskaExtractor에서 발생하는 범위 초과 쓰기입니다.

한눈에 보기

  • 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 이슈: A-485377744
  • 패치: 2026년 9월 Android 보안 업데이트에서 해결됨

1. 요약

Android의 MatroskaExtractor에 있는 MatroskaSource::read()에는 프레임 데이터 포인터를 바이트 오프셋인 frame->range_offset()을 더하기 전에 uint16_t *로 캐스팅하는 PCM 빅엔디언 바이트 스왑 루프가 포함되어 있습니다. uint16_t *에 대한 C 포인터 연산은 오프셋을 sizeof(uint16_t) = 2배로 스케일링하기 때문에, 결과 포인터는 버퍼 시작 지점으로부터 range_offset 바이트가 아니라 2 * range_offset 바이트 뒤를 가리킵니다.

range_offset > 0일 때, 루프는 프레임의 MediaBuffer 끝을 넘어 하나 이상의 바이트를 읽고 씁니다. ASan이 없는 기기에서는 범위 초과 읽기가 조용히 성공하고, 범위 초과 쓰기는 버퍼 바로 다음 바이트를 손상시킵니다.

취약한 줄:

// 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 *로 캐스팅합니다:

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. 추출기를 취약한 분기로 유도하여 0이 아닌 range_offset을 갖게 하는 WebM 파일을 생성하는 Python 생성기.
  2. dlopen을 통해 추출기 플러그인을 로드하고, GETEXTRACTORDEF를 호출하며, 파일에서 프레임을 읽는 C-ABI 하네스.
  3. 취약한 AOSP 추출기의 ASan 계측 사본을 컴파일하고 기기의 미디어 프레임워크 라이브러리에 링크하는 빌드 스크립트 세트.
  4. include 디렉터리를 자동으로 탐색하는 빌드 구성으로, 어떤 AOSP 체크아웃에도 빌드가 적응할 수 있게 합니다.

취약한 기기에서의 결과는 다음과 같습니다:

==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. 트리거 메커니즘

취약한 분기가 실행되려면 다음 조건이 모두 충족되어야 합니다:

조건출처
트랙이 PCM임mType == PCM
빅엔디언AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN == 1
16비트 샘플AMEDIAFORMAT_KEY_BITS_PER_SAMPLE == 16
프레임의 range_offset이 0이 아님set_range(offset, ...)에 의해 설정됨

처음 세 가지는 코덱 ID A_PCM/INT/BIG와 비트 심도 16으로 트랙을 선언하면 충족됩니다. 네 번째가 흥미로운 부분입니다.

range_offset은 readBlock()에서 다음 조건 하에 호출되는 MatroskaSource::setWebmBlockCryptoInfo()에서만 0이 아닌 값으로 설정됩니다:

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바이트를 벗어난 위치입니다.

트리거 프레임의 바이트 레이아웃

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

신호 바이트 0x00은 set_range(1, 64)에 의해 제거되어, 65바이트 할당 내부에 64바이트 프레임이 남습니다. 취약한 포인터 연산은 그런 다음 바이트 오프셋 2부터 65까지에 씁니다.


4. 저장소 구조

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

빌드 전에 사용자가 클론하는 업스트림 종속성:

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 업스트림 종속성 클론

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 기기 라이브러리 가져오기

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 구성

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 빌드 및 실행

./scripts/run.sh

run.sh 스크립트는 다음 네 단계를 순서대로 실행합니다:

  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 — -shared-libsan으로 harness_c_abi를 컴파일합니다.
  4. 플러그인, 하네스, ASan 런타임, poc.mkv를 /data/local/tmp로 푸시하고 하네스를 실행합니다.

빌드 스크립트는 누락된 include 루트를 자동으로 탐색합니다. 컴파일러가 fatal error: 'X' file not found를 보고하면, 스크립트는 의존성 트리를 검색하여 X의 상위 디렉터리를 찾고 이를 include_dirs.conf에 추가합니다. 이것이 첫 빌드 중에 include_dirs.conf가 커지는 이유입니다. 모든 헤더가 발견되면 파일은 안정화되고 이후 빌드는 결정적입니다.


7.크래시

취약한 기기에서 하네스는 다음을 출력합니다:

도구 다운로드