Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
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é.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
wp2shell-lab — Détecteur non destructif + laboratoire Docker pour wp2shell (CVE-2026-63030 confusion de route REST /batch/v1 + CVE-2026-60137 SQLi author__not_in) dans WordPress core 6.9.0-6.9.4 / 7.0.0-7.0.1 | Kitploit
Outils/GitHubGitHub/dinosn/wp2shell-lab
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionApprentissage et ÉducationLabs et Pratique
GitHubdinosn/wp2shell-lab

wp2shell-lab

Détecteur non destructif + laboratoire Docker pour wp2shell (CVE-2026-63030 confusion de route REST /batch/v1 + CVE-2026-60137 SQLi author__not_in) dans WordPress core 6.9.0-6.9.4 / 7.0.0-7.0.1

Voir le dépôt
541744il y a 3 moisVérifié par Kitploit

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 lab & detector + PoC RCE pre-auth

Un lab autonome, un détecteur non destructif et une preuve de concept complète de RCE pre-auth pour wp2shell — la chaîne de vulnérabilités de pré-authentification dans le cœur de WordPress :

CVEComposantClasseCVSS
CVE-2026-60137WP_Query::author__not_inInjection SQL (CWE-89)9.1
CVE-2026-63030Confusion de route REST /batch/v1conflit d'interprétation (CWE-436) → chaîne vers RCE7.5

Affecté : cœur de WordPress 6.9.0–6.9.4 et 7.0.0–7.0.1 (le point d'injection SQLi seul affecte également 6.8.0–6.8.5). Corrigé dans 6.8.6 / 6.9.5 / 7.0.2. Signalé par Adam Kues (Assetnote / Searchlight Cyber) ; SQLi également crédité à TF1T, dtro, haongo. Chaîne RCE sur configuration par défaut (oEmbed → changeset → ré-entrée) par Mustafa Can İPEKÇİ (nukedx).

Mettez à jour en premier. WordPress a déployé des mises à jour automatiques forcées pour ce problème. Ce dépôt existe pour vous aider à vérifier que votre propre parc est corrigé et à comprendre la faille — pas pour attaquer qui que ce soit. Voir SECURITY.md.


Ce que c'est réellement

La primitive toujours vraie est une injection SQL non authentifiée, sans plugin, sur le cœur standard offrant une lecture complète de la base de données (hachages de mots de passe admin, tout dans wp_options/wp_users). Cela seul justifie le 9.1 et un correctif immédiat.

La RCE est réelle et fonctionne sur un WordPress par défaut — aucun privilège FILE, aucun cache d'objets persistant, aucun plugin, aucune mauvaise configuration requis. La chaîne utilise l'injection SQL en lecture seule comme primitive de falsification de lignes (UNION ALL SELECT injecte de fausses lignes wp_posts), puis exploite le propre pipeline de rendu de contenu de WordPress pour convertir ces lignes falsifiées en écritures réelles en base de données via la mise en cache oEmbed. À partir de là, l'élévation par changeset et le parse_request ré-entrant s'exécutent en contexte admin, créant un nouveau compte administrateur — le tout à partir d'une seule requête HTTP non authentifiée.

La chaîne complète (aucun identifiant, point d'entrée unique POST /?rest_route=/batch/v1)

1. Route confusion    — double-nested batch desyncs $matches/$validation so a GET
                        /wp/v2/widgets runs under posts::get_items() (public), reaching
                        WP_Query's author__not_in with attacker-controlled input.

2. Row forgery        — author__not_in is string-concatenated into SQL;
                        "1) AND 1=0 UNION ALL SELECT <23 cols> -- -" injects fake
                        WP_Post rows. per_page=-1 bypasses split_the_query (WP_Query
                        treats -1 as "no limit" → empty $limits → split=false →
                        full SELECT wp_posts.* → UNION columns match).

3. oEmbed write       — forged posts carry [embed]<self-url>[/embed]; rendering via
                        context=view makes WordPress cache real oembed_cache posts in
                        the DB (turns read-only SQLi into writes with predictable IDs).

4. Elevation+re-entry — a forged customize_changeset (user_id = real admin) plus a
                        forged post_type=request row with parent loops drives an
                        in-process re-entrant parse_request in admin context.

5. Admin creation     — POST /wp/v2/users in the same batch passes
                        current_user_can('create_users') → new administrator.

6. RCE                — login → plugin webshell upload → command execution → cleanup.

Gadgets porteurs (pourquoi la chaîne tient)

La nouveauté réside dans la composition, et non dans un bug isolé — les gadgets individuels sont des comportements légitimes de WordPress. Les nommer (d'après l'analyse d'Adam Kues) rend lisible le graphe de lignes forgées dans exploit() et signale ce qu'il faut ré-auditer après le correctif des points d'entrée :

  • Réconciliation cache/BD — lorsqu'un article en cache mémoire diffère de sa ligne en BD, WordPress réconcilie via wp_update_post() et privilégie le post_type/post_status en mémoire, permettant à une ligne oembed_cache d'être retypée en véritable post/customize_changeset.
  • Détection de cycle préservant post_content — le filtre wp_insert_post_parent parcourt la chaîne des parents ; lorsqu'un cycle est détecté, il appelle un second wp_update_post() qui corrige le parent sans écraser post_content. C'est le maillon critique : il permet au post_content malveillant du changeset forgé de survivre. (C'est pourquoi les lignes forgées utilisent des boucles de parent auto-référentielles ou mutuelles.)
  • Rejeu de hooks via parse_request — publier un article déclenche do_action("{$status}_{$type}") ; une ligne forgée avec post_status=parse / post_type=request déclenche parse_request, réexécutant le pipeline de traitement par lots tant que l'identité d'administrateur assumée du changeset (wp_set_current_user) tient encore.

Ces gadgets restent présents dans WordPress corrigé — seuls les deux points d'entrée (désynchronisation du traitement par lots + contournement scalaire author__not_in) ont été fermés. Toute nouvelle primitive qui forge le cache d'articles en mémoire ou écrit une ligne oembed_cache réactiverait la même queue de prise de contrôle administrateur.

Primitives d'écriture au moment du rendu

Les quatre primitives d'écriture au moment du rendu ont été confirmées actives contre 7.0.1 — chacune forgée comme un article non authentifié, rendue via la confusion du traitement par lots, et l'écriture en BD résultante vérifiée par SQLi en aveugle :

PrimitiveBalisage déclencheurDestinationIdentifiant préditVérifié
oembed[embed]<url>[/embed]ligne wp_posts (oembed_cache)post_name = md5(url+attrs)ID d'article créé
rsswp:rss {feedURL}site-transient wp_options_site_transient_feed_<md5(url)>option_id, 5192 B mis en cache
navigationwp:navigationligne wp_posts (wp_navigation)post_name = 'navigation' (fixe)ID créé, slug navigation
calendarwp:calendarwp_optionswp_calendar_block_has_published_postsoption_id, valeur '1'

Ce que chaque résultat prouve :

  • oembed — la primitive de référence : une nouvelle ligne wp_posts avec un slug prédit par l'attaquant (md5(url+serialize(attrs))) et un véritable ID auto-incrémenté. C'est la seule qui fournit plusieurs lignes d'articles, à la demande et nommées par l'attaquant — c'est pourquoi la chaîne RCE l'utilise pour étayer le graphe changeset/request forgé.
  • rss — l'écriture générale la plus puissante : la clé _site_transient_feed_<md5(url)> est entièrement prévisible, et les octets stockés sont le corps du flux servi par l'URL de l'attaquant — c'est-à-dire que l'attaquant contrôle à la fois la clé et la valeur. C'est une écriture dans wp_options (pas d'ID d'article), donc c'est une primitive d'empoisonnement d'option plutôt qu'un substitut direct pour l'étayage du changeset.
  • navigation — le seul autre chemin non authentifié « le rendu crée une véritable ligne d'article ». Il est à usage unique (ignoré si un wp_navigation publié existe) avec un slug fixe, il ne peut donc étayer au plus qu'un seul objet forgé, contrairement aux N lignes d'oEmbed.
  • calendar — confirme que le chemin rendu→update_option se déclenche sans authentification, mais le nom de l'option et sa valeur '1'/'0' sont fixes/dérivés de la BD, c'est donc une démonstration « l'écriture a lieu » sans aucun contrôle de l'attaquant sur la clé ou la valeur.
Télécharger l’outil