盗版网站如何把视频伪装成字体,滥用 Cloudflare 缓存

一场有节制的调查:以 .woff2 为 URL 的 MPEG-TS 分片、在 Cloudflare 边缘被缓存,并在两条分发路径上复现。

商业电影盗版,跑的是别人的 CDN,而我花了很长时间搞清楚到底是谁的。去年,其中一个网站开始把视频当字体文件来提供;今年 7 月,我又发现另一个毫不相关的运营方也在干同样的事。它的播放器在拉 .woff2 文件,每十秒一个,大小在 111 KB 到 888 KB 之间。

WOFF2 是一种 Web 字体格式。2025 年 Web Almanac 的数据显示,字体响应的中位数是 23 KB,第 90 百分位是 79 KB。那一串文件里,每一个都超过了第 90 百分位。最大的那个,是它的 11 倍。

我拉了一个下来,跑了一下 file:

MPEG transport stream data

H.264 视频,AAC 音频。第零个字节是 0x47,也就是 MPEG-TS 的同步字节,188 字节的包一路整齐排到文件末尾。没有包装层,没有需要剥掉的头部。实际上就是 mv segment.ts segment.woff2,然后直接发出去。

为什么改个扩展名就够了

处理这个文件的是两个系统,而它们对“什么决定文件类型”这件事的判断并不一致。

Cloudflare 看文件名。它 2026 年 5 月 6 日更新的缓存文档说得很直接:缓存决策用的是文件扩展名,不是返回的 MIME 类型。默认可缓存列表覆盖字体(WOFF、WOFF2、TTF、EOT、OTF)和媒体(MP4、MKV、WEBM、MP3、FLAC),但不覆盖 .ts 或 .m3u8,而这两个恰恰是 HLS 实际传输用的格式。

HLS.js 看字节。在 1.5.18 版本里,TSDemuxer.probe() 会调用 syncOffset(),在前 940 字节里扫描间隔 188 字节的 0x47 标记,并检查是否存在节目关联表。URL 后缀从头到尾都不参与这个判断。一个从第零字节开始的裸 TS 分片,返回偏移 0,正常播放。

所以,改个名只需要一条命令,就同时满足了两个系统。CDN 在缓存列表上看到的是一个字体扩展名。播放器在第零字节看到的是合法的传输流。

那为什么不干脆用 .mp4?它也在默认列表上。我的理解是,.mp4 等于自报家门。任何扫描请求元数据的流水线,不用碰载荷就能把它标出来。而一个 .woff2 URL 什么都不宣告,要确认里面是什么,得把对象拉下来足够多的部分,去检查签名和包结构。Cloudflare 把视频限制说成是带宽问题,而一秒视频的成本大致就是一次页面加载的成本。换扩展名并没有让违规变得不可检测,它只是让确认和处置变得更贵——如果你在运营这门生意,这是一个不同而且更有用的性质。

十二个分片说明了什么

2026 年 7 月,minochinos[.]com,来自它 Cloudflare 前置的备用 CDN 的十二个 .woff2 分片。

第一个的响应头:

HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
cf-cache-status: HIT
cf-ray: ...-SIN
server: cloudflare

源站连 MIME 类型都懒得跟扩展名对齐。一个名为 .woff2、内容是视频的文件,它返回 text/plain,而这个对象照样被缓存了。

前 32 个字节:

00000000: 47 40 00 11 00 00 B0 0D 00 01 C1 00 00 00 01 EF
00000010: FF 36 90 E2 3D FF FF FF FF FF FF FF FF FF FF FF

WOFF2 文件开头是 77 4F 46 32。这个开头是 47。

分片大小TS 包数
1114,680610
2111,672594
3120,696642
4114,680610
5156,792834
6310,2001,650
7782,4564,162
8860,6644,578
9686,2003,650
10698,2323,714
11695,2243,698
12887,7364,722

每个大小都能被 188 整除,没有余数,所以这些文件里任何地方都没有填充、尾部或外壳。十二个全部返回 cf-cache-status: HIT。播放列表标注的是十秒分片,ffprobe 测得这一组在 10.06 到 10.08 秒之间,所以八倍的大小差异来自码率和画面复杂度,而不是时长。

有一件事我没做:用不同扩展名拉取同一个对象的对照测试。缓存规则、Cache-Control 头和其他 zone 配置,都可能影响某个具体响应是否被存储,仅凭这十二个请求,我没法把扩展名单独隔离成原因。我能说的是:这些对象是从边缘缓存提供的,而扩展名是这里唯一能对应上 Cloudflare 文档中默认列表的变量。

同一部电影,两个 CDN

这个网站的主分发路径更奇怪。它通过一家市值千亿的消费科技公司的 CDN 提供同一部视频,形式是 PNG polyglot:一个 70 字节的合法 PNG 外壳,后面拼接原始 TS,通过一个面向广告主的图片端点上传,再以一年期的签名 URL 提供。当这些失败时,播放器回退到 Cloudflare 路径。我在这里不点名这个平台,因为这个攻击面还没被修补,而运营方也没有明显的替代方案。

配对PolyglotCloudflare WOFF2TS 载荷包数
1114,750114,680114,680610
2111,742111,672111,672594
3120,766120,696120,696642
4156,862156,792156,792834

Polyglot 文件正好大 70 字节。剥掉 PNG 外壳后,SHA256 哈希与 Cloudflare 分片逐字节一致(配对 1 到 3 对应分片 1 到 3,配对 4 对应分片 5;分片 1 和 4 共享同一份载荷)。同一部电影,两种滥用技术在并行运行。

两者之中,WOFF2 是廉价档。Polyglot 需要一个构造步骤,以及一个会跳过外壳继续扫描的播放器。改名只需要一个源站、一个可弃用的 Cloudflare 前置域名,和 mv。域名被标记了,就再注册一个。

规模

这不是一个业余玩家。StreamHG 集群,在包括 kravaxxa[.]com 和 haxloppd[.]com 在内的多个域名上可见,整个 2025 年都在可弃用的 Cloudflare 域名上使用 .woff2,估计月访问量达 640 万(SEMrush,2025 年 9 月,这是我能拿到的最新数字)。Minochinos 是另一个独立运营方,它的流量不包含在这个数字里。

StreamHG 还把 .woff2 文件名放在 Cloudflare R2 预签名 URL 上,形如 [bucket].r2.cloudflarestorage.com/.../file.woff2?X-Amz-Signature=...。我无法确认这些 URL 是否被边缘缓存,而 Cloudflare 的 R2 文档说,预签名 URL 存在于 S3 API 域名上,不能配合自定义域名使用。它的条款更新也允许通过 CDN 从 R2 提供视频,因为视频限制针对的是托管在 Cloudflare 之外的内容。所以 R2 这个案例是版权侵权加上可弃用基础设施,但并不是同一种缓存绕过。这种命名习惯延续到一个它毫无收益的语境里,读起来更像是一个共用的上传工具,而不是刻意的手法——这使它成为一个聚类线索,仅此而已。

为什么它一直有效

这里的缺口是执法经济学,不是 bug。按扩展名缓存是有意为之、有文档记录、对性能有益的。而能抓住这种行为的信号,其实很便宜:

一个不以 77 4F 46 32 开头的 .woff2 文件就是错的,检查这一点在缓存填充时只花四个字节。我那十二个分片里,没有一个有合法头部。

一个页面只会请求一小组可复用字体。HLS 则是在两小时内按固定间隔请求一长串有序的、互不相同的对象。这个模式仅凭请求元数据就能看出来,一个载荷字节都不用读。

单独看,这两个信号都不足以定论。CJK 字体家族确实会合法地拆成数百个 Unicode 范围子集,大小也可能远超全网尺寸百分位,所以对象数量多或字体大,本身不是任何事的证据。但序列、间隔、大小,加上缺失的魔数,合在一起就是另一回事了。

所以,诚实的版本是:Cloudflare 能检测到。它之所以持续存在,是因为一个可焚毁域名只要几美元,而根据检测结果去处置的滥用流水线成本要高得多。盗版方不需要一个永远有效的绕过方案。他们需要的是,容忍他们的成本低于清除他们的成本——而目前,确实如此。

这个普遍教训超出了盗版本身。任何系统,如果它靠扩展名决定怎么处理一个文件,而最终的消费者却靠字节来决定,那它就有这个缺口。扩展名等于内容,这个假设成立,直到攻击者开始挑文件名。

先前工作

Chocolatkey 在 2024 年 2 月的《盗版视频主机如何绕过 Cloudflare 的 TOS》中记录了这项通用技术,覆盖了随机扩展名(.txt、.css、.html、.gif、.png)并确认了 cf-cache-status: HIT。这是我能找到的最早公开记录。里面没有出现 .woff2,我也没有找到更早的报告描述 WOFF2 变体、R2 预签名 URL 命名,或双 CDN 回退安排。


文件格式、包对齐、时长、哈希匹配和 CDN 响应结论,均复现自下载的证据。缓存行为和播放器探测结论,来自 Cloudflare 文档和 hls.js 1.5.18 源码。流量估算为第三方数据(SEMrush,2025 年 9 月)。作者不托管或分发任何受版权保护的材料。证据文件私下保留,可应 CDN 提供商和执法部门要求提供。活跃域名已做去毒化处理。

THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容