跳转到帖子

WordPress Elementor Pro WooCommerce 模块权限绕过漏洞验证与修复记录

精选回复

发布于

背景

这篇记录放在漏洞库板块,主要针对一次授权环境中的 WordPress 插件漏洞验证过程。目标站点使用 WordPress + WooCommerce + Elementor Pro,业务侧反馈存在异常管理员账号创建记录。经版本核对,Elementor Pro 插件处于受影响版本范围内,风险点集中在 WooCommerce 模块相关的 Ajax 调用权限校验不足。

本文不讨论批量利用,只记录单站授权验证、日志排查、漏洞确认、权限边界判断和修复建议。类似漏洞在 WordPress 插件中比较常见:前端 Ajax 接口挂载在 admin-ajax.php,但后端回调缺少能力检查或 nonce 校验,导致低权限用户甚至未认证用户触发敏感逻辑。

适用场景

  • 站点使用 WordPress,并安装 Elementor Pro 与 WooCommerce。
  • 发现异常用户创建、插件配置被修改、后台选项表异常变更。
  • 需要在授权渗透测试中验证漏洞是否真实存在。
  • 需要判断漏洞影响范围、日志留痕位置以及修复方式。

问题定位

排查时先确认插件版本,不建议直接从后台页面判断,因为部分站点会隐藏版本号。可以在服务器侧读取插件头信息:

cd /var/www/html/wp-content/plugins/elementor-pro

# 查看插件版本
sed -n '1,40p' elementor-pro.php | grep -i "Version"

# 或直接从 WordPress CLI 查询
wp plugin list | grep -E "elementor|woocommerce"

一次现场环境中的版本信息如下:

elementor-pro    active    none    3.11.x
woocommerce      active    none    7.x
wordpress        6.x

同时检查是否存在异常用户和可疑时间线:

wp user list --fields=ID,user_login,user_email,user_registered,roles

# 查看最近注册用户
wp db query "SELECT ID,user_login,user_email,user_registered FROM wp_users ORDER BY user_registered DESC LIMIT 10;"

如果存在短时间内新增管理员账号,需要继续查 wp_usermeta 中权限字段:

wp db query "SELECT user_id,meta_key,meta_value FROM wp_usermeta WHERE meta_key IN ('wp_capabilities','wp_user_level') ORDER BY user_id DESC LIMIT 20;"

技术分析

WordPress Ajax 的核心入口是:

/wp-admin/admin-ajax.php

插件通常通过以下方式注册 Ajax 行为:

add_action('wp_ajax_xxx', 'callback_function');
add_action('wp_ajax_nopriv_xxx', 'callback_function');

其中 wp_ajax_nopriv_* 表示未登录用户也可访问。如果回调函数中执行了更新选项、创建用户、修改角色、调用 WooCommerce 管理逻辑等敏感操作,但没有做下面这些校验,就会形成权限绕过:

  • current_user_can('manage_options') 或更细粒度能力检查缺失。
  • check_ajax_referer() 缺失或 nonce 可被低权限用户获取。
  • 对传入参数直接进入内部控制器逻辑,形成方法调用链滥用。
  • 将前端组件请求与后台管理请求混用,导致权限边界失效。

在授权验证时,不需要破坏业务数据。建议优先验证是否能触发目标 Ajax 分支、是否能越权调用敏感动作,而不是直接新增管理员账号。可以使用测试账号、临时环境或快照环境进行复现。

操作步骤

以下步骤适用于授权测试或自有环境排查。

1. 确认插件安装与版本

wp plugin list --status=active --fields=name,version,status | grep -E "elementor|woocommerce"

如果没有 WP-CLI,也可以直接查文件:

grep -i "Version" wp-content/plugins/elementor-pro/elementor-pro.php
grep -i "Version" wp-content/plugins/woocommerce/woocommerce.php

2. 检查 Ajax 动作注册点

在插件目录中搜索 Ajax 注册和 nonce 校验:

cd wp-content/plugins/elementor-pro

grep -R "wp_ajax" -n . | head -50
grep -R "wp_ajax_nopriv" -n . | head -50
grep -R "check_ajax_referer\|current_user_can" -n modules/ | head -100

重点看 WooCommerce、模板导入、站点设置、全局选项相关模块。如果发现某个回调函数存在 wp_ajax_nopriv 挂载,却没有权限检查,需要进一步追调用链。

3. 低权限账号验证权限边界

创建一个普通订阅者账号,仅用于确认接口是否被低权限触发:

wp user create test_subscriber [email protected] --role=subscriber --user_pass='TestPass-ChangeMe-123'

登录后获取 Cookie,然后请求可疑 Ajax 动作。这里用占位形式表示,实际动作名以代码审计结果为准:

curl -i ' \
  -H 'Cookie: wordpress_logged_in_xxx=YOUR_COOKIE' \
  --data 'action=ELEMENTOR_PRO_RELATED_ACTION&_nonce=NONCE_IF_REQUIRED&param=value'

判断点:

  • 如果返回 0 或 -1,通常表示动作不存在、权限不足或 nonce 校验失败。
  • 如果返回 JSON 且进入业务逻辑,需要看是否发生状态变更。
  • 如果订阅者可以触发仅管理员应能执行的操作,基本可判定存在权限边界问题。

4. 数据库侧确认是否发生敏感变更

不要只看前端返回。WordPress 很多操作最终体现在 wp_options、wp_users、wp_usermeta 表中:

# 最近变更的用户
wp db query "SELECT ID,user_login,user_email,user_registered FROM wp_users ORDER BY ID DESC LIMIT 10;"

# 管理员角色用户
wp db query "SELECT u.ID,u.user_login,u.user_email,m.meta_value FROM wp_users u JOIN wp_usermeta m ON u.ID=m.user_id WHERE m.meta_key='wp_capabilities' AND m.meta_value LIKE '%administrator%';"

# Elementor / WooCommerce 相关配置
wp db query "SELECT option_name,LENGTH(option_value) AS len FROM wp_options WHERE option_name LIKE '%elementor%' OR option_name LIKE '%woocommerce%' ORDER BY option_id DESC LIMIT 30;"

日志留痕排查

漏洞验证和应急排查都需要看 Web 访问日志。重点检索 admin-ajax.php、异常 action、短时间高频 POST 请求、异常 User-Agent。

# Nginx 日志示例
grep "admin-ajax.php" /var/log/nginx/access.log | tail -100

grep "POST /wp-admin/admin-ajax.php" /var/log/nginx/access.log | awk '{print $1,$4,$7,$9,$12}' | tail -100

# 如果日志中记录了请求体,可进一步检索 action
grep -i "elementor\|woocommerce\|admin-ajax" /var/log/nginx/access.log*

Apache 环境:

grep "admin-ajax.php" /var/log/apache2/access.log | tail -100
grep -i "POST /wp-admin/admin-ajax.php" /var/log/apache2/access.log*

如果使用了 WAF、CDN 或反向代理,还要注意真实源 IP 是否在 X-Forwarded-For 中。Nginx 日志建议增加如下字段,方便后续追踪:

log_format main_ext '$remote_addr $http_x_forwarded_for [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time ua="$upstream_addr"';

风险判断

风险点影响排查位置
低权限 Ajax 越权普通用户触发后台敏感操作插件 Ajax action、访问日志
未认证 Ajax 暴露未登录用户可调用敏感接口wp_ajax_nopriv_* 注册点
管理员账号被创建站点完全失陷wp_users、wp_usermeta
插件配置被篡改页面注入、跳转、后门加载wp_options、主题模板文件

修复建议

  • 立即升级 Elementor Pro、WooCommerce、WordPress Core 到官方修复版本。不要只升级 WordPress 核心,插件漏洞不会随核心自动消失。
  • 删除异常管理员账号,并重置所有管理员密码。
  • 检查 wp_users、wp_usermeta、wp_options、主题目录和插件目录是否存在异常写入。
  • 关闭不必要的用户注册功能,后台路径增加访问控制或二次认证。
  • 对 /wp-admin/admin-ajax.php 做行为监控,不建议简单封禁该入口,因为很多正常插件依赖它。
  • 检查服务器文件权限,避免 Web 用户对插件目录、主题目录有不必要的写权限。

文件权限可参考:

# 目录 755,文件 644
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;

# wp-config.php 收紧权限
chmod 600 /var/www/html/wp-config.php

# 确认属主,按实际 PHP-FPM 用户调整
chown -R www-data:www-data /var/www/html

如果业务允许,可以在 Nginx 层对未登录的高风险 Ajax 请求做限制。示例仅供思路参考,实际不要直接复制到生产,需要结合插件 action 白名单测试:

location = /wp-admin/admin-ajax.php {
    limit_req zone=ajax burst=20 nodelay;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}

代码层加固参考

插件开发或二开时,Ajax 回调至少要包含 nonce 和能力检查。敏感操作不要只依赖前端隐藏按钮。

add_action('wp_ajax_safe_update_option', 'safe_update_option_handler');

function safe_update_option_handler() {
    if (!current_user_can('manage_options')) {
        wp_send_json_error(['message' => 'permission denied'], 403);
    }

    check_ajax_referer('safe_update_option_nonce', 'nonce');

    $value = isset($_POST['value']) ? sanitize_text_field($_POST['value']) : '';
    update_option('custom_safe_option', $value);

    wp_send_json_success(['message' => 'updated']);
}

如果确实需要提供未登录 Ajax 接口,建议只处理无状态查询类逻辑,不要连接到用户创建、权限修改、插件安装、模板写入、站点选项更新等敏感能力。

总结

这类 WordPress 插件漏洞的关键不在于入口是否是 admin-ajax.php,而在于回调函数是否正确做了权限和 nonce 校验。授权测试时建议按“版本确认、代码定位、低权限验证、数据库核对、日志追踪、修复复测”的顺序推进,避免直接做破坏性验证。

对生产站点来说,插件升级只是第一步。真正需要补上的,是异常账号清理、历史日志回溯、文件完整性检查和 Ajax 行为监控,否则很容易出现漏洞已修但后门仍在的情况。

网络流量与边界分析示意图
网络请求、日志与边界流量分析示意

这个洞验证完建议别只停在“插件已升级”这一步,重点要确认有没有被利用过。Elementor Pro 这类问题常见利用链是通过 admin-ajax.php 修改站点关键 option,再注册/提升管理员,所以排查可以围绕 option 变更和新增管理员做。

可以先看访问日志里有没有相关 AJAX action 和敏感 option:

grep -R "admin-ajax.php" /var/log/nginx/*access* | grep -Ei "elementor|woocommerce|update_page_option|users_can_register|default_role"

grep -R "admin-ajax.php" /var/log/apache2/*access* | grep -Ei "elementor|woocommerce|update_page_option|users_can_register|default_role"

如果用了 WP-CLI,直接查当前关键配置:

wp option get users_can_register
wp option get default_role
wp option get siteurl
wp option get home

正常情况下多数站点应该是:

users_can_register = 0
default_role = subscriber

如果发现 default_role 被改成 administrator,或者 users_can_register 被打开过,就要继续查用户表:

wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
wp user list --orderby=registered --order=DESC --fields=ID,user_login,user_email,user_registered,roles

数据库里也可以直接看:

SELECT ID,user_login,user_email,user_registered
FROM wp_users
ORDER BY user_registered DESC
LIMIT 20;

SELECT user_id,meta_key,meta_value
FROM wp_usermeta
WHERE meta_key LIKE '%capabilities%'
  AND meta_value LIKE '%administrator%';

修复动作建议按这个顺序做:

  1. Elementor Pro 升到官方修复版本以上,WooCommerce、Elementor Free 也一起更新。
  2. 确认关闭注册和默认角色:
wp option update users_can_register 0
wp option update default_role subscriber
  1. 删除异常管理员账号,重置所有管理员密码。
  2. 检查是否有新装的可疑插件、主题或 mu-plugin:
wp plugin list
wp theme list

find wp-content/mu-plugins -type f -maxdepth 2 -ls 2>/dev/null
find wp-content/uploads -type f \( -name "*.php" -o -name "*.phtml" -o -name "*.phar" \) -ls
  1. 轮换 wp-config.php 里的 salts,强制所有会话失效。

另外可以临时在 WAF/Nginx 层对异常请求做拦截,比如包含敏感 option 修改的请求直接拒绝:

location = /wp-admin/admin-ajax.php {
    if ($request_body ~* "(users_can_register|default_role|administrator)") {
        return 403;
    }

    include fastcgi_params;
    fastcgi_pass php-fpm;
}

这个规则只能作为临时缓解,不建议长期依赖。最终还是要升级插件并确认站点没有遗留后门。对于这类权限绕过,最容易漏的是“攻击者已经创建了管理员,但漏洞补上后账号还在”,所以用户和 option 的核查一定要做。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。