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é.

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

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/0xsha/wp2shell
Cassage de Mots de PasseAnalyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionCommandement et ContrôleApprentissage et ÉducationRed TeamingDéveloppement de Charges UtilesLabs et Pratique
GitHub
963037il y a 2 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
0xsha/wp2shell

wp2shell

CVE-2026-63030 + CVE-2026-60137 - “wp2shell” : RCE non authentifiée dans le cœur de WordPress

Voir le dépôt

CVE-2026-63030 + CVE-2026-60137 - « wp2shell » : RCE non authentifiée dans le cœur de WordPress

API REST : confusion de routes batch (CVE-2026-63030) enchaînée avec une injection SQL author__not_in de WP_Query (CVE-2026-60137) → exécution de code à distance avant authentification contre une installation WordPress par défaut.

Découverte par Adam Kues (Assetnote / Searchlight Cyber), divulguée le 17/07/2026. Avis de sécurité : GHSA-ff9f-jf42-662q, GHSA-fpp7-x2x2-2mjf.

Chaîne (RCE non authentifiée)WordPress 6.9.0 - 6.9.4 et 7.0.0 - 7.0.1
SQLi uniquement (nécessite un plugin/thème facilitateur)6.8.0 - 6.8.5
Non concernés≤ 6.8 pour la confusion de batch ; 6.9.5 / 7.0.2 / 7.1-beta2 (corrigés)
Conditions préalablesAPI REST accessible ; aucun cache d'objets persistant (Redis/Memcached) ; ≥1 article publié
Authentification requiseaucune
Impactnon authentifié → création d'un nouvel administrateur → exécution de code (la SQLi extrait aussi le hash admin)

Démo

https://github.com/user-attachments/assets/7f9cc52c-3f31-4339-9192-e31e506684f6

Ce que ce dépôt apporte

  • Un outil original, uniquement en bibliothèque standard (wp2shell.py), qui réunit le meilleur de six PoC publics dans un seul fichier, sans dépendance requests et sans fonctionnalité cassée.
  • La RCE complète sans cassage de hash, vérifiée de bout en bout en laboratoire : shell, sans identifiants, forge un faux WP_Post via la confusion UNION sur article unique, passe par le customizer pour créer un administrateur flambant neuf (POST /wp/v2/users), se connecte et dépose un webshell protégé par jeton. L'extraction du hash admin par SQLi (read --preset users) est conservée comme seconde voie vérifiée.
  • Un détecteur de confusion indépendant de la version (block_cannot_read), utilisé comme check principal non destructif.
  • Un transport de production sur chaque commande : TLS auto-signé, en-têtes personnalisés, User-Agent personnalisé, proxy, nouvelles tentatives, délai entre les requêtes.
  • Un chemin de SQLi facilitée 6.8.x vérifié (sqli), que les autres PoC ne possèdent pas.
  • Des laboratoires Docker reproductibles, plus une matrice de fiabilité version × base de données, avec chaque résultat vérifié en laboratoire.
  • Le mode hashcat pour le nouveau hash de mot de passe $wp$2y$ (-m 35500).
wp2shell/
├── README.md              ← you are here
├── wp2shell.py            ← the unified PoC (single file, stdlib only, by 0xsha)
└── lab/                   ← reproducible Docker labs + reliability matrix
    ├── docker-compose.yml         (default 6.9.4 lab)
    ├── docker-compose.matrix.yml  (parameterised: any version × MySQL/MariaDB)
    ├── docker-compose.sqli.yml    (6.8.3 "SQLi only" lab)
    ├── matrix.sh                  (runs the whole reliability matrix)
    └── sqli-only/facilitator.php  (mu-plugin: the 6.8.x facilitating sink)

Les six PoC publics sur lesquels s'appuie cet outil ne sont pas intégrés ici ; ils sont référencés dans Crédits.

Tout ce qui suit a été vérifié dans le laboratoire Docker local (voir §4) ; les affirmations qui n'ont pas été exécutées en laboratoire sont signalées comme telles.


1. Détails des vulnérabilités - plongée dans le code

La chaîne soude deux bugs indépendants. Les numéros de ligne proviennent du vrai code source de WordPress 6.9.4 (extrait de wordpress:6.9.4-apache).

Bug A - injection SQL author__not_in (CVE-2026-60137)

wp-includes/class-wp-query.php, WP_Query::get_posts():

2403  if ( ! empty( $query_vars['author__not_in'] ) ) {
2404      if ( is_array( $query_vars['author__not_in'] ) ) {                 // ← guard only fires for ARRAYS
2405          $query_vars['author__not_in'] = array_unique( array_map( 'absint', $query_vars['author__not_in'] ) );
2406          sort( $query_vars['author__not_in'] );
2407      }
2408      $author__not_in = implode( ',', (array) $query_vars['author__not_in'] );   // ← string passes straight through
2409      $where         .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) ";  // ← raw interpolation
2410  } elseif ( ! empty( $query_vars['author__in'] ) ) {
...
2415      $author__in = implode( ',', array_map( 'absint', array_unique( (array) $query_vars['author__in'] ) ) );  // ← absint INSIDE implode

Un author__not_in de type chaîne contourne la garde is_array() (2404) ; implode(',',(array)"…") le renvoie tel quel (2408) et il est concaténé brut dans le SQL (2409). Le author__in voisin (2415) réapplique array_map('absint', …) à l'intérieur de l'implode et est sûr - c'est ce array_map manquant qui constitue le bug. La valeur atterrit sous la forme ... post_author NOT IN (<value>) ..., donc 0) <sql>-- - ferme la liste et ajoute du SQL.

Faire parvenir une chaîne jusqu'ici est la partie difficile : le endpoint REST des articles mappe author_exclude → author__not_in (class-wp-rest-posts-controller.php:247) mais le déclare 'type' => 'array' d'entiers, si bien que le cœur convertit/rejette une chaîne :

GET /wp-json/wp/v2/posts?author_exclude=1) OR SLEEP(3)-- -
→ 400 "author_exclude[0] is not of type integer."      (verified on 6.8.3)

C'est pourquoi le bug A seul n'est que « facilité ». Le bug B fait passer la chaîne au-delà de la validation sur 6.9+.

Bug B - confusion de routes batch de l'API REST (CVE-2026-63030)

wp-includes/rest-api/class-wp-rest-server.php, serve_batch_request_v1():

1720  if ( false === $parsed_url ) {
1721      $requests[] = new WP_Error( 'parse_path_failed', … );   // a bad path becomes a WP_Error IN $requests

1749  foreach ( $requests as $single_request ) {
1750      if ( is_wp_error( $single_request ) ) {
1752          $validation[] = $single_request;     // ← pushed to $validation …
1753          continue;                            // ← … but $matches is SKIPPED
1754      }
1757      $matches[] = $match;                     // ← $matches only grows for VALID requests

1825  foreach ( $requests as $i => $single_request ) {   // indexed by position in $requests
1841      $match = $matches[ $i ];                        // ← $matches is SHORTER → +1 shift
1861      $result = $this->respond_to_request( $single_request, $route, $handler, $error );

Une sous-requête WP_Error est poussée dans $validation[] (1752) mais pas dans $matches[] (le continue à la ligne 1753 saute la ligne 1757), si bien que $matches manque d'entrées et que $matches[$i] (1841) contient le gestionnaire de la requête suivante. La requête i est traitée avec le gestionnaire de la requête i+1, tout en portant ses propres paramètres et son propre verdict de validation (réussi).

Origine de la régression (diff 6.8.3 → 6.9.4 vérifié) : en 6.8.3, la boucle pousse $matches[] = $match pour chaque requête et les mauvais chemins sont écartés dans la première boucle - les tableaux restent alignés, pas de désynchronisation. La refactorisation de 6.9.0 a introduit le décalage. C'est exactement la raison pour laquelle 6.8.x est « SQLi uniquement » et que la chaîne RCE commence en 6.9.0.

Le correctif documenté (6.9.5 / 7.0.2)

Le correctif ajoute également $matches[] pour les entrées d'erreur, durcit la réentrance et analyse author__not_in à l'aide d'un utilitaire de liste d'identifiants. (6.9.5 n'était pas sur Docker Hub au moment des tests, cette information provient donc des avis de sécurité, pas d'un diff en laboratoire.)


2. Méthode d'exploitation

2.1 La double confusion de routes

Télécharger l’outil