你的网站是不是突然“跳”到了别处?

昨天客户凌晨两点发我截图:用户点进官网,秒切到一个卖壮阳药的页面。他自己试了三次,两次中招。你可能也经历过——不是每次访问都跳,但只要有人反馈,心里就咯噔一下:哪段代码在偷偷搞鬼?

别急着删文件,先摸清它藏在哪。这事儿真不玄乎,老站长都碰过,关键是按顺序一步步筛。

第一步:如何确认网站真的被挂了跳转代码?

先停手,别急着改代码。很多“被挂”其实是假警报:公司WiFi路由器被劫持、本地hosts文件被改、甚至浏览器装了流氓插件,都会造成跳转假象。

最靠谱的验证方式就两条:

  • 打开 Chrome 或 Edge 的无痕窗口(别登录账号),直接输网址访问;
  • 拿手机关掉 WiFi,切到 4G/5G 网络,用 Safari 或 Chrome 访问同一地址。

如果两个环境都跳,问题才大概率出在你服务器上。再补一招:用 curl 命令看原始响应头(如果你有服务器 SSH 权限),或者直接在浏览器开发者工具里打开 Network 标签页,刷新页面,点首页请求 → 查看 Response Headers 里有没有异常的 Location 字段,或者 <script> 标签指向了陌生域名。

我们之前遇到个客户,反复说首页跳转。结果发现他办公室所有电脑都走同一条内网出口,而那台出口路由器的 DNS 设置被人改成了恶意地址——换家咖啡馆连 WiFi 就一切正常。所以,交叉验证这十分钟,真能省你半天白忙活。

第二步:从哪里开始进行文件排查?

锁定是服务器问题后,别一股脑翻几千个文件。黑客图快,最爱动三类地方:入口文件、主题/插件里的 JS、还有服务器配置。

先盯死这几个文件:

  • 网站根目录下的 index.php(或 index.html
  • .htaccess(Apache 用户必查)
  • Nginx 用户则重点看站点配置里有没有 rewriteadd_header 被塞了 JS

打开它们,拉到最开头和最末尾——90% 的跳转代码就插在这两处,一行 window.location.href=... 或一段 document.write(...),伪装成统计代码。

接着去 /wp-content/themes//wp-content/plugins/ 目录下,用 FTP 工具或宝塔面板的文件管理器,按“修改时间”倒序排列。重点看那些你最近没动过、却显示“今天刚改”的 .js.php 文件——尤其是名字像 footer.min.jscommon.php 这种不起眼的。

第三步:如何识别经过伪装和加密的恶意代码?

没人会明目张胆写 location.href="http://xxx.com"。他们惯用三招:混淆、拼接、套壳。

PHP 里常见这种套路:

<?php $a = "base64_decode"; $b = "eval"; $c = "H4sIAAAAAAA..."; $b($a($c)); ?>

看到 eval( + base64_decode( + 一长串乱码,基本可以判定是黑产模板。

JS 里更隐蔽:

  • 整个脚本压缩成一行,里面夹着 String.fromCharCode(119,105,110,100,111,119...)
  • 或者用 document.createElement('iframe') 动态加框
  • 甚至把跳转逻辑藏在图片 onerror 事件里

别只扫文件头尾。用编辑器(比如 VS Code、Notepad++)打开可疑文件,Ctrl+F 全局搜这几个词:
evalbase64_decodefromCharCodedocument.write<iframelocation.hrefwindow.open

搜出来高亮的行,逐行读。哪怕只是多了一个空格后的 // 注释,也可能藏着跳转指令。

第四步:数据库是不是也被“污染”了?

文件全扫完没发现?或者删了又回来?那得查数据库了。很多挂马是“持久型”的——代码被塞进文章正文、评论、甚至 WordPress 的主题设置里。

如果你用的是 WordPress:

  • 登进 phpMyAdmin(宝塔、cPanel 里都有)
  • 找到 wp_posts 表,重点查 post_content 字段,搜 <scripteval(javascript:
  • 再查 wp_options 表,搜 option_nametheme_mods_siteurl 的记录,看 option_value 里有没有嵌了 JS

注意:黑客常把 <script> 编码成 &lt;script&gt; 来绕过基础搜索。所以搜的时候,把关键词也换成 HTML 实体形式试试。

我们帮一个教育类网站处理过,跳转代码就藏在三年前一篇“招生简章”的文章末尾,用 <!-- 注释包着,实际渲染时却被执行了——因为主题模板用了 wp_kses_post() 但漏掉了 script 标签过滤。

第五步:清除后如何防止再次被挂?

删干净只是开始。真正要命的是:漏洞还在那儿,黑客明天就能原路杀回来。

立刻做这四件事:

  1. 把 WordPress 核心、所有启用的插件、当前主题,全部更新到最新稳定版(别用破解版!)
  2. 删除所有没启用的主题、停用半年以上的插件——它们是最大的后门温床
  3. 重设所有密码:后台管理员、FTP 账号、数据库用户,必须含大小写字母+数字+符号,且彼此不同
  4. 登进服务器终端(或宝塔后台),用 last 命令看看最近登录记录,删掉不认识的用户

如果你不常碰服务器,装个靠谱的安全插件真有必要。Wordfence 或 Sucuri(免费版够用)能实时监控文件变动、限制暴力登录、隐藏 wp-login.php 地址。另外,养成每周手动备份一次的习惯——把整个网站目录 + 数据库 SQL 文件,存到本地或阿里云 OSS,出事时双击还原,比重装快十倍。

今天下班前就能执行的具体操作

现在,就打开电脑:

  1. 用手机关 WiFi,切 4G/5G,访问你的网站;再用电脑开无痕窗口访问,确认是否都跳
  2. 登进你的 FTP(FileZilla / 宝塔 / cPanel 文件管理器),直奔网站根目录,打开 index.php.htaccess,拖到最底部,看有没有多出 <script>window.location
  3. 进入 /wp-content/themes/,按修改时间排序,点开最近改动过的主题文件夹,找 footer.phpfunctions.php;同样方法查 /wp-content/plugins/ 下最近改过的插件
  4. 用记事本或 VS Code 打开这些文件,Ctrl+F 搜 evalscript,发现就复制整段出来,先备份,再删
  5. 最后一件事:打开 WordPress 后台 → 用户 → 所有用户,把所有非管理员角色的密码重置一遍;再去宝塔或服务器终端,把 FTP 和数据库密码全换掉

做完这五步,今晚睡觉前,你大概率就能松口气了。