网站被劫持怎么办恢复正常

文章导读
网站被劫持后想恢复正常,先别急着删文件或整站还原。多数情况不是整站被换掉,而是某一层被改写:DNS 解析、CDN 回源、nginx 配置、CMS 主题或插件、数据库正文里被塞了脚本。恢复动作要和被改的那一层对应,层次判断错了,改完过几天往往又出现。下面按实际排查顺序给可核对的位置和命令,先把层定位清楚,再动手。
📋 目录
  1. Ⅰ 网站被劫持怎么办恢复出厂设置
  2. Ⅱ 网站被劫持先定位在哪一层
  3. Ⅲ 网站被劫持:先看这四个位置
  4. Ⅳ 网站被劫持:按可能性从高到低排除
  5. Ⅴ 网站被劫持:改完怎么确认真的解决了
A A

网站被劫持后想恢复正常,先别急着删文件或整站还原。多数情况不是整站被换掉,而是某一层被改写:DNS 解析、CDN 回源、nginx 配置、CMS 主题或插件、数据库正文里被塞了脚本。恢复动作要和被改的那一层对应,层次判断错了,改完过几天往往又出现。下面按实际排查顺序给可核对的位置和命令,先把层定位清楚,再动手。

先定位是哪一层被改,再动文件。建议的判断顺序是:多出口 DNS 解析对比、源站直连与公网域名对比、服务器本机取首页与公网对比、日志和文件修改时间对照。几组对比中只要有一组不一致,就优先修对应那一层。「恢复出厂设置」在网站语境里指把站点文件、数据库和 Web 配置回滚到劫持前的已知干净备份,不是面板上的一个按钮;回滚前先留一份现场快照。

网站被劫持怎么办恢复出厂设置

网站没有真正的「出厂设置」按钮,这个词对应的是最后一步动作:当站点文件已被大面积改写、找不到干净版本时,用劫持前的备份把文件、数据库、Web 配置整体还原。它不适合当第一步,因为一旦覆盖,入侵入口的痕迹也一起丢了。

判断要不要走这一步,先看两个能核对的位置。第一是文件修改时间:

# 列出站点目录最近 7 天被改动过的文件,按时间倒序
find /www/wwwroot/www.example.com -type f -mtime -7 -printf '%TY-%Tm-%Td %TH:%TM  %p\n' | sort -r | head -30

如果输出里大量文件的修改时间集中在同一个几分钟内,且包含 index.php、主题模板、functions.php 这类文件,通常说明是被批量写入,值得回滚。如果只有一两个可疑文件,先按后面的排查逐层处理,不必整站还原。

第二是面板的备份列表。以常见面板为例,路径是「网站 → 某个站点 → 备份」,看列表里的「备份时间」「大小」「备注」三列,确认是否存在劫持发生之前的备份点。不同面板字段名可能叫「快照」「历史版本」,以你面板实际显示的为准。确认有干净备份点后,先留现场再还原:

网站被劫持怎么办恢复正常
tar -czf /root/site-snapshot-$(date +%F-%H%M).tar.gz /www/wwwroot/www.example.com
mysqldump -u root -p 你的库名 > /root/db-snapshot-$(date +%F-%H%M).sql

网站被劫持先定位在哪一层

改错地方是最常见的返工原因。劫持通常落在以下几层,每层都有对应的检查位置和对不上的判断依据。

  • DNS 解析层:用不同 DNS 分别解析同一域名,看返回 IP 是否一致。dig +short www.example.com @223.5.5.5、dig +short www.example.com @8.8.8.8、dig +short www.example.com。三方结果不一致,或某个 IP 根本不属于你的服务器,问题在解析层。
  • CDN / 反向代理层:直连源站 IP 取首页与走域名取首页做哈希对比。curl -s -H 'Host: www.example.com' http://源站IP/ | md5sum 与 curl -s https://www.example.com/ | md5sum。直连干净、域名异常,问题在 CDN 或代理层。
  • Web 服务器层:在服务器上取本机首页,curl -s http://127.0.0.1/ -H 'Host: www.example.com' | md5sum。本机干净但公网异常,说明中间还有一层;本机就异常,问题在服务器配置或站点程序本身。
  • 应用 / CMS 层:服务器本机取到的首页里含可疑 script、iframe,而 nginx 配置正常,重点查主题、插件、上传目录和数据库正文。
  • 终端层:只有你自己的电脑打开异常,手机流量或其他网络正常,查本机 hosts 文件(Linux/macOS:/etc/hosts,Windows:C:\Windows\System32\drivers\etc\hosts)和浏览器扩展。

网站被劫持:先看这四个位置

四个位置按打开成本从低到高排列,建议先全部看一遍再决定改哪里。

  1. 访问日志:/var/log/nginx/access.log(面板环境常见 /www/wwwlogs/站点名.log)。先看来源集中度:awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20;再看向非常规路径的 POST:awk '$6 ~ /POST/ {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20。正常后台之外出现 /xx.php 这类文件的 POST,值得顺着 IP 和时间段回查。
  2. 命令输出:curl -s https://www.example.com/ | head -40 看头部是否多出 script;curl -sI https://www.example.com/ 看状态码和 Server 字段是否符合预期;curl -s https://www.example.com/ | grep -nE 'script src|iframe' | head 找出外链来源。
  3. 配置项:nginx -T | grep -nE 'proxy_pass|rewrite|include|return 30' 检查是否有你没写过的反代或跳转;ls -l /etc/nginx/conf.d/ /etc/nginx/sites-enabled/ 看配置文件修改时间。
  4. 面板字段:域名解析记录里的「记录值」和「修改时间」、CDN 控制台的「回源地址」和「缓存规则」、面板站点设置里的「网站目录」「默认文档」「伪静态」。这几项被改动往往不留文件痕迹,只能靠面板记录核对。

网站被劫持:按可能性从高到低排除

以下是常见的排列顺序,每一项都配一个能确认或排除它的动作。

  • 主题 / 插件 / 上传目录被写入(最常见):grep -rn 'eval(\|base64_decode' /www/wwwroot/www.example.com/wp-content/themes --include=*.php -l。查出可疑文件后,用官方同版本包对比该目录,或直接重装这个主题 / 插件。
  • Web 配置被追加反代或跳转:nginx -T 输出中逐个核对 location 和 include,确认没有指向外部地址的 proxy_pass。可疑文件先备份再删除,然后 nginx -t 校验。
  • 数据库正文被注入脚本:把文章表导出后搜索 grep -i '<script' 导出文件.sql,命中就说明是内容层注入,需要清理正文而不是改模板。
  • DNS 记录被改:对照前面多出口 dig 的结果,登录域名控制台看「修改时间」字段,同时改掉域名账号密码并开启二次验证。
  • CDN 回源或缓存被污染:刷新缓存后用带随机参数的地址取首页 curl -s 'https://www.example.com/?_=12345' | md5sum,与直连源站结果对比。
  • 终端本地问题:换设备、换网络访问同一域名。只有原设备异常,就清理 hosts 对应行和浏览器扩展。

这里有个容易踩的坑:把首页或模板里的注入代码删干净、页面看着恢复了,却没有找到写入入口(比如上传目录里一个可执行的小文件、后台弱口令账号)。这种情况下通常几天内会再次被改写,让人误以为是缓存没清。处理完表面症状后,要回到访问日志按时间段找首次写入前后的异常请求,把入口一并堵掉。

网站被劫持怎么办恢复正常

网站被劫持:改完怎么确认真的解决了

验证分两步。先做即时核对:走域名取首页、直连源站取首页、服务器本机取首页,三份哈希应当一致;curl -sI https://www.example.com/ 的状态码和 Server 字段恢复正常;nginx -T | grep -c proxy_pass 的数量和你预期的一致。

再做持续观察,用脚本定期取首页比对哈希,发现变化就记录时间点:

for i in $(seq 1 20); do
  echo "$(date '+%F %T') $(curl -s "https://www.example.com/?_=$RANDOM" | md5sum)"
  sleep 1800
done | tee /root/hijack-watch.log

观察多久算稳定,取决于 CDN 缓存 TTL 和站点更新频率,建议至少覆盖一个完整的缓存过期周期,通常不少于 24 小时;期间页面哈希除正常内容更新外不再突变,且日志里没有再出现此前的异常 POST,可以认为这一轮处理结束。

回滚办法要在动手前就准备好。改 nginx 配置前执行 cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%F),改完 nginx -t 通过再 nginx -s reload;判断改错了就 cp /etc/nginx/nginx.conf.bak.日期 /etc/nginx/nginx.conf,再 nginx -t && nginx -s reload。站点文件用前面那份 tar 快照还原,数据库用对应的 sql 快照导入。面板环境优先用面板自带的备份还原,回滚后同样按上面的三份哈希再核对一次。