站长圈里最常见的惊吓之一:自己输入网址一切正常,用户却说一点开就跳到一个陌生页面,有的还带“恭喜中奖”“博x优惠”这种字眼。第一反应往往是“是不是浏览器坏了”,其实网站突然跳转到陌生页面,十有八九是站点被挂马了——攻击者往你的程序里塞了跳转代码,拿你的域名当跳板去引流。
在动手之前,先把“真挂马”和“假跳转”分开,否则白忙一场。下面按确认、定位、清理、止血的顺序来。
一、先排除不是挂马的情况
有几种跳转看起来像挂马,其实不是。第一,DNS 被改:域名解析指向了别人的服务器,这种情况你后台也登不上去,去域名控制台看解析记录就被改过。第二,CDN 或缓存没刷新:你刚改完页面,用户看到的是旧缓存里的跳转,强制刷新或清缓存就好。第三,浏览器插件或运营商劫持:换个无插件的无痕窗口、换台设备访问,如果不再跳,问题在你本地环境。第四,自己之前配过的 301:比如旧站搬迁时写的整站跳转忘了删。把这四类排除掉,剩下的才是真挂马。
二、确认跳转来自服务器还是前端
确认被挂马后,要分清跳转是服务端下发的还是前端脚本触发的。用命令行 curl -I 你的首页,如果响应头里直接出现 Location: 陌生域名,说明是服务端(.htaccess、Nginx 配置、程序里的 header 跳转)在跳;如果 curl 正常、但浏览器里跳,说明是页面里的 JS 在跳。再做一个验证:用 curl 带上普通浏览器 UA 和不带 UA 各请求一次,若结果不同,说明跳转代码在按 UA 或 Referer 下发,专门挑真用户下手、躲过站长自查。这个区别决定了你后面去哪一层找代码。
三、跳转代码常藏的四个入口
恶意跳转最爱藏在这几个地方:首页或入口文件 index.php 顶部被插了一行 header 跳转;公共模板的页脚 footer 里被加了 JS(document.location、window.location、meta refresh);数据库的配置表被写入跳转地址,后台改了也白改;.htaccess 或 web.config 里被加了 RewriteRule 把所有请求重定向。下面这段脚本帮你把全站扫一遍,凡是含跳转特征的文件都打出来,你顺着清单去定位最快。
# 在全站文件里搜索跳转类代码,定位恶意跳转藏在哪里
import os, re
ROOT = "/www/example.com" # 改成你的站点根目录
PAT = re.compile(
rb"(location\s*\.\s*(href|replace)|window\.location|document\.location|"
rb"http-equiv\s*=\s*[\"']?refresh[\"']?|"
rb"RewriteRule[^\n]*(Redirect|Location)|"
rb"header\s*\(\s*['\"]location)",
re.I,
)
for root, _, files in os.walk(ROOT):
for f in files:
fp = os.path.join(root, f)
try:
data = open(fp, "rb").read()
except OSError:
continue
if PAT.search(data):
print("疑似含跳转代码:", fp)
跑出来的清单里,优先看 .htaccess、首页入口文件和公共模板,这三处命中基本就是源头。数据库里的跳转要单独查:在后台或命令行里检索配置表,看有没有陌生域名。找到后把那一行删掉、模板还原,跳转就停了。
四、止血与清理的收尾
跳转停了不代表安全了。挂马留下的后门可能不止跳转这一处,按上一篇文章的清除流程把 webshell 和后门一并清掉,再改掉所有密码。最后去站长平台复查快照是否恢复正常、提交被黑修复反馈。记住一件事:用户报告跳转那刻,伤害已经在发生,响应越快,流量和信誉损失越小。
相关阅读:
申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!
