搜索全站
安全防护 11 分钟阅读

WordPress 插件安全审计:30 分钟自己过一遍代码的自查清单

不敢随便装第三方插件?本文给一套 30 分钟可完成的人工审计流程:危险函数扫描、可疑行为清单、更新源核验与官方工具用法,附可直接运行的命令行脚本。

U
UFO_PF 2019-09-01 · 阅读 11 分钟
Wo 安全防护
阅读提示
本文约 4,062 字,预计阅读 11 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:你装的不只是功能,还有执行权限

WordPress 插件运行在 Web 服务器进程里,和核心拥有同样的文件系统权限。这意味着一个写得随意的插件,理论上可以读你的 wp-config.php、往任何目录写文件、给任意用户提权。绝大多数插件作者是尽责的,但市场上确实存在三类高风险来源:作者放弃维护后被他人接手并植入代码的包、第三方站点二次打包的“专业版”、以及一些号称能解锁付费功能的 nulled(破解)版本。

现实困境是,绝大多数站长不可能逐行读完一个十万行插件的代码。可行的做法是做定向审计:不追求读完,而是把注意力集中在攻击者必然会接触的几个地方——危险函数、动态执行、外部通信、提权接口、更新机制。这几处如果干净,插件的风险面就收敛了一大截。

本文的流程不需要你懂全部 PHP,命令行操作和文本搜索为主,配合几个官方/社区工具,30 分钟可以过完一个常规插件。从第三方渠道下载插件的安全核验会补充下载前的验证环节,本文聚焦拿到代码之后的部分。

原理分析:恶意代码通常躲在哪

审计目标 典型手法 为什么危险
动态执行 eval、assert、create_function、preg_replace 带 /e 把字符串当代码跑,可以任意变形
混淆隐藏 base64_decode、str_rot13、gzinflate、str_replace 拼接 绕过肉眼和简单关键字扫描
远程通信 wp_remote_post 到陌生域名、curl 请求 传输站点数据、接收远程指令
文件系统 file_put_contents、move_uploaded_file、fopen 写 PHP 落地 Webshell,二次入侵
权限变更 wp_insert_user 赋予 administrator、update_option('users_can_register') 悄悄开后门账号
隐藏自身 在 option 里删配置、钩子注册后 remove_action 自己的菜单 后台看不见,但代码还在跑

需要强调一点:base64_decode 这类函数本身不是恶意的,很多正常插件用它处理图片或 API 数据。审计看的是组合:base64_decode 紧跟 eval/assert,或者解码结果直接进 call_user_func / $func(...) 变量函数调用,这种行为基本没有正当理由。

另外容易被忽视的还有 register_activation_hook 和 $wpdb->query 里直接拼接 $_GET/$_POST 的写法——前者可能被用来在安装时植入持久数据,后者是典型的 SQL 注入点。

保姆级实操

第一步:确认来源与完整性。

# 官方源下载插件并核对基本信息(版本号应与官方页面一致)
wp plugin install duplicate-post --dry-run

# 若已有本地包,先核对文件总数与首层结构
ls -la wp-content/plugins/目标插件/
find wp-content/plugins/目标插件/ -type f | wc -l

然后核对主文件头部的版本号、插件 URI 是否与官方目录条目一致。版本对不上、README 缺失、目录里多出 core.php、libs/system.php 这类与主功能无关的文件,都应提高警惕。

第二步:扫描高危关键字。

cd wp-content/plugins/目标插件/

grep -rn "eval(\|assert(\|create_function\|system(\|exec(\|passthru(\|shell_exec(\|popen(\|proc_open" --include="*.php" .

grep -rn "base64_decode\|gzinflate\|str_rot13\|convert_uudecode\|gzuncompress" --include="*.php" .

grep -rn '\$[a-zA-Z_]\{1,20\}(\$\?[a-zA-Z_]' --include="*.php" . | head -40

第三条命令是找变量函数调用($callback( $arg ))这种常用绕过手法,命中后需要人工看上下文。

第三步:查外部通信目标。

grep -rEn "wp_remote_(get|post|request)|curl_|fsockopen|stream_socket_client" --include="*.php" . | head -40

# 把所有出现的域名抽出来,逐个判断归属
grep -rhoE "https?://[a-zA-Z0-9.-]+" --include="*.php" . | sort -u | head -60

把抽出的域名逐个查 WHOIS 与所属关系。指向短链服务、无名 VPS、或近期注册域名的请求尤其可疑。

第四步:检查是否偷偷创建管理员或改权限。

grep -rn "wp_insert_user\|wp_update_user\|add_role\|set_role\|capabilities" --include="*.php" . | head -20
grep -rn "users_can_register\|default_role" --include="*.php" . | head -10

正常情况下只有少数会员类插件会出现这类调用,普通工具类插件出现就要读一下上下文。

第五步:看有没有把用户输入直接拼进 SQL。

grep -rnE "\\\$wpdb->(query|get_results|get_var|get_row|get_col)\(.*(\\\$_GET|\\\$_POST|\\\$_REQUEST|\\\$_SERVER)" --include="*.php" .

命中位置应确认是否使用了 $wpdb->prepare()。没有 prepare 的直接拼接是可利用的注入点。

第六步:用官方/社区工具交叉验证。

# WPScan:检查已安装插件是否存在已知漏洞
wpscan --url https://example.com --enumerate vp --plugins-detection aggressive

# Plugin Check(PCP):WordPress 官方出品的检查插件,可命令行运行
wp plugin install plugin-check --activate
wp plugin check 目标插件/目标插件.php --format=table

第七步:看代码是否混淆。

# 找出单行超长、变量名为随机串、无换行的可疑文件
awk 'length > 2000 {print FILENAME": "FNR" 行长度="length}' $(find . -name "*.php") | head -20

一行几千字符的 PHP 文件、变量名全是 $a1b2 这类无意义字符串,几乎可以确定是混淆代码。

常见踩坑

  1. 看到 base64_decode 就报警。正常插件处理图片、Google API 数据常用它。看它后面跟着什么才是关键。
  2. 只在启用后才开始查。恶意代码常在 register_activation_hook 或主文件顶层作用域里跑,审查阶段只要读了文件就应当扫一遍,不用等激活。
  3. 忽略 .php 之外的文件。.phtml、.inc、只含 PHP 代码的 .txt 都可能被执行或被 include。
  4. 以为免费版没风险、付费版才危险。2021 年就有多个付费插件被曝供应链投毒,价格不是安全背书。
  5. 不检查更新机制。有些插件自己实现远程更新,把ZIP包地址写死在私有域名上,这类 bypass 了官方审核机制,风险显著更高。
  6. 只查一次。插件每次更新都应复查——接受CVE 补丁的同时也可能引入新风险。建议把上面的 grep 脚本固化成一个 shell 脚本,更新后跑一遍。
  7. 案例:某企业站点用了某款第三方下载站的“商业版缓存插件”,运行半年一切正常,直到搜索引擎把它标为风险站点。审计发现插件根目录多出一个 license.php,其中用 base64_decode 拼接出一段往 $wpdb->options 写入项的代码,并以 option_value 的形式存放了一段检查远程授权失败后执行 curl 拉取执行体的逻辑。由于该行为只在授权检查失败时触发,平时完全看不出来。教训:触发条件藏在异常分支里的代码,恰恰是最该仔细读的部分。

总结

人工审计的目标不是找到所有问题,而是把风险从“完全未知”降到“已知且可接受”。落地 checklist:来源核对 → 危险函数 grep → 外部域名抽验 → 提权调用检查 → SQL 拼接检查 → WPScan / Plugin Check 交叉跑一遍 → 混淆文件识别。

来源核验的完整流程可配合阅读免费主题与付费主题的真实差异。最后给一条硬规则:凡是来自非官方渠道的包,无论价格多便宜、功能多诱人,都不应该上生产环境。 实在要用,也请先在隔离的临时环境跑完上面这套流程,再考虑上线。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。