今天晚上八点多,我随手打开了一下博客,发现网站打不开了,直接报 500 错误。

我开始以为只是 Hostinger 宕机,但邮箱里没有收到任何故障通知。登录 Hostinger 后台检查了一下,AI 助手提示网站里可能有恶意文件。

网站被黑以及恢复记录 - 截图 1

一开始我也没太当回事,因为 Hostinger 以前也扫描出过一些所谓的恶意文件,后来确认只是误报。

但我顺手检查了同一个账户里的其他网站,很快发现这次不一样。其中一个网站的首页已经被替换成黑色页面,上面写着:

HACKED BY MR.DOMSVG
THIS WEBSITE HAS BEEN LOCKED


网站被黑以及恢复记录 - 截图 2

我再进入 Hostinger 文件管理器,随便打开一个 PHP 文件,文件最前面已经被连续写入大量内容:

<?php /* DOMSVG WORM */ ?>
<?php /* DOMSVG WORM */ ?>
<?php /* DOMSVG WORM */ ?>
......


这时基本可以确认,不是普通的 WordPress 500 错误,而是网站文件被批量篡改了。

恢复每日备份,为什么还是不行


Hostinger 上有每天的备份,所以我最先做的事情就是恢复备份。因为第一次感染的时间是7月29日,所以我恢复了7月28日的备份。

但恢复完成以后,网站仍然不正常。

这一步让我意识到一个问题:如果旧主机环境里还有残留文件、后门、异常定时任务,或者同一账户中的其他站点仍然被感染,那么把一份正常备份恢复回原处,并不代表问题已经结束。恢复出来的文件还有可能再次被改写。

我能确认的是,同一个旧主机账户里的多个网站文件都受到了污染。但仅凭这些现象,还不能断言 Hostinger 的物理服务器被攻击。更准确的说法是:**旧托管环境已经不适合继续作为紧急恢复的落点。**

所以我没有继续在旧主机里反复恢复,而是决定先准备一个新的环境。

先检查备份有没有明显感染标记


我把 7 月 28 日左右的网站文件备份和 SQL 数据库备份下载到本地,解压后搜索这次已经发现的攻击标记。

四份备份加起来大约检查了 1.5 万个 PHP 文件,没有发现这些内容:

- DOMSVG WORM
- MR.DOMSVG
- HACKED BY MR.DOMSVG
- 常见的 eval(base64_decode(...))
- 常见的 gzinflate(base64_decode(...))
- 可疑的 auto_prepend_file

uploads 目录里也没有发现异常 PHP 脚本,.htaccess 基本都是常见的 WordPress 和 LiteSpeed 规则。

不过,这个结果只能说明没有扫到这次已经见过的感染标记和几类常见特征,并不能证明备份百分之百安全。

就算备份能在本地 WordPress 或新主机上正常运行,也只能证明它可以运行,不能等同于“里面一定没有后门”。

最后是怎么恢复成功的


当时我首先考虑的是尽快恢复网站访问。

所以我用一个新账号又买了一台 Hostinger 主机。这样操作界面和恢复流程都比较熟悉,也不用在网站全部离线的时候临时研究 VPS 运维。

我先把其中一个网站的备份上传到新主机,使用 Hostinger 提供的临时域名测试。结果网站可以正常运行,这至少证明 7 月 28 日的备份是可用的。

与此同时,我让 Codex 帮我分析还有没有更快的恢复办法。它给出的建议是:不要继续直接覆盖已经被感染的文件,而是先清空原账户中文件管理器里的网站文件,重新安装 WordPress,再恢复数据库和备份中的网站内容。

最后我并没有把正式网站迁移到新买的 Hostinger 账户,而是直接在原来的账户中处理:

1. 清空对应网站文件管理器中的文件。
2. 重新安装一套 WordPress。
3. 恢复备份中的主题、插件、上传文件和配置文件。
4. 检查数据库,没有发现明显的篡改迹象,因此继续使用原数据库。
5. 检查首页、文章页、图片、后台登录和固定链接。

处理完成后,网站恢复正常。

随后我用同样的方法处理其他网站,最后所有网站都恢复了访问。

这次真正起作用的不是单纯点击“恢复备份”,而是先把已经被污染的网站文件清空,重新安装 WordPress,再从感染前的备份中恢复需要的文件。

这次救了我的,又是每日备份


这次有几个东西非常关键。

第一个还是每天备份。

如果没有感染前的网站文件和数据库备份,我就只能一边清理被改写的 PHP 文件,一边猜还有没有漏掉的文件,恢复时间会长很多。

第二个是新主机提供了一个测试环境。

虽然最后没有把网站正式迁移过去,但我先在新账号里上传备份,并通过临时域名确认网站能够运行。这样我才敢回到原账户,清空文件后重新安装。

第三个是临时域名。

正式域名当时还绑定在旧 Hostinger 账户,添加到新账户时会提示 Already used at Hostinger。先用临时域名测试,就不用为了验证备份而提前切换域名,也减少了恢复过程中的不确定性。

网站恢复,不等于事情结束


现在所有网站都已经恢复访问,但我不会把“能打开”当成“已经彻底安全”。

接下来还需要做这些事情:

1. 更换 Hostinger、邮箱、域名、Cloudflare、WordPress 管理员、SFTP/SSH 和数据库密码。
2. 给所有关键账户开启两步验证。
3. 检查 WordPress 管理员账号、应用程序密码和异常定时任务。
4. 从可信来源重新安装或更新 WordPress 核心、主题和插件,删除停用及来路不明的组件。
5. 检查数据库中的 wp_users、wp_usermeta 和 wp_options。主机的恶意软件扫描通常主要检查文件,不能代替数据库检查。
6. 继续保留每日主机备份,同时增加每周异地备份,并保留 30—60 天。
7. 监控 500 错误、首页内容变化、新管理员账号,以及 uploads 目录里新出现的 PHP 文件。

如果服务器支持 WP-CLI,也可以先校验 WordPress 核心和来自 WordPress.org 的插件文件:

wp core verify-checksums --include-root
wp plugin verify-checksums --all --strict


然后在 wp-config.php 中关闭后台主题和插件文件编辑:

define('DISALLOW_FILE_EDIT', true);


WordPress 官方有一份比较完整的安全加固文档。Hostinger 也提供了网站被黑后的处理说明恶意软件扫描工具说明

不过经历这次事情以后,我最想做的还是逐步把博客从 WordPress 迁出去。

现在 AI 写代码已经很方便了。以后完全可以让 AI 帮我做一个静态博客,文章直接保存成 Markdown 文件。更新内容时改一下 .md 文档再发布,不需要一直维护 WordPress、PHP、数据库、主题和一堆插件。

当然,静态网站也不是绝对安全,但至少攻击面会小很多,迁移和备份也更简单。

这次总算把所有网站都救了回来。每天备份平时看不出有什么价值,真正出事的时候,它可能就是几个小时恢复和彻底重做之间的区别。

5/5 - (3 votes)