盗版世界杯直播流到底是怎么运作的

我想搞清楚那个明摆在眼前的小把戏到底是怎么运作的。盗版流媒体网站一直都存在,但在世界杯期间,你打开任何一个体育论坛,总能看到有人甩出一条直播比赛的链接——全高清、不卡顿、不用登录。我一直以为底层有什么玄妙的东西。一个朋友在英格兰对克罗地亚那场比赛前给我发了一条链接。“看这个,“他说。于是我打开了 DevTools。

我本以为会看到一个抓取来的 HLS 播放列表,或者一个转推的信号流。结果我看到的却是一个 <video> 标签、一个指向合法 Akamai CDN 的 Shaka Player 实例,以及一个 <script> 块里那两串十六进制字符串——所有的活儿都是它们干的。那两串十六进制字符串就是 DRM 解密密钥。就在页面源码里。没有藏在 API 后面。没有加密。只是裹在一层看起来吓人、实际上什么都不干的 JavaScript 里。

后来有人给我看了一个安卓应用,它对每一场世界杯比赛都做着同样的事情——但是"很正规地"做的,有加密的配置、Firebase Remote Config、一个授权服务器,应有尽有。一个专门的"MUNDIAL FIFA 2026"板块,每场比赛有 28 个频道,包括多机位、球员视角和教练视角。我花了大约一个小时才意识到,这就是同一个漏洞穿上了一身更体面的西装。

最初只是三十分钟的好奇,结果变成了一整个周末。到最后,我从网页这边绘制出了横跨 33 个国家、169 个 CDN 的 670 路直播流,又从单单一个安卓应用里整理出了另外 525 个频道——全都由一种被 W3C 自己称为"测试"工具的 DRM 方案保护着。而这正发生在一届世界杯期间——英格兰正把四个球灌进克罗地亚的球门,而每一个进球都同时出现在数百路未经授权的直播流上。

免责声明
**这是一篇漏洞分析。**文中不发布任何真实密钥、直播流 URL 或可用工具。应用名称和域名均已隐去。目的是记录各平台部署 DRM 时存在的系统性弱点——而非助长盗版。

每一个播放加密视频的浏览器都会用到 W3C 的 Encrypted Media Extensions(EME)。EME 支持四种密钥系统。其中三种——Widevine、FairPlay、PlayReady——使用授权服务器、加密的密钥交换以及由硬件支撑的解密。第四种是 ClearKey。

ClearKey 以明文形式把解密密钥发给浏览器。

就这么简单。和 Widevine 一样的 AES-128 加密。一样的 MPEG-DASH 分发。但 Widevine 是通过安全通道协商密钥,并在浏览器无法窥探的硬件沙箱里解密视频,而 ClearKey 则是把原始密钥直接交给 JavaScript,说一句"给你”。

text

    WIDEVINE L1                          CLEARKEY
    ───────────────────────              ───────────────────────
    License server (HTTPS)               No license server
    Encrypted key exchange               Key in plaintext JS
    Hardware TEE decryption              Software decryption
    Key never in JS memory               Key IS the JS
    Per-device, per-session policy       No policy at all

DASH Industry Forum 表示 ClearKey “仅建议用于测试目的”。但有些平台还是决定在生产环境里使用它。我分析的那些网站和那个应用,都依赖于这个决定。

我检视了数十个盗版流媒体网站。它们全都遵循同一种套路。

text

    ┌──────────────────────────────────────────────────────────────┐
                        HOW IT ACTUALLY WORKS                     
    └──────────────────────────────────────────────────────────────┘

    STEP 1                    STEP 2                    STEP 3
    User visits               Clicks a channel          Page loads an <iframe>
    pirate-site.co            (e.g. "Sky Sports")       from a different domain

    ┌──────────────┐          ┌──────────────┐          ┌──────────────────┐
                              ┌────┐┌────┐│            player-host.co  
      Channel       click     ESPN││DAZN││  iframe                    
      Grid Page    ───────>   ├────┤├────┤│ ───────>   Shaka Player    
                              Sky ││beIN││            + DRM keys      
      (static                 └────┘└────┘│            + manifest URL  
       HTML)                └──────────────┘          └────────┬─────────┘
    └──────────────┘                                             
                                                                  fetches
                                                                 
                                                    ┌──────────────────────┐
                                                      LEGITIMATE CDN      
                                                      (akamaized.net,     
                                                       skycdp.com,        
                                                       indazn.com)        
                                                                          
                                                      Encrypted DASH      
                                                      segments            
                                                    └──────────────────────┘

    The pirate site serves ZERO video.
    The CDN bill belongs to the legitimate provider.
    The pirate site hosts ~50KB of HTML.

盗版网站不过是一个知道那两串十六进制字符串的中间人。它把观众的浏览器指向一个真实的 CDN,把解密密钥递过去,剩下的事浏览器自己做。CDN 从头到尾都不知道这个观众并不是付费订阅用户。

播放器宿主页面包含一个带有密钥的 <script> 块,外面裹着一层混淆,而一个 30 行的 Node 脚本不到一秒就能把它解开:

javascript

// Before: 40 lines of _0x4a2f, IIFEs, string-array lookups
// After: this is what it actually does

var drmKeyId = 'a1b2c3d4e5f6a7b80000000000000000';
var drmKey   = '0123456789abcdef0123456789abcdef';

player.configure({
    drm: { clearKeys: { [drmKeyId]: drmKey } }
});
player.load('https://cdn.legitimate-provider.com/manifest.mpd');

两个变量。两串十六进制字符串。这就是全部的"DRM 保护”。那层混淆——变量重命名、字符串数组、控制流扁平化——会被 eval() 还原,因为浏览器本身也得运行它。只要浏览器能执行,脚本就能执行。

一旦被提取出来,密钥就会通过 GitHub 和 Telegram 上的 M3U 播放列表扩散开去。我找到过一个 M3U 文件,里面有横跨 92 个 CDN 的 545 条 ClearKey 条目。公开、可搜索、被 Google 收录。从提取到全球分发的时间:几分钟。密钥被吊销的时间:通常永远不会。

并非每个盗版团伙都只搞一个静态网页。有些会发布一个完整的安卓应用——带登录界面、Firebase 分析、加密配置和专业的 UI。我在世界杯期间分析的一个应用就采用了这种做法。525 个频道。36 个分类。一个专门的"MUNDIAL FIFA 2026"板块,每场比赛都有多机位视角。

该应用加密的频道配置——横跨 36 个分类的 525 个频道,带有 AES 加密的 URL 和 DRM 凭据。[URL 已隐去]

该应用从远程服务器获取其频道列表,形式是一段经过 AES 加密的 JSON。每一个字段——直播流 URL、DRM 授权 URI、HTTP 头——都是经过 base64 编码的 AES 密文。解密密钥是一个 16 字符的字符串,存放在 Firebase Remote Config 里,在启动时获取。

听起来挺正经。然后你看一眼密文:

text

    236 URLs share the same first 35 encrypted blocks.

    Block 0: f91b7f273abccc6e...  ← identical across all 236
    Block 1: 932b23560f1d43ba...  ← identical
    Block 2: a7d788a399cea962...  ← identical
    ...

    ECB mode. Same plaintext block = same ciphertext block.
    The URLs all start with the same CDN domain prefix.

AES-ECB 是教科书级别的"如何正确使用 AES"的反面例子。每一门密码学课程都会用ECB 企鹅来讲解这一点——用 ECB 加密一张位图,图像依然能被辨认出来,因为相同的明文块会产生相同的密文块。这个应用加密了 236 个以同一个 CDN 域名开头的 URL,产生了 236 段拥有相同 560 字节前缀的密文。光是做模式分析,你还没找到密钥,就已经能看出结构了。

一旦解密,ClearKey 凭据并不存在于某个单独的密钥交换里。它们就在授权 URI 本身之中,作为明文查询参数:

text

    drm_license_uri (after decryption):

    https://[redacted]/?keyid=49eb924b...&key=6e131b04...
                              ^^^^^^^^        ^^^^^^^^
                              ClearKey ID     ClearKey Key
                              (in the URL)    (in the URL)

这个应用的"授权服务器"就是一个包含着密钥的 URL。没有挑战-应答。没有会话绑定。应用去获取这个 URL,而这个 URL 就是密钥,密钥再去解密直播流。

三层间接——Firebase Remote Config、AES 加密、一个"授权服务器"端点——全都坍缩成同一个失败:解密密钥以明文形式落到了客户端手里,因为 ClearKey 要求如此。

text

    ┌──────────────────────────────────────────────────────────────┐
    │           ANDROID APP ARCHITECTURE                           │
    └──────────────────────────────────────────────────────────────┘

    1. App launches
       └──> Firebase Remote Config
            └──> Fetches AES key ("claveapp") + config URLs

    2. App fetches encrypted JSON (525 channels)
       └──> Base64 decode ──> AES-128-ECB decrypt
            └──> Stream URLs, DRM license URIs, headers (plaintext)

    3. For CLEARKEY channels (348 of 525):
       └──> "License URI" = https://[redacted]/?keyid=XXX&key=YYY
            └──> Key ID and Key are IN THE URL

    4. App configures ExoPlayer with ClearKey
       └──> Fetches DASH manifest from legitimate CDN
            └──> Decrypts video with the key from step 3

    Package name: com.example.myapplication
    Encryption:   AES/ECB/PKCS5Padding (textbook insecure)
    Key storage:  Firebase Remote Config (single API call to extract)
    Key length:   16 characters, static, never rotated

包名 com.example.myapplication 把这场操作背后的开发严谨程度交代得明明白白。Android Studio 的默认模板。连名字都没改。

最不动声色却又最致命的一点——也是最能体现这场操作真正高明之处的一点(其高明之处主要在于后勤调度)——是那份加密配置的托管位置。该应用从一个公开的 GitHub 仓库获取它的频道 JSON。任何人都能浏览它。任何人都能 git clone 它。任何人都能查看提交历史。

而提交历史才是有意思的地方:

托管着该应用加密频道列表的那个公开 GitHub 仓库。每 4–5 分钟就会落下一个提交——这是对频道 JSON 的自动化编辑,随着上游直播流被轮换、被掐断或被替换而更新。用户名和仓库所有者已隐去。

每 4–5 分钟就会落下一个提交。差异始终是针对 tv (10).jsonbearer.json 的——前者是加密的频道列表,后者是用来从上游获取新直播流的鉴权凭据。提交信息全都是 "Actualizar tv (10).json desde tv.json""Actualizar bearer.json desde panel - <timestamp>"。翻译过来就是:某处有一个自动化任务,每隔几分钟就重写一遍频道配置并推送更新,好让运行该应用的手机在一个轮询周期之内拿到新的直播流 URL 和轮换后的 DRM 凭据。

这才是这场操作真正的护城河。不是 AES-ECB(已破解)。不是 Firebase Remote Config(一次 API 调用)。不是那个"授权服务器"(一个把密钥写在里头的 URL)。这条护城河是运营层面的:一段自动化程序,时刻让频道 JSON 与那一刻还活着的上游信号源保持对齐,并且明目张胆地托管在一个他们根本不用自己搭建的免费 CDN 上。当一个合法提供商轮换密钥时,机器人会察觉到,去获取新密钥,重新加密配置,然后提交。当一个 CDN 封掉源 IP 时,机器人就再找一个。客户的手机轮询、看到新提交、获取新配置,然后继续看比赛。用户甚至都看不到轮换发生。

人人都会想到的防御手段是"吊销密钥"。但你吊销一个密钥的速度,永远快不过一个脚本把新密钥推到 GitHub 仓库的速度。这种节奏上的不匹配,就是整盘棋的关键。

网页审计安卓应用
直播流670525(348 路 ClearKey)
CDN16934
国家33~8(以拉美为主)
密钥存储JavaScript <script>Firebase Remote Config
混淆JS 变量重命名 + IIFEAES-128-ECB(已破解)
客户端明文密钥
世界杯覆盖数十个体育频道28 个专属频道 + 多机位

两种做法——静态网站和完整的安卓应用——最终都落到同一处:一对 ClearKey 密钥躺在客户端内存里,没有任何机制能阻止它被提取,没有会话绑定,没有吊销,也没有密钥轮换。

经济账解释了一切。盗版网站托管着约 50KB 的静态 HTML,把你的浏览器指向别人的 CDN。那个应用不过是裹在别人基础设施外面的一层薄薄的 ExoPlayer。两者都不提供视频。两者都靠广告网络变现。

StreamEast 在 2025 年 9 月被查封前,已经服务了 16 亿次访问。“Operation Takendown"行动中的那个 IPTV 团伙拥有 2200 万用户,每月进账 2.5 亿欧元。一个中等规模的网站在世界杯期间——比赛日一百万访客,每人六次广告展示,CPM 1.50 美元——在几乎为零的托管成本下,每天净赚 9000 美元

执法力度不断升级——西班牙的监禁判决、得州的 1875 万美元判赔、世界杯前一周下架的 27000 个信号源——而新网站还是层出不穷。因为这个漏洞是架构性的。面对一个把解密密钥放进浏览器的规范,你抓人是抓不完的。你也加密不出去,正如那个安卓应用所示范的:三层加密,密钥最后还是以明文形式落在客户端,因为 ClearKey 就是这么要求的。

真正的修复办法,是彻底迁移出 ClearKey——转向 Widevine、FairPlay 或 PlayReady。在那之前,密码就刻在挂锁的背面,而世界杯正确保所有人都知道该往哪儿看。

相关内容