从一次盗版镜像事件说起:用 20 行 JS 让镜像站流量归零
起因
7 月 10 日,UpXuu 发了一篇博客《关于近期全站被盗版镜像的处理》——他的站点 upxuu.com 被人用 Cloudflare Worker 全站镜像到了 qas458.com,实时同步所有文章、图片、页面内容,未获任何授权。
这种事在技术博客圈并不罕见。攻击者的套路很简单:
wget --mirror一把梭下载整个站- 丢到 Nginx 上,改个域名
- 搜索引擎收录 → 流量到手
UpXuu 的处理方式是 DMCA 投诉 + 域名校验脚本弹窗。看完之后我检查了自己的站点 nixegus.com,发现没有任何防护。
那就加上。
思路
镜像站的本质矛盾在于:攻击者下载的是静态文件,但真实访客打开的是浏览器。浏览器会执行 JavaScript,而 wget/curl/httrack 不会。
利用这个差异:在页面里嵌入一段 JS,检查当前域名是否匹配,不匹配就跳回真站。
// 密钥与密文分开存储,防止全文搜索替换
const XOR_KEY = "97vaMcLo";
const XOR_CIPHER = atob("TkABTyMKNApeQgVPLgwh");
function getTargetHost() {
let host = "";
for (let i = 0; i < XOR_CIPHER.length; i++) {
host += String.fromCharCode(
XOR_CIPHER.charCodeAt(i) ^
XOR_KEY.charCodeAt(i % XOR_KEY.length)
);
}
return host; // → "www.nixegus.com"
}
(function () {
const targetHost = getTargetHost().trim();
if (window.location.host === targetHost) return;
const targetUrl = window.location.protocol +
"//" + targetHost +
window.location.pathname +
window.location.search +
window.location.hash;
window.location.replace(targetUrl);
})();
几个设计要点:
- XOR 加密域名:不是防破解,是防止攻击者对 HTML 全文搜索
nixegus.com然后一键替换。密钥和密文分开存,Base64 再包一层,增加自动化替换的麻烦。 location.replace():不用location.href =,这样访客点后退回不到镜像站,浏览器历史记录被替换。- 全站嵌入:首页、文章页、标签页、关于页——每个 HTML 页面都放一份,不留死角。
- 对正常访客零影响:host 匹配时直接
return,什么都不会发生。
测试
写完不测等于没写。用了三种克隆工具 + 浏览器对 www.nixegus.com 做了完整测试:
| 工具 | 能否下载文件 | 执行 JS | 对镜像站访客的效果 |
|---|---|---|---|
wget --mirror |
✅ 31 个文件 | ❌ | 无影响(但不执行 JS) |
httrack -r3 |
✅ 40 个文件 | ❌ | 无影响(但不执行 JS) |
curl |
✅ 9 个文件 | ❌ | 无影响(但不执行 JS) |
| 浏览器访问镜像站 | — | ✅ | 自动跳回真站 |
前三个工具能完整下载站点——这一点没法防,也没必要防。静态文件本身就是公开的。
关键在于第四行:当真实访客通过镜像域名访问时,浏览器自动执行 JS,检测到 host 不匹配,立即跳回 nixegus.com。
测试还覆盖了几个边界场景:
| 场景 | 结果 | 原因 |
|---|---|---|
浏览器访问 www.nixegus.com |
✅ 正常 | host 匹配,脚本跳过 |
| 浏览器访问镜像站 | ✅ 跳回真站 | host 不匹配 |
本地 file:// 打开克隆文件 |
⚠️ 跳转失败 | host 为空,URL 非法 |
localhost:8080 serve 克隆文件 |
✅ 跳回真站 | host 为 localhost |
| hosts 劫持指向本地 | ❌ 正常显示 | host 被伪造为真域名 |
| 关闭 JavaScript | ❌ 正常显示 | JS 不执行 |
| 搜索引擎爬虫 | ❌ 正常 | 爬虫不执行 JS |
hosts 劫持和禁用 JS 这两种情况无法防御,但它们的攻击成本和收益完全不成比例——对于批量镜像攻击者来说,需要考虑的不是技术上限,而是成本下限。
成本效益分析
这个机制真正的杀伤力不在技术层面,而在攻击者的决策链上:
攻击者的选择树:
① wget --mirror 一把梭 ← 成本 0
② 丢到 Nginx 上 → 完事 ← 成本 0
③ 发现 JS 跳转 → 流量为零 ← 收入 0
④ 选择:花 10 分钟写后处理脚本 / 换一个站
⑤ → 换一个站。 ← 成本 0,收入正常
批量镜像攻击者的目标是 "偷流量",不是 "攻克某个特定站点"。只要还有无防御的站可以镜像,他们不会在任何一个站上多花一分钟。
| 选项 | 成本 | 收益 |
|---|---|---|
| 分析并移除 JS 脚本 | 10-30 分钟 + 写后处理 | 一个站的流量 |
| 换一个没有防御的站 | 0 | 一个站的流量 |
评价
| 维度 | 评价 |
|---|---|
| 服务器开销 | 零,纯客户端 |
| 实现成本 | 一个 <script> 块,零依赖 |
| SEO 影响 | 无,爬虫不执行 JS |
| 对正常访客 | 无感,host 匹配时直接跳过 |
| 对镜像站访客 | 自动跳回真站 |
| 对抗批量攻击 | 极高——攻击者不会为你写后处理脚本 |
这个方案不是 "无法绕过",而是 "不值得绕过"。 攻击者面对的不是一道密码学难题,而是一道经济题:花时间去处理 JS 不如换个目标来得快。
参考
- 关于近期全站被盗版镜像的处理 — UpXuu
- 测试工具:wget, httrack, curl, Chromium headless
评论