WordPress被挂马实录:4分钟塞进5个后门,手机一打开就跳转

本站部分链接为联盟推广链接。通过这些链接购买,我可能获得佣金...

这不仅不会增加您的实际费用,通常还能让您享受到专属折扣。所有上榜推荐均基于真实项目环境下的自费实测,排名完全由客观测评数据决定。详细规则请查阅《免责声明》。

就在昨天有客户发来消息:”网站用手机打开会跳到乱七八糟的网站,电脑上又好好的。”

我用自己电脑点开,正常。换手机,关掉 WiFi 用流量,开无痕模式点进一篇文章,页面刚加载完,就被带去了别的网站。

这是一个用宝塔面板跑的 WordPress 游戏资源站,主题是 RiPro-V5 加一个定制子主题。下面是我从排查、取证到清理的完整过程,包括一开始走的弯路。如果你的站也有”手机跳恶意网站、电脑不跳”的症状,可以直接跳到后面的自查命令。

wordpress hacked cleanup cover 1

症状:电脑一切正常,手机一打开就跳

这类挂马最折磨人的地方,是站长自己几乎碰不到。

你用电脑登后台改文章,什么都看不出来。用手机打开,也可能不跳,因为很多跳转脚本会先判断”是不是第一次来””是不是从搜索引擎点进来””是不是管理员 IP”,满足条件才动手。我自己拿手机测的时候也是时灵时不灵:同一部手机,有时连开几篇都正常,有时点进去就被带走。

后来我在服务器日志里也看到了印证:用我自己的同一部 iPhone 打开某篇文章后,十几秒没有任何请求,接着以空白来路重新打开页面。这是典型的”被带走了,又自己点回来”。

我拿到的第一份文件,干净得反常

客户提供的面板的访问权限,我打包了整个网站目录和数据库。我做的第一件事,是拿 WordPress 官方 7.1.3 的源码,跟他的 wp-admin、wp-includes 逐个文件比对字节,结果全部一致。

插件也比对了,Wordfence、Sucuri 跟官方包一模一样。数据库全库检索 <script、eval(、location.href、atob( 这些特征,零命中。主题后台那个”网站底部自定义JS代码”的框,也是空的。

我又去服务器上看 Nginx 配置、Lua 模块、PHP 的 auto_prepend_file,全都正常。还做了一个很有用的测试:用手机 UA 和电脑 UA 分别去请求纯静态文件 readme.html,再和磁盘上的原文件对比,三个 md5 完全一样。这说明 Nginx 没有按设备往页面里塞东西。

nginx mobile ua md5 compare

查到这一步我其实有点慌。哪都干净,那跳转是从哪来的?

问题出在时间上。我把文件的修改时间排了一遍,发现有 3 个文件在客户联系我之前的几个小时里刚被改过,其中一个是子主题的 functions.php。再翻 Wordfence 的数据库记录,有个叫 File Manager Advanced 的插件”最近被停用”。

看起来,在我接手之前已经有人动手清过一轮,删了插件、改了文件,只是没清到根上。我拿到的,是一个被收拾过的现场,我问过客户才知道,他按照 AI 的提示自己进行过清理工作,不得不说这确实省去了我清理这些恶意文件的一些时间。

转机:一份”清理前”的备份

后来客户发给我了一份整站备份,打包时间比那次清理还早 3 分钟。

这份就不一样了。根目录一眼就多出两个 PHP 文件,按修改时间一排,整个入侵过程清清楚楚,前后只用了 4 分钟:

wordpress backdoor attack timeline

凌晨 4 点 36 分,攻击者在后台装了 File Manager Advanced。这个插件本身是正经插件,作者是 wpexpertsio,底层用的是 elFinder,能在 WP 后台直接浏览、上传、编辑服务器文件,官方介绍里还写着能访问 WordPress 根目录以外的文件。对攻击者来说,这就是一个现成的远程文件管理器。

装插件需要管理员权限。所以这里有个让人不舒服的推论:攻击者在 4:36 之前就已经能登录后台了,挂马只是收尾动作。

5 个后门分别藏在哪

wordpress malware file locations

两个放在根目录,名字一个随便取,一个故意起得像 WordPress 自带的 wp-activate.php。两个塞进了 wp-includes/block-bindings/,这是 WordPress 核心目录,很多人清理时根本不会往这里看。还有一个寄生在主题的 functions.php 末尾。

根目录还有个 .tmb 文件夹,这是 elFinder 生成缩略图用的。看到它,基本就能确定有人用文件管理器类插件操作过服务器。

Adszx.php:10 个管理员

这个文件只有 2.6KB,注释是印尼语,执行完会输出一句俄语”一切都已完成,安全!”,东拼西凑的味道很重。

它干的事情很简单粗暴:加载 wp-load.php,以 WordPress 的身份批量创建 adminisz1 到 adminisz10 共 10 个账号,全部设成管理员,共用一个写死在代码里的密码。注意,访问这个文件不需要任何登录,谁知道路径谁就能触发。

adszx hidden admin backdoor

真正阴的是第二步。它往当前主题的 functions.php 末尾追加了两段代码:一段挂在 pre_user_query 上,后台”用户”列表查询时自动排除这 10 个账号;另一段挂在 user_has_cap 上,任何人想删这 10 个账号,删除权限都会被直接改成 false。

结果就是:攻击者却握着 10 把备用钥匙。改密码?改的是你自己的。

正常情况下一个站该有几个管理员、各个角色能干什么,可以对照这篇 WordPress 五种用户角色的权限区别 看。被挂马的站,用户列表是不可信的,必须去数据库里查,命令我放在后面了。

剥了 16 层,才看到 WebShell 的真身

根目录另一个文件 wp-activajetbxzm.php 有 113KB,打开只有一行 eval(str_rot13(gzinflate(base64_decode("\x4a\x62..."))))。

我写了个小脚本做静态解码,不执行任何代码,一层一层剥。每一层的组合都不一样,base64、gzinflate、gzuncompress、rot13、字符串反转、URL 解码轮番上阵,一共 16 层。这么折腾只有一个目的:躲开按特征码扫描的安全插件。

webshell 16 layer obfuscation

剥到底,是一个标题叫”JKT48″的 WebShell。它有登录页,密码用 bcrypt 存;登录后能浏览、上传、编辑、删除服务器上的任意文件,还能改名、改权限、打包压缩。函数名全是印尼语,比如 tulisLah、faylSil、kunci。

说白了,攻击者给自己装了一个网页版的服务器文件管理后台,跟宝塔的”文件”菜单差不多好用。

混进 wp-includes 的另外两个

wp-includes/block-bindings/ 这个目录在 WordPress 7.1.3 官方包里只有 4 个文件:pattern-overrides.php、post-data.php、post-meta.php、term-data.php。备份里多了 connects.php 和 index.php。

connects.php 是一个叫”B3T4 Shell”的文件管理型后门。有意思的是,它开头还粘着一大段别人网站的 PHP 报错,里面有巴西某网站的服务器路径。攻击者大概是直接从另一个被黑的站上把输出复制了过来,连垃圾都没擦干净。index.php 则是又一个经过变量名混淆的 WebShell。

为什么藏在这?因为很多人清理挂马只盯着根目录和 uploads,不会想到去核心目录里数文件。你要是只把 WordPress”更新一下”,更新程序覆盖的是官方文件,多出来的文件它不管,后门照样活着。

那手机跳转到底是谁干的?

说实话,这个问题我到现在也没能抓到现场。

清理前的备份里,我把所有文件又搜了一遍跳转特征,没有。主题的核心文件和 translate.js,跟清理后的版本逐字节一致。数据库也是干净的。

真正让我确定方向的,是客户后来补的一句:”宝塔面板下的所有站点都会跳。”同一台服务器上另一个完全不是 WordPress 的站也中招了,那问题就不可能只出在某个 WordPress 文件里,而是在服务器这一层。

wordpress malware investigation layers

那些 WebShell 能读写服务器上的文件,攻击者完全有条件往系统层面继续渗透。具体用了什么手法往页面里注入跳转,我没能确认(不确定:重装前没有抓到注入时的进程和内存现场,只能根据”所有站点都跳、网站文件和配置都干净”推断)。

所以处理方案是:不在原系统上修修补补,直接重装系统,只迁移核实过的数据。服务器重装成了全新的 Debian,WordPress 核心和插件全部重新下载官方包,数据库只导入检查过的那一份。如果你也打算换机器,可以看看换一台干净的 VPS 时有哪些选择。

攻击者是怎么进后台的?

这一段我只能给出线索,给不了定论。

Wordfence 装上之后没几个小时,就记录到有个 IP 在一分钟内对 xmlrpc.php 连续登录失败 20 次被锁;还有带假 UA 的扫描器在全站各种目录里找 cache.php,这是在找别人留下的现成后门。

后台账号是被暴力破解的、密码在别处泄露了,还是从同服务器别的站横向过来的?日志不够,我不确定。能确定的只有一件事:攻击者在装插件之前就有管理员权限。所以清理之后,给登录页加上防暴力破解限制、关掉不用的 XML-RPC,比删后门更关键。那些乱扫路径的请求,也可以用 Nginx 规则直接挡在门外。

照着查你自己的站:6 条命令

下面的命令都在宝塔终端里执行,把 /www/wwwroot/你的站点 换成你自己的网站目录。全部是只读操作,不会改动任何文件。

1. 列出最近 30 天被改过的 PHP 文件

出现你没动过的文件要警惕,尤其是一堆文件集中在几分钟内被改。

2. 搜索常见后门特征

Wordfence 这类安全插件自己的特征库文件也可能被搜出来,要人工看一下。

3. 在数据库里查所有管理员(绕过后台的隐藏)

sql命令

在宝塔”数据库 → 管理”里执行。表前缀不是 wp_ 的话自己改。拿结果跟后台”用户”页面对比,数量对不上就有鬼。

4. 找文件管理器用过的痕迹

5. 核对 WordPress 核心文件

装了 WP-CLI 的话:

按官方文档,它会把核心文件跟 WordPress.org 的校验值比对,加上 --include-root 还会对根目录里不属于 WordPress 的文件发出警告。但它会不会报告 wp-includes 里多出来的文件,文档没写,我也没实测(不确定)。保险起见,我更推荐下载同版本的官方包,直接对比 wp-includes 目录的文件列表。

6. 测试服务器有没有按手机身份改页面

三个 md5 一样,说明服务器至少没在静态文件上做手脚;手机那行不一样,问题就在服务器层。

清理顺序别搞反

很多人一发现后门就急着删文件,结果删完没两天又中招。顺序很重要。

动手之前,先把整站文件和数据库完整备份一份留作证据,别在原件上动手。这次就是因为先清理、后排查,我拿到的第一份文件几乎没有证据价值。

接着处理 functions.php 末尾那段注入代码。顺序反过来会白忙:不先删这段,adminisz 账号在后台既看不见也删不掉。删掉之后回到后台,就能看到并删除这些账号了。

然后删除根目录和 wp-includes 里多出来的文件,删掉 File Manager Advanced 插件,再用官方包覆盖 WordPress 核心、主题和插件。

紧接着改掉所有凭据:所有管理员密码、数据库密码、宝塔面板密码、SSH 密码,再重新生成 wp-config.php 里的密钥。忘了密码进不去后台的话,可以直接在数据库里重置管理员密码。

如果像这次一样,同服务器其他站点也有异常,那就别在原系统上清了,直接重装。重装后可以在宝塔面板上重新装一遍 WordPress,再导入核实过的数据库和 uploads 目录。嫌麻烦也可以把站点完整搬到新服务器,但前提是搬过去的文件已经确认干净。

这次我学到的几件事

清理前先备份,这条我会一直跟客户强调。被收拾过的现场,等于把证据也一起扫走了。

WordPress 后台的用户列表不可信。 一个 pre_user_query 钩子就能让管理员凭空消失,查账号永远以数据库为准。

别在生产站上装文件管理类插件。 File Manager Advanced 本身没问题,但它太好用了,对攻击者也一样。真要在线改文件,就用宝塔自带的文件管理,至少多一层面板登录。

还有一个小插曲:Wordfence 扫描时报警,说 RiPro 主题的 template-assets.php 里有一个在它域名黑名单上的地址 cdn.bootcdn.net。这是主题内置的 CDN 选项之一,客户实际用的是”本地加载”,所以这次不是它的问题。但如果你的主题能选 BootCDN 加载 jQuery,建议改成本地加载。

自己维护服务器、自己扛安全,对很多做外贸或资源站的站长来说成本确实不低。如果你不想再折腾这些,托管型 WordPress 主机会帮你兜住系统层的安全更新和恶意软件扫描,代价是贵一些、自由度低一些,按自己情况选就好。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注


快捷菜单
WordPress 主机
VPS 主机
最新优惠
正版授权
VPS 补货监控