猿人学 App 第二十一题「二十四桥明月夜」离机复现:答案藏在视频第一个 ts 里
本文最后更新于:2026年9月2日 下午
[猿人学 App 逆向系列]第二十一题「二十四桥明月夜【m3u8】」。这题不翻页取数,而是”看视频交答案”型:ExoPlayer 播放一段 HLS 视频,你把答案填进输入框,提交到
app_check校验。
有意思的是——视频画面里根本没有答案。本文记录怎么排除画面/音频/元数据,最终定位到”答案 = 视频第一个 ts 分片的 MD5”。⚠️ 猿人学闯关 App 是面向逆向练习的 CTF 式靶场;本文仅用于授权范围内的学习研究,请遵守相关服务条款与法律。
本文目录
- 请求模型:一个视频 + 一个校验接口
- 拿到视频:AES-128 加密的 HLS
- 排除法:画面、音频、元数据里都没有答案
- 答案 = 第一个 ts 的 MD5
一、请求模型:一个视频 + 一个校验接口
ChallengeTwentyOneFragment 里没有翻页逻辑,只有:
1 | |
OooOo0(id, anw, token) 对应 challenge/api/app_check——就是通关答案提交接口,id=48 是本题。所以第二十一题没有数据 API,核心是”搞到那个要填进输入框的答案”。
混淆字符串用 JVM 预言机解一下(把 dex2jar 出的 app.jar 挂上,直接调解密函数):
1 | |
二、拿到视频:AES-128 加密的 HLS
stream.m3u8 是个加密的点播流:
1 | |
ffmpeg 能自己去拉 key、解密、拼接:
1 | |
拿到一段约 23 秒的视频。
三、排除法:画面、音频、元数据里都没有答案
按”看视频取答案”的惯性,先去画面里找数字:
- 逐帧扫描 + 拼接图:整段就是一段黑白海面空镜,没有任何数字/文字叠加。
- 场景切换检测(
select='gt(scene,0.15)'):0 个切换帧——没有一闪而过的叠加。 - 多帧平均(
tmix,静止的水印会保留、流动的水面会糊掉):平均出来还是海面,没有隐藏水印。 - 音频:
astats显示Max level: 0.0——音轨全静音,不可能是播报/DTMF/摩尔斯。 - TS 元数据 / ID3:解密后的 ts 里只有 H264 + AAC,没有可读的答案串。
画面、音频、元数据全排除。视频本身(“二十四桥明月夜”的空镜)只是主题装饰,答案不在它”演的内容”里,而在它”作为文件”的属性上。
四、答案 = 第一个 ts 的 MD5
这类题的答案落点,常是”对某个资源做个哈希”。这题的答案就是——视频第一个分片 segment-0.ts 原始字节(下载来的加密 ts,不用解密)的 MD5:
1 | |
把这个 MD5 填进输入框提交,即通关。
小结
第二十一题的坑在于惯性:一看到”播放视频”,就下意识去画面里找答案,结果逐帧、平均、音频、元数据一通折腾全是空。当所有”内容通道”都排除时,就该换个角度——答案往往不在视频演了什么,而在这个文件本身(整段 md5、首个分片 md5、文件大小、时长等)。这里正是”第一个 ts 的 MD5”。
离机复现只要:读 m3u8 → 取第一个分片 → 算 MD5。连解密都不用。