网站突然变慢还弹广告?我花了一下午排查出这些安全隐患

事情是这样的。

去年有个周五下午,我打开自己的网站,首页加载了快十秒。一开始以为是服务器抽风——毕竟用的便宜主机,偶尔卡一下也正常。刷新了几次,还是慢。然后诡异的事情来了:页面右下角弹了一个违规广告。

我第一反应是——中病毒了?不对,我用的 Mac,而且其他网站都正常,就我自己的站弹广告。emmm,这真是网站被挂马了。

说实话,当时脑子里闪过一堆念头:数据库被拖了?后台密码泄露了?插件有漏洞?搞了三年建站,第一次遇到这种事,说实话,有点慌。

但慌没用。我花了整整一个下午,从一头雾水到最终定位到问题,中间踩了不少坑。这篇文章把当时整个排查过程还原出来——如果你哪天发现自己的网站也”不对劲”,可以照着这个思路走一遍。


症状出现了:先别急着动手,把异常记下来

很多人发现网站出问题,第一反应就是冲进后台一顿乱改。千万别。

我当时做的第一件事,是打开一个空白文档,把看到的所有异常记下来:

  • 首页加载时间从平时的 2 秒变成了 8-10 秒
  • 页面右下角出现弹窗广告(刷新后偶现,不是每次都弹)
  • 网站底部多了一行莫名其妙的隐藏链接(查看源代码才看到)
  • 百度统计里出现了一个来路不明的陌生域名

这四个症状摆在一起,基本可以确定:不是服务器问题,是被挂马了。 服务器抽风不会无缘无故多出隐藏链接和弹窗广告。

我先把网站切成了维护模式——WordPress 装个 WP Maintenance Mode 插件,或者直接在 functions.php 里加几行代码就行。这一步是防止访客在不知情的情况下中招,也避免百度蜘蛛爬到被污染的页面。


排查第一步:看源代码,别只看页面

很多人只看浏览器里渲染出来的页面,觉得没啥问题就过了。大错特错。

挂马的人不傻,他加的恶意代码往往会用 JS 动态加载,或者藏在页面底部肉眼看不到的地方。你直接看网页是看不到的。

我当时的做法:打开网站首页,右键 → 查看网页源代码,然后 Ctrl+F 搜索这几个关键词:

  • <script —— 看有没有不认识的 JS 引用
  • eval( —— 混淆代码的标配,正常网站几乎不会出现
  • iframe —— 挂马最爱用的标签
  • display:none —— 隐藏元素

搜到第三个关键词就出问题了。在源代码最底部,</html> 标签前面,多了这么一段:

<div style="display:none">
<a href="https://xxx-spam-xxx.com">违规广告</a>
<a href="https://xxx-spam-xxx.com">违规广告</a>
</div>

就是这玩意儿。隐藏链接,搜索引擎能看到,用户看不到,典型的黑帽 SEO 挂马手法。攻击者在你网站上挂他的链接,蹭你的权重给他的垃圾站引流。恶心吧?

这里有个细节:光看首页不够,多抽查几个页面。 我当时随机点了五六篇文章,发现有两篇也被塞了类似的隐藏链接,另外几篇是干净的。这说明攻击不是全局性的——可能是某个插件或主题文件被修改了。


排查第二步:扫文件修改时间,锁定可疑文件

知道是文件被篡改了,下一步就是定位哪些文件被改过。

我连上服务器,用了一条命令:

find /www/wwwroot/你的网站目录 -type f -mtime -7 -ls

这条命令的意思是:列出最近 7 天内被修改过的所有文件,按时间排序。

跑出来的结果让我倒吸一口凉气。最近一天内被修改的文件有二三十个,大部分集中在 wp-content/uploads/ 目录下。uploads 目录按理说只应该放图片和附件,这里面却多了几个 .php 文件。

点进去一看,文件名伪装得很像正常文件:wp-config-simple.phpclass-wp-links.php。打开一看,里面全是混淆过的 PHP 代码,一眼就能认出是 webshell(一句话木马)。

后来查资料才知道,攻击者是通过一个我装了但半年没更新的图片压缩插件搞进来的。那个插件有个文件上传漏洞,允许未经身份验证的用户上传任意文件到 uploads 目录——而我服务器上 PHP 的执行权限没有对 uploads 目录做限制,上传的 PHP 文件直接就能跑。

教训太深刻了。 两个问题同时存在:插件有漏洞 + 服务器权限配置太宽松。任何一个单独存在都不至于被拿下,两个凑一起就给了攻击者完整的一条龙服务。


排查第三步:检查是否有未知管理员账户

文件被改了,还得确认一下后台有没有被留后门。

我进 WordPress 后台 → 用户 → 所有用户,把所有账户扫了一遍。一开始没发现异常,就我一个管理员账户。但仔细一看,有个用户名叫 “wpadmin” 的账户,角色是”订阅者”。

“订阅者”看起来没有权限,但这不对劲。我从来没创建过这个账户。

后来我在 wp-admin/includes/user.php 的搜索结果里看到,有人提到攻击者会先创建一个低权限账户占坑,等过段时间再用提权漏洞把角色改成管理员。这个”订阅者”账户,就是一颗定时炸弹。

我立刻删掉了这个账户。然后去数据库里跑了一条查询:

SELECT * FROM wp_users WHERE user_login NOT IN ('你的管理员用户名');

确认没有其他异常账户后,才稍微放心一点。

这里顺便说一句: 如果你用的是默认的 “admin” 作为管理员用户名,赶紧改。攻击者爆破登录的时候,第一个试的就是 admin。不知道有多少站就是这么被拿下的。


排查第四步:检查 wp-config.php 和 .htaccess

这两个文件是 WordPress 的核心,一旦被改,攻击者可以做的事情多了去了——重定向流量、劫持后台、甚至直接操作数据库。

打开 wp-config.php,从头到尾看了一遍。表面上看起来一切正常,但我在文件末尾发现了一行:

@include_once(ABSPATH . 'wp-content/uploads/wp-config-simple.php');

就是前面在 uploads 目录里发现的 webshell 文件,通过 wp-config.php 被自动加载了。每次有人访问网站,这个恶意文件就会执行一次。

删掉这行,再把那个 webshell 文件删掉。

然后是 .htaccess。这玩意儿更容易被忽略——很多人装完就再也没打开过。我用 grep 搜了一下有没有异常的重定向规则:

grep -n "RewriteRule\|Redirect\|ErrorDocument" .htaccess

果然,在文件的最后几行,多了一条指向违规广告站的 301 重定向规则,只对来自搜索引擎的流量生效。这就是为什么我自己访问的时候偶尔弹广告,但从百度搜进来的用户看到的却是违规广告页面——攻击者通过 UA 判断流量来源,精准投放。

这招很阴。 你自己访问网站看起来一切正常,所以根本不会发现异常。等你从百度统计里看到流量暴跌,都过去好几天了。


排查第五步:用在线工具做自动化扫描

手动排查到这一步,能发现的漏洞基本都找到了。但人的眼睛会漏,尤其是混淆加密过的恶意代码,藏在几千行文件里根本看不出来。

我用了两个免费工具做自动化扫描:

第一个,Sucuri SiteCheck。 网址是 sitecheck.sucuri.net,免费在线扫,不需要注册。输入域名,它会自动扫描网站有没有已知的恶意软件、黑名单状态、异常重定向等。扫出来我的站被标记为”Medium Risk”,列出了几个可疑文件路径,跟我手动排查的结果基本一致。

第二个,Wordfence 插件。 装完后跑一次全站扫描,它会逐个文件比对 WordPress 官方仓库的原始版本,标记出所有被修改过的核心文件、主题文件和插件文件。这个功能实在太实用了——我手动排查花了三个小时,它扫描十分钟就定位到了所有异常文件,包括三个我漏掉的。

有个小插曲:Wordfence 扫描的时候,服务器 CPU 飙到了 90%。因为它要遍历所有文件做哈希比对,很吃资源。建议在凌晨访问量低的时候跑扫描,扫完就停掉,别让它在后台一直跑。


清理完了,然后呢?

找到问题、删掉恶意文件、清理数据库,这只是第一步。更关键的是堵住漏洞,别让攻击者再来一次。

我当时做了这几件事:

更新所有东西。 WordPress 核心、主题、所有插件,全部更新到最新版本。那个被利用的图片压缩插件,直接删了,换了个还在维护的替代品。说真的,插件半年没更新还在用,就是给自己埋雷。

限制 uploads 目录的 PHP 执行权限。 在 uploads 目录下放一个 .htaccess 文件,内容是:

<FilesMatch "\.(php|php\.|phtml)$">
    Require all denied
</FilesMatch>

这样就算攻击者上传了 PHP 文件到 uploads 目录,也执行不了。这一步我后悔没早点做——太基础了,但就是很多人不知道。

修改所有密码。 数据库密码、FTP 密码、WordPress 管理员密码,全部换了一遍。顺便把 WordPress 安全密钥(在 wp-config.php 里那四行 AUTH_KEY 开头的)也重新生成了一套——WordPress 官网有个在线生成器,搜”WordPress salt key”就能找到。

装了 Wordfence 防火墙。 免费版够用了,主要开两个功能:登录暴力破解防护(限制登录失败次数)和 Web 应用防火墙(拦截常见的攻击请求)。开完之后,Wordfence 的日志里天天能看到一堆被拦截的恶意请求——大部分是自动化扫描工具在批量扫漏洞,不是针对我,但没人拦着就全进来了。

设置自动备份。 之前觉得备份麻烦,一直没搞。这次差点翻车,如果攻击者删了数据库,我的站就没了。后来装了 UpdraftPlus,每周自动备份到远程存储(我用的是百度网盘,免费的有 2TB 空间,够用了),出问题随时能恢复。


写在最后

说句掏心窝子的话:个人站长搞安全,不需要成为安全专家,不需要花钱买企业级防护,甚至不需要懂太多技术细节。真正要做的,就是把几件基础的事做到位:

插件保持更新、不用来路不明的主题和插件、限制文件上传权限、装个防火墙插件、定期备份。就这五件事,能做到的,已经能挡住 90% 以上的攻击了。

大多数攻击者不是针对你个人来的。他们用的是自动化扫描工具,批量扫互联网上所有 WordPress 站点,谁有漏洞就顺手拿下。你只要比旁边那个站多一层防护,他就去搞别人了。搞安全这件事,不需要跑得比熊快,跑得比旁边的人快就行。

如果你发现网站有异常,或者想排查一下安全隐患但不知道从哪下手,欢迎联系我。毕竟我自己也是从”被挂马”这件事开始,才真正重视起网站安全的。


本文由 wujianzhan.com 原创发布,如需转载请联系作者。

有建站或安全方面的问题?点这里联系我,一起交流。