关于 CVE-2026-28618 / StreamBox APV 实验环境的脱敏笔记——通过 FRAME 高度不匹配向会话对象进行堆写入
StreamBox 中的 CVE-2026-28618 —— 与在野利用的 Android APV RCE 属于同一解码器类,被转化为针对会话对象的堆写入。
本仓库是一份公开的、经过脱敏的 writeup:flag、实例令牌和 HMAC 密钥均已省略。APK 和 make_clip.py 属于 Mobile Hacking Lab;此处不提供镜像。

StreamBox 是一个小型 APV 播放器。APV 是 Advanced Professional Video(RFC 9924),三星的免版税编解码器,与 Android 媒体栈中搭载的属于同一家族。实验的设定只有一句话:播放器在收到共享剪辑时即播放。
SEND、VIEW 或 streambox://?url=… 会将文件落到 files/incoming.apv,随后 NativeDec.loadClip() 运行。无需额外点击剪辑。
该漏洞是 CVE-2026-28618:OpenAPV 的 dec_frm_prepare 中的堆缓冲区溢出。与 CVE-2026-0006 属于同一类、同一解码器,后者是今年早些时候在野利用的零点击 APV RCE。
实验将这次写入包装成一个游戏。溢出硬编码的 64×64 Y 平面,破坏相邻的会话对象,将 teardown 重定向到 handlers[2],Worker 就会交回 flag。
工具包是来自实验的两个 zip:
streambox-lab.apk.zip —— 播放器make_clip.py.zip —— 64×64 素材库剪辑是如何构建的,以及你溢出的比特流
PlayerActivity 执行:
NativeDec.setVideoTitle(name);
status = NativeDec.loadClip(path);
// WebView bridge later calls Android.openTier(status)
openTier(1) 是部分命中(会话被触及,令牌不匹配)。openTier(2) 是 win()。PremiumActivity 将原生状态 POST 到实验服务器:
POST /api/unlock
{
"instance_id": <from POST /api/instance>,
"tier": 3,
"session_hex": hex(sessionProof[64]),
"ticket": HMAC-SHA256(ticketKey, instance_id + ":" + session_hex)
}
启动时应用已经执行了 POST /api/instance 和 NativeDec.setPlatinumToken(token)。该令牌正是溢出需要写入会话的内容。

arena = calloc(1, 0x206040);
session = arena + pad + 0x2000;
*(uint64_t *)session = 0x53545245414D424F; /* bytes: "OBMAERTS" */
oapv_imgb_t 被硬编码为 64×64、10 位 YUV。平面 0(Y)从 arena+0 开始。64 × 64 × 2 = 0x2000。当 pad == 0 时,会话就位于 Y 之后的第一个字节处。
oapvd_decode() 按 FRAME PBU 的宽/高写入。高于 64 的 FRAME 会将 10 位样本直接写入 session。
解码后:
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;

实验的生成器绘制 32 帧 64×64 RGB,转换为 yuv422p10le,并调用 OpenAPV 参考编码器:
oapv_app_enc -i anim.yuv -w 64 -h 64 -z 8 --input-csp 2 -d 10 -o out.apv -v 1
每个捆绑的剪辑都是 32 个 FRAME 64×64 的访问单元:
[u32be au_size] ['aPv1' + PBUs] × 32

播放器仍然分配 64×64。将每个 AU 的 frame_height 从 64 修补为 72:
python3 scripts/patch_frame_height.py clip_pulse.apv -o overflow_height72.apv --height 72
分享它(SEND / VIEW / streambox://?url=)。自动播放就是利用。
更干净的溢出方式是将 make_clip.py 中的 H 改为 72 或 128 并重新编码,使额外的 Y 行成为真实的图像数据。64 宽 10 位平面的第 64 行是 128 字节:
OBMAERTS)g_token)2APV 是有损的;通过 oapv_app_enc 获得精确的 10 位值需要 QP 0 / 近无损。
父类漏洞的相关公开 PoC:mobilehackinglab/CVE-2026-0006-openapv-poc。
Python urllib 会得到 Cloudflare 1010。使用移动端 UA 的 curl 可以正常工作。
Worker 会以 no overflow evidence: session magic intact 拒绝原始 magic。ASCII STREAMBO(与 LE uint64 不同的字节)会被视为一次写入。

# fill TICKET_KEY in scripts/unlock.py from NativeDec.ticketKey()
python3 scripts/unlock.py
win() 是当 loadClip 返回 2 时播放器显示的内容:

dec_frm_prepare 中的维度校验Mobile Hacking Lab 的 StreamBox 练习的授权实验笔记。无 APK、无实时令牌、无 flag。不要对任何你不拥有或未获授权测试的目标运行这些原语。