网站被挂马怎么彻底清理?一次真实排查与修复的完整记录

2025 年 11 月 8 日,一个客户发来消息,说百度搜索他网站的时候,标题下面多了一行灰字——”该网站可能包含恶意软件”。

我打开百度搜了一下,确实。那个标签像一块膏药一样贴在搜索结果里,谁看了都不敢点进去。

这不是小问题。百度给网站打上这个标签,意味着它已经检测到你的网站存在恶意代码。点击量直接腰斩都不止——用户看到这行字,你觉得有几个还敢点?我赶紧打开网站,页面看着一切正常。首页正常,文章页正常,后台也正常。没有弹窗,没有跳转,没有异常广告。但百度不会无缘无故给你贴标签——它一定是抓到了什么。


第一轮排查:表面什么都没发现

我先做了几个常规检查。

查首页源代码。 右键查看网页源代码,从头滚到尾。没有可疑的 <script> 标签,没有隐藏的 iframe,没有奇怪的 base64 编码字符串。看起来干干净净。

查 WordPress 插件。 后台插件列表,每一个我都认识。没有多出来的陌生插件,也没有被停用的插件重新启用。插件数量对得上,更新时间也正常。

查主题文件。 用宝塔面板的文件管理器,把主题目录翻了一遍。functions.php 没有异常代码,header.php 没有外链注入,footer.php 也没有被篡改的痕迹。

查最近修改的文件。 find /www/wwwroot/xxx -mtime -7 跑了一遍,看看最近一周有哪些文件被修改过。结果是正常的——只有我前两天更新的几篇文章的静态缓存文件。

到这里我有点懵。百度说你网站有恶意代码,但我把能查的地方都查了,什么都没找到。是不是百度误报?

我打开百度搜索资源平台,在”安全检测”里看了下详情。百度给出的检测时间是 2025 年 11 月 7 日晚上 23:41,检测类型是”恶意代码”,但没有给出具体位置。

也就是说,百度确实抓到了东西,但不知道它抓到的到底是什么、在哪个文件里。


第二轮排查:用扫描工具深挖

单靠肉眼和手工排查,大文件量根本不可能覆盖。一个 WordPress 网站 Core 文件就几百个,加上主题、插件、uploads,几千个文件,你不可能一个个打开看。这时候必须上工具。

我用的是 Wordfence 插件(免费版)。装上之后跑了一次全站扫描,等了大概 15 分钟,结果出来了:

  • 扫描了 5832 个文件
  • 发现 3 个可疑文件
  • 2 个在 /wp-includes/ 目录下,1 个在 /wp-content/uploads/ 目录下

Wordfence 标记这三个文件”包含恶意代码”,但没有说明具体是什么恶意代码。我点开文件详情,看到了被注入的代码。

第一个文件:/wp-includes/class-wp-query.php

这个文件是 WordPress 核心文件,但文件末尾多了 12 行代码。这 12 行代码做的事情是:判断访问者是否来自搜索引擎(通过 User-Agent 判断),如果是,就输出一段隐藏的 HTML,里面包含违规广告链接。这段链接对普通用户完全不可见(CSS display:none),但百度蜘蛛抓取的时候能看到——这就是百度检测到恶意代码的原因。

第二个文件:/wp-includes/class-wp-user.php

同样在文件末尾被追加了代码。这次是一个后门——攻击者可以通过特定的 URL 参数执行任意 PHP 代码。代码写得非常隐蔽,用了一串字符串拼接和 base64 解码来隐藏真实意图。如果不用工具扫描,我翻到这个地方大概率也会一扫而过,根本看不出问题。

第三个文件:/wp-content/uploads/2025/10/screenshot.png.php

看到这个文件名的时候,我整个人都不好了。文件名是 screenshot.png.php——一个伪装成 PNG 图片的 PHP 文件。打开之后发现是一个 webshell,功能齐全:文件浏览、数据库查询、命令执行,该有的都有。上传时间显示是 2025 年 10 月 23 日,也就是说它已经在服务器上躺了半个月了。

看到这里,我基本理清了攻击路径:攻击者通过某种方式上传了 webshell 到 uploads 目录,然后通过 webshell 修改了 WordPress 核心文件,注入了恶意代码和后门。整个过程没有任何明显的入侵痕迹——没有新增管理员账号、没有修改密码、没有大量异常请求。


清理:不是删了文件就完事

很多人以为找到恶意文件删掉就行了。删了确实能解决眼前的问题,但如果你不把入侵入口堵上,攻击者隔几天又回来了。我见过一个站,管理员删了三次恶意代码,攻击者又注入了三次。最后发现是攻击者留了一个隐蔽的后门——一个看起来完全正常的文件,里面藏了一行 eval(gzinflate(base64_decode(...))),每次管理员清理完,攻击者通过这个后门重新部署恶意代码。

所以我这次的清理步骤是这样的:

第一步:隔离网站。 先把网站设为维护模式,防止用户在清理过程中访问到恶意代码。同时备份当前网站——不是备份到恢复用,而是保留证据,万一后续需要分析攻击来源。

第二步:替换 WordPress 核心文件。 被感染的 wp-includes 目录下的文件,不要手动修改,直接从 WordPress 官网下载同版本的安装包,用官方文件整体替换 wp-includeswp-admin 目录。手动修改的风险是:你可能漏掉某个被感染的文件,或者没有完全清除注入的代码。官方替换是最干净的方式。

第三步:删除 webshell。 uploads 目录下的那个伪装 PHP 文件,直接删除。然后检查 uploads 目录里所有 .php 文件——正常来说 uploads 目录不应该有任何 PHP 文件,只有图片、PDF、压缩包等静态资源。找到一个删一个。

第四步:全站扫描第二次。 清理完之后,用 Wordfence 再跑一次扫描,确认没有遗漏。这次扫描结果干净了。

第五步:变更所有密码。 这是最容易被跳过的一步。WordPress 管理员密码、FTP 密码、数据库密码、宝塔面板密码——全部改掉。密码强度至少 16 位,大小写字母 + 数字 + 特殊字符混合。别用生日、手机号、公司名这类容易被猜到的弱密码。

第六步:排查入侵入口。 这是最头疼的一步,也是最关键的一步。攻击者是怎么把 webshell 上传到 uploads 目录的?我排查了以下几种可能:

  • 插件漏洞。 检查了所有插件的版本和已知漏洞。有一个图片压缩插件,版本是 2.1.3,而这个版本在 2025 年 8 月爆出了一个文件上传漏洞(CVE 编号就不列了,感兴趣自己搜)。漏洞允许攻击者绕过文件类型检查,上传 PHP 文件到 uploads 目录。这大概率就是入口。
  • 主题漏洞。 主题用的是正版 GeneratePress,版本也是最新的,基本排除。
  • 弱密码爆破。 查了服务器登录日志,没有异常的登录尝试,排除。
  • 服务器层面的漏洞。 宝塔面板和服务器系统都是最新版,排除。

确定入口之后,我把那个图片压缩插件直接卸载了,换了一个功能类似的替代品。不只是更新——直接卸载。一个插件如果爆过文件上传漏洞,我不会再信任它的后续版本。谁知道开发者有没有彻底修好?

第七步:加固安全。 清理完之后,做了几件事防止再次被黑:

  • 在 WordPress 的 wp-config.php 里加了 define('DISALLOW_FILE_EDIT', true);,禁止后台编辑主题和插件文件。即使攻击者拿到了管理员权限,也不能通过后台修改文件。
  • .htaccess 里加了规则,禁止直接访问 wp-content/uploads/ 目录下的 .php 文件。
  • 装了 Wordfence 的防火墙功能,开启了实时流量监控。

后续:百度标签怎么去掉

清理完恶意代码之后,百度那个”该网站可能包含恶意软件”的标签不会自动消失。你需要主动去百度搜索资源平台申诉。

在”安全检测”页面,点击”申请复查”。百度会重新抓取你的网站,确认没有恶意代码之后,标签会在 1-3 天内去掉。我在 11 月 9 日提交的申请,11 月 11 日下午标签就撤了。

另外,如果你网站之前被百度降权了(因为恶意代码被检测到),清理之后排名恢复需要时间。我的经验是短则一周,长则一个月,取决于你网站原来的权重。这个客户网站清理之后大概两周,排名基本回到了被挂马之前的水平。


一些你可能想知道的

问:为什么会被挂马?

绝大多数情况是三个原因:插件有漏洞(最常见)、主题有漏洞、密码太弱被暴力破解。三者里插件漏洞占了大头——WordPress 生态太开放,插件质量参差不齐,一个小众插件的安全漏洞可能几个月都没人发现。

问:怎么知道网站有没有被挂马?

三个信号:百度搜索结果里出现安全警告(最明显)、网站访问量突然大幅下降(因为百度降权了)、网站莫名变慢或者出现奇怪的 JS 报错。定期用 Wordfence 或 Sucuri 做全站扫描,别等出事了再查。

问:除了 Wordfence,还有什么工具可以用?

Sucuri 的在线扫描(sitecheck.sucuri.net)可以用来快速检查网站有没有被列入黑名单。Wordfence 适合深度扫描和实时防护。如果是服务器层面的排查,可以用 rkhunterchkrootkit 检查有没有 rootkit。我之前写过一篇在线网站检测工具推荐,里面列了更多工具,可以对照着用。

问:被挂马之后,备份还能用吗?

得看情况。如果你的备份是在被挂马之前做的,那可以直接恢复。但如果备份里也包含了恶意代码(比如你已经带着恶意代码运行了好几天,自动备份把恶意代码也备进去了),那恢复备份等于是把恶意代码重新部署了一遍。所以清理完恶意代码之后,建议做一次全新的备份,替代旧的。


这件事之后,我给自己定了一个规矩:每个客户的网站,装完插件之后定期检查更新,有安全漏洞的插件立刻换掉。不是等客户来找我”网站出问题了”,而是我自己主动去查。因为挂马这种事,等到你发现的时候,损失已经造成了——排名掉了、用户跑了、百度标签贴上了。

来自 wujianzhan.com,一个分享建站与 SEO 实战的博客。