Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
wp2shell — PoC RCE pré-authentification pour le cœur de WordPress — enchaîne CVE-2026-63030 (désynchronisation par confusion de routes REST /batch/v1) avec CVE-2026-60137 (SQLi author__not_in) pour obtenir un shell non authentifié. Test autorisé uniquement. | Kitploit
Outils/GitHubGitHub/mcipekci/wp2shell
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationExploitation d'Applications WebPost-ExploitationSécurité WebTests d'IntrusionCommandement et ContrôleRed TeamingDéveloppement de Charges Utiles
GitHubmcipekci/wp2shell
158il y a 1 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

wp2shell

PoC RCE pré-authentification pour le cœur de WordPress — enchaîne CVE-2026-63030 (désynchronisation par confusion de routes REST /batch/v1) avec CVE-2026-60137 (SQLi author__not_in) pour obtenir un shell non authentifié. Test autorisé uniquement.

Voir le dépôt

wp2shell — RCE sans authentification dans le cœur de WordPress

PoC de RCE sans authentification dans le cœur de WordPress enchaînant CVE-2026-63030 + CVE-2026-60137. Test autorisé uniquement.

wp2shell.py est une preuve de concept mono-fichier, utilisant uniquement la bibliothèque standard, qui enchaîne deux vulnérabilités du cœur de WordPress pour aboutir à une exécution de code à distance sans authentification :

CVEComposantDéfaut
CVE-2026-63030Gestionnaire REST /batch/v1désynchronisation par confusion de route — le gestionnaire de lots perd la synchronisation entre sa table de gestionnaires et sa table de validation dès qu'un chemin de sous-requête ne peut pas être analysé, si bien qu'une sous-requête est routée via un gestionnaire pour lequel elle n'a jamais été validée.
CVE-2026-60137WP_Queryinjection SQL scalaire — la valeur de author__not_in est insérée telle quelle dans le SQL, donc une chaîne qui l'atteint est injectable.

Aucune des deux n'est une RCE à elle seule. La désynchronisation est le moyen de livraison (elle fait passer clandestinement une chaîne de l'attaquant dans une requête qu'elle ne devrait jamais atteindre) ; l'injection est la primitive. Ensemble, elles offrent à un attaquant non authentifié un oracle SQL complet en lecture/écriture, et de là, un shell fonctionnel.

⚠️ Test autorisé uniquement. Cet outil exploite des installations WordPress actives. Ne l'utilisez que contre des systèmes dont vous êtes propriétaire ou pour lesquels vous disposez d'une autorisation écrite explicite de test.


Versions concernées

Vulnérables : 6.8.0–6.8.5, 6.9.0–6.9.4, 7.0.0–7.0.1 Corrigées : 6.8.6, 6.9.5, 7.0.2 (et ultérieures) Signalées par Adam Kues (Assetnote / Searchlight Cyber) ; l'injection SQL est également créditée à TF1T, dtro, haongo.

Seules les versions 6.9.0–7.0.1 sont capables de RCE. Sur la ligne 6.8.x, la désynchronisation se déclenche toujours, mais la branche qui désalignerait le gestionnaire provoque à la place une erreur fatale WP_Error::get_method() — la 6.8.x est donc un déni de service / crash, pas un shell. L'outil le détecte et vous indique quelle primitive est disponible.

Comment fonctionne la chaîne

L'exploit est construit en couches ; chacune est un pont vers la suivante.

  1. Désynchronisation (CVE-2026-63030). Une requête par lots imbrique un second lot. Une sous-requête transporte un chemin volontairement malformé (http://:, que wp_parse_url() rejette). En 6.9.0+, l'échec d'analyse fait dériver les tables de gestionnaires et de validation d'une entrée, si bien que la sous-requête suivante est routée vers un gestionnaire pour lequel elle n'a jamais été validée — la collection publique de posts.

  2. Injection (CVE-2026-60137). Cet appel mal routé atteint WP_Query avec un author__not_in contrôlé par l'attaquant. Un UNION ALL SELECT n'y lit pas les lignes — il les fabrique, ce qui nous permet de forger des posts arbitraires dans le résultat de la requête.

  3. Pont SQL → écriture. Les posts forgés portent un balisage [embed]. WordPress les résout consciencieusement et les met en cache comme de véritables lignes oembed_cache de post-meta — transformant une injection en lecture seule en primitive d'écriture arbitraire.

  4. Pivot de privilèges. Grâce à ce pont d'écriture, nous forgeons (a) un changeset du customizer dont l'auteur est le véritable administrateur et (b) un post request auto-référentiel. Ensemble, ils forcent WordPress à réexécuter son propre pipeline de requêtes en tant que cet administrateur — une fenêtre juste assez longue pour qu'un appel en file d'attente crée un nouvel administrateur.

Oracles d'extraction

Pour le côté lecture (--dump, résolution du préfixe, IDs en cache), l'outil sélectionne automatiquement l'oracle le plus rapide qui fonctionne et s'arrête au premier résultat :

  1. union — UNION in-band : le post_title de la ligne forgée contient |||HEX(value)|||, qui est reflété tel quel dans le corps de la réponse /wp/v2/posts. Lit une valeur entière (de n'importe quelle longueur) en une seule requête. Si l'UNION se reflète, les oracles booléens ne sont jamais sondés.
  2. bool — oracle booléen X-WP-Total : l'en-tête X-WP-Total de la sous-réponse confuse vaut count>0 pour vrai / 0 pour faux. Un bit par requête (bissection).
  3. time — SLEEP() basé sur le temps : le repli lorsque le corps est supprimé et que la réponse est une 500 (par exemple une erreur fatale post-dispatch provenant d'un mu-plugin de cache). Fonctionne même sur des cibles qui plantent à chaque appel REST.

--dump utilise GROUP_CONCAT pour récupérer tous les identifiants en une seule fois lorsque l'UNION est disponible.

Installation

Aucune. Uniquement la bibliothèque standard Python 3.7+ — pas de pip install.

root@kitploit:~
chmod +x wp2shell.py

Utilisation

root@kitploit:~
# 1. Is it vulnerable? (no injection, no writes, no account created)
./wp2shell.py http://target --check

# 2. Read-only credential dump — FIRST administrator + option secrets
./wp2shell.py http://target --dump

#    …every administrator
./wp2shell.py http://target --dump all

# 3. Full RCE — create a temp admin, run a command, clean up
./wp2shell.py http://target --exec "id; uname -a"

Reconnaissance en lecture seule (sans création d'administrateur, contourne la 2FA)

root@kitploit:~
./wp2shell.py http://target --user-list          # full user table (logins/emails/roles)
./wp2shell.py http://target --content            # every post type at status=any (private/draft)
./wp2shell.py http://target --content full        #   …including each item's raw body

Analyse de nombreux hôtes

root@kitploit:~
./wp2shell.py -f targets.txt --check --target-threads 8

Options

Contournement WAF / durcissement

Remarques sur la sortie

  • Hashs de mots de passe ($wp$2y$… / $P$… / $2y$…) vont directement dans hashcat (-m 3200 pour phpass, ou le mode bcrypt WP). WordPress 6.8+ utilise le bcrypt $wp$….
  • --dump cible par défaut uniquement le premier administrateur. Utilisez --dump all pour la liste complète des administrateurs.
  • Cibles avec erreur 500 / crash : si une erreur fatale post-dispatch (par exemple un mu-plugin de cache type Pantheon) transforme chaque réponse REST en 500, la création d'administrateur ne fonctionnera pas, mais les lectures fonctionnent toujours — passez à --oracle time --dump pour récupérer les hashs.

Pourquoi le nettoyage est important

Le chemin --exec est conçu pour ne laisser aucune trace : l'administrateur temporaire, ses usermeta, les lignes oembed_cache forgées et la webshell téléversée sont tous supprimés avant la sortie de l'outil. Il n'y a pas d'option --keep — un opérateur ne devrait jamais laisser un compte administrateur actif créé par un attaquant sur le système d'un client.

Fichiers

  • wp2shell.py — l'exploit (fichier unique, bibliothèque standard uniquement).

Crédits

La découverte des vulnérabilités, leur divulgation et l'analyse originale de « wp2shell » sont créditées à l'équipe de recherche Searchlight Cyber / Assetnote :

  • CVE-2026-63030 — désynchronisation par confusion de route REST /batch/v1
  • CVE-2026-60137 — injection SQL sur WP_Query author__not_in

Ce dépôt est une implémentation indépendante de preuve de concept de la chaîne d'exploitation qu'ils ont divulguée ; il ne revendique pas la découverte des vulnérabilités sous-jacentes. Si une attribution est incomplète ou incorrecte, ouvrez une issue et elle sera corrigée.

Références

  • Searchlight Cyber / Assetnote — wp2shell : RCE pré-authentification dans le cœur de WordPress https://slcyber.io/research-center/wp2shell-pre-authentication-rce-in-wordpress-core/
  • Publication de WordPress 7.0.2 (correctif) — https://wordpress.org/news/2026/07/wordpress-7-0-2-release/
  • Avis de sécurité — GHSA-ff9f-jf42-662q, GHSA-fpp7-x2x2-2mjf

Avertissement

Ceci est une preuve de concept de recherche en sécurité pour des tests d'intrusion autorisés et une validation défensive. L'exécuter contre des systèmes dont vous n'êtes pas propriétaire ou pour lesquels vous n'avez pas d'autorisation écrite de test est illégal. L'auteur décline toute responsabilité en cas d'utilisation abusive.

Télécharger l’outil
POST /wp/v2/users
  • Shell. Connectez-vous en tant que nouvel administrateur, téléversez un plugin, exécutez la commande. Le compte, ses meta, les lignes oembed et la webshell sont ensuite tous nettoyés — aucune empreinte persistante n'est laissée.

  • OptionDescription
    url / -f FILEcible unique, ou fichier de cibles (une URL par ligne)
    --checkvérification de vulnérabilité uniquement — pas d'injection, d'écriture ni de compte
    --dump [all]extraire le hash du premier administrateur + les secrets ; all = tous les administrateurs
    --exec CMDcréer un administrateur temporaire → exécuter CMD → nettoyer
    --user-listlecture in-band privilégiée de la table complète des utilisateurs (sans connexion, contourne la 2FA)
    --content [full]lecture privilégiée de chaque type de publication à status=any ; full ajoute les corps
    --oracle {auto,union,bool,time}forcer un oracle d'extraction (défaut auto)
    --prefix PFXforcer le préfixe de table au lieu de la résolution automatique
    --impersonate UIDusurper cet identifiant utilisateur au lieu du premier administrateur
    --threads Nsondes d'extraction concurrentes sur une seule cible (défaut 5)
    --target-threads Nanalyser N cibles depuis -f en parallèle (défaut 1)
    --proxy URLpasser par un proxy (ex. Burp http://127.0.0.1:8080)
    --timeout SECdélai d'expiration par requête (défaut 30)
    --verbose / -vafficher les sous-réponses batch brutes (débogage)
    OptionDescription
    --formenvoyer le batch en multipart/form-data (URL propre, sans ?rest_route=)
    --permalink [PREFIX]router via /<PREFIX>/batch/v1 (défaut wp-json) ; garde la charge utile hors de l'URL et hors de $_POST. Astuce : --permalink index.php/wp-json atteint REST via PATH_INFO, échappant aux règles ancrées sur /wp-json
    --dummy Npréfixer N octets de déchets dans le corps pour faire déborder le tampon d'inspection du WAF
    --donor {widgets,categories,tags}changer la route donneuse de confusion si l'une renvoie une 500 (défaut widgets)
    --per-page Nforger per_page (-1 ou un grand nombre positif renvoient toutes les lignes ; utilisez un grand nombre positif si la cible renvoie une 500 sur -1)
    --users-route PATHvariante de casse/requête pour l'appel de création d'utilisateur (/wp/v2/Users, …?_=1)
    --primer PATHchemin de désynchronisation malformé alternatif si un WAF identifie le http://: par défaut
    --user-agent UAfixer le UA (défaut : un UA de navigateur réaliste aléatoire à chaque exécution)
    --embed-base URLremplacer la base d'URL oembed (éviter une boucle d'auto-intégration)