首页 · 技术

WordPress 站点遭遇 XML-RPC 暴力破解:一次安全事件的完整复盘

背景

2026 年 8 月 11 日,我的 WordPress 站点被发现多了 6 篇不是我发布的文章——内容全是盗版软件、影视资源的推广链接。这不是一次复杂的 0day 攻击,而是利用 WordPress 一个默认开启但常被忽视的接口:XML-RPC。本文记录了完整的攻击过程、取证方法和处置措施,希望能给同样使用 WordPress 的站长提供参考。

事件发现

当天下午,我登录后台时注意到文章列表中出现了 6 篇异常文章,作者显示为管理员账号。内容均为盗版 Crack / RePack / WEBRip 推广,夹杂随机字符串(如 a67zj9vwtkqymy9txui3hf1b,这是自动化 SEO 验证的典型特征)。我自己的 5 篇真实文章未被改动。

攻击时间线

时间 事件
站点部署日 部署 WordPress,安全配置为默认状态(XML-RPC 开启、密码可预测)
部署后数日 攻击者持续探测,xmlrpc.php 累计被请求 1480 次
事发日 06:43 第一批垃圾文章注入(2 篇)
事发日 09:43 第二批(2 篇)
事发日 12:44 第三批(2 篇)——每批间隔约 3 小时,符合自动化脚本特征
事发日 14:49 我发现异常,开始排查处置

攻击过程分析

经过日志审计,还原出以下攻击链:

① 端口探测 / 指纹识别
   └─ 识别目标为 WordPress(通过响应头、/wp-login.php 等特征)

② 选定薄弱入口:XML-RPC 接口(/xmlrpc.php)
   ├─ WordPress 默认启用该接口
   ├─ 支持 system.multicall:单次 HTTP 请求可批量尝试数百组凭证
   └─ 完全绕过 wp-login.php 的登录失败限制

③ 凭证破解
   └─ 原密码为「站点名+年份+感叹号」模式,属于字典攻击高优先级条目

④ 利用管理员权限注入内容
   └─ 通过 XML-RPC 的 wp.newPost 方法批量创建文章
      (不走浏览器后台,因此后台操作日志无痕迹)

⑤ 目标:SEO 劫持 / 内容农场推广

攻击者为什么选择 XML-RPC?因为它有两个”免费午餐”:无失败次数限制 + 绕过常规访问日志。这正是 WordPress 垃圾文章注入的经典攻击路径——system.multicall 允许在单次 HTTP 请求中批量尝试数百组凭证,而 WordPress 内置的登录防爆破机制仅保护 /wp-login.php 页面,对 XML-RPC 接口完全不生效。

取证过程

我从五个层面进行了审计:

文章层

6 篇垃圾文章(盗版资源推广),真实文章 5 篇未被动。

账号层

用户表仅 1 个管理员账号,无新增用户、无提权痕迹,排除”新建后门账号”模式。

文件层

  • wp-config.php 修改时间为部署日,未被篡改
  • 主题目录所有文件修改时间均在部署窗口内,无新近后门
  • wp-content/uploads/ 下 0 个 .php 文件,无 webshell

日志层(关键证据)

  • xmlrpc.php 请求计数:1480 条(攻击通道直接证据)
  • REST API POST 记录:0 条——佐证文章非通过 REST 创建
  • 后台 post.php POST 记录:0 条——佐证文章非通过浏览器后台创建

以上两者为零 + XML-RPC 高计数,形成完整证据闭环。

计划任务层

wp_options.cron 共 16 个任务,全部为 WP 核心 / 已知插件的正常任务,无恶意定时任务。

处置措施

# 措施 方式
1 下架垃圾文章 6 篇移入回收站 → 确认后永久删除
2 封堵 XML-RPC 通道(双重) ① 主题层:add_filter('xmlrpc_enabled','__return_false') + 移除 X-Pingback 头
② Nginx 层:location = /xmlrpc.php { return 403; }
3 更换管理员密码 强随机 16 位密码
4 清除全部登录会话 攻击者既有会话立即失效
5 安装登录限速插件 Limit Login Attempts Reloaded(失败 4 次锁定 20 分钟)
6 清理缓存 确保封堵即时生效

根因分析

根因 说明
XML-RPC 默认开启且无防护 WordPress 默认启用该接口,无失败次数限制,部署时未关闭
密码模式可预测 「站点名+年份+感叹号」模式,字典攻击高优先级命中
缺乏登录监控 无登录失败告警/日志插件,攻击过程不可见

核心结论:本次事件属于”可预防的配置型漏洞被自动化攻击命中”,非 0day 或源码级漏洞。攻击者不需要高超技术——1480 次请求 + 可预测密码 = 破解成功。这说明 WordPress 默认配置的安全性不足,站长必须在部署后主动加固。

后续加固建议

优先级 措施 说明
P0 初始密码立即改为强随机密码 禁用「站点名+年份」等可预测模式
P0 关闭或限制 XML-RPC 如果不用博客客户端/Trackback,直接 Nginx 层 403
P1 安装登录限速插件 Limit Login Attempts Reloaded 或类似插件
P1 配置自动备份 每日备份 + 本地保留多份,防内容丢失
P2 关闭/停用不需要的插件 减少攻击面
P3 迁移管理员登录路径 自定义登录地址,降低被探测概率

经验教训

  1. 部署 WordPress 的安全基线:初始密码必须强随机;XML-RPC 默认关闭或加 Nginx 层拒绝;安装登录限速插件。这三件事应该在部署当天就完成,而不是等到被攻击后才补。
  2. 密码纪律:任何系统密码禁用可预测模式;不同系统使用不同密码。1480 次请求就破解成功,说明密码强度是第一道也是最关键的一道防线。
  3. 部署纪律:所有脚本内嵌代码(PHP/Shell)修改生产文件前,必须先做语法验证再上线——本次处置过程中,因脚本变量转义错误曾造成全站短暂 500,属于”处置时自伤”,值得警惕。
  4. 监控意识:即使是小站点也需关注异常内容。攻击自动化程度极高,从探测到注入完全无人值守,发现越早损失越小。

写在最后

这次事件没有造成数据泄露或不可逆损失,6 篇垃圾文章删除后站点恢复正常。但它提醒了一个事实:WordPress 的默认配置是为兼容性而非安全性优化的。作为站长,我们需要在部署的第一天就主动加固,而不是依赖”我的站点太小没人会攻击”的侥幸心理。

如果你也使用 WordPress,建议现在就去检查:xmlrpc.php 是否可访问、管理员密码是否足够强、是否安装了登录限速插件。三分钟的自查,可能省去三个小时的应急处置。

100%