
Détecter et nettoyer la compromission WordPress wp2shell (CVE-2026-63030) — exécutable par lots, lecture seule par défaut
Détectez et nettoyez la compromission wp2shell (CVE‑2026‑63030) sur un ou plusieurs sites WordPress.
wp2shell est la vulnérabilité d'exécution de code à distance avant authentification corrigée dans WordPress 7.0.2 / 6.9.5 / 6.8.6 (2026‑07‑17). Un PoC public est apparu en un jour et une exploitation massive a suivi en ~48 heures. Le correctif bouche la faille — mais un site exploité avant son application est déjà compromis, et la mise à jour ne supprime pas la persistance de l'attaquant.
Cet outil détecte et supprime cette persistance. C'est un script Bash unique, avec peu de dépendances, qui s'exécute en lecture seule par défaut et peut analyser des milliers de sites en une seule passe.
⚠️ Il s'agit d'un outil défensif. Il ne contient aucun code d'exploitation. Prenez un instantané d'un site avant d'exécuter
--clean.
Après l'exploitation, l'outillage wp2shell laisse généralement deux artefacts de persistance, que cet outil détecte tous les deux :
user_login = wpsvc_<hex> / wp2_<hex> / w2s_<hex>, ou un e-mail sur un domaine de l'attaquant (@wp2shell.*, @shellcode.*, @wordpress-svc.internal, @wordpress-noreply.net, @x.lol), avec le rôle administrator. (Remarque : @system.local est un e-mail administrateur légitime utilisé comme espace réservé sur certains hébergements managés — il n'est volontairement pas traité comme un IOC.)wp-content/plugins/<plausible-name>-<6hex>/<same>.php : un petit fichier PHP (~1,3 Ko) avec un faux en-tête Author: WordPress.org Community, protégé par un jeton, exposant une interface ?c=<command>.Il détecte également le cas générique : tout petit fichier PHP sous wp-content/ qui envoie $_GET['c'] dans un sink de commande/eval.
curl -fsSLO https://raw.githubusercontent.com/InstaWP/wp2shell-scan/main/wp2shell-scan.sh
chmod +x wp2shell-scan.sh
Nécessite bash, find, grep et un client mysql/mariadb. WP‑CLI est utilisé lorsqu'il est présent (suppression d'utilisateur plus propre) mais n'est pas obligatoire — la détection des webshells n'a besoin d'aucune base de données.
# Scan ONE site (read-only)
./wp2shell-scan.sh --path /var/www/example.com
# Scan EVERY WordPress install under a base directory (bulk)
./wp2shell-scan.sh --base /var/www
./wp2shell-scan.sh --base /home # shared hosting
# Auto-detect common layouts (/var/www/*, /home/*/public_html, ...)
./wp2shell-scan.sh
# Machine-readable
./wp2shell-scan.sh --base /var/www --json > report.json
# CLEAN — quarantine + remove backdoors, rotate wp-config salts (logs everyone out)
./wp2shell-scan.sh --base /var/www --clean --yes
# Vet a BACKUP / SNAPSHOT / TEMPLATE dump before restoring it (see warning below)
./wp2shell-scan.sh --sql /path/to/backup.sql
Les artefacts supprimés sont déplacés vers un répertoire de quarantaine (non supprimés définitivement) afin de conserver des preuves. Le code de sortie est 1 lorsqu'une compromission est trouvée (scan) ou nettoyée (clean), 0 lorsqu'il n'y a rien — pratique pour cron/CI.
[COMPROMISED] /var/www/example.com — 2 backdoor admin(s), 2 webshell(s)
admin: ID=41 wpsvc_2e1487df8abb <[email protected]> (2026-07-19 06:41:48)
webshell: .../wp-content/plugins/security-headers-manager-8d1d21/security-headers-manager-8d1d21.php
[clean] /var/www/other-site.com
----------------------------------------------------------------
scanned=812 clean=811 compromised=1 cleaned=0
Nettoyer un site en production ne nettoie PAS vos sauvegardes. Une sauvegarde, un instantané ou un modèle de staging/blueprint capturé pendant que le site était compromis contient toujours le compte administrateur de l'attaquant — le restaurer (ou en provisionner un nouveau site) ré-infecte instantanément. Nous l'avons appris à nos dépens : après avoir nettoyé tous les sites en production concernés, de nouveaux sites continuaient d'apparaître avec la porte dérobée, car ils étaient provisionnés à partir d'un instantané de modèle empoisonné.
Vérifiez un dump avant de le restaurer :
./wp2shell-scan.sh --sql /path/to/backup.sql
./wp2shell-scan.sh --sql backup1.sql --sql backup2.sql.gz # repeatable, .gz supported
Le code de sortie est 1 si l'un des dumps est empoisonné. Le cas échéant : ne le restaurez pas — nettoyez d'abord le site en production, puis effectuez une nouvelle sauvegarde, et supprimez/remplacez tout instantané ou modèle créé pendant votre fenêtre d'exposition.
--clean supprime l'admin + le webshell et fait pivoter les sels. Vous devez quand même :
wp core verify-checksums).?c=./wp-json/batch/v1, ?rest_route=/batch/v1, y compris encodé en %2f). Placez-la à l'origine si un CDN risque de laisser passer le chemin REST.Administrateurs frauduleux :
SELECT u.ID,u.user_login,u.user_email,u.user_registered
FROM wp_users u JOIN wp_usermeta m ON u.ID=m.user_id
WHERE m.meta_key='wp_capabilities' AND m.meta_value LIKE '%administrator%'
ORDER BY u.user_registered DESC;
Plugins webshell :
find wp-content/plugins -maxdepth 1 -type d -regextype posix-extended -regex '.*-[0-9a-f]{6}$'
grep -rl "\$_GET\['c'\]" wp-content/plugins/
Consultez CLEANUP-WITH-CLAUDE.md pour un prompt prêt à coller qui guide Claude Code (ou tout agent de codage capable) à travers la même détection et le même nettoyage sur un seul site, avec confirmation humaine avant chaque étape destructive.
MIT — voir LICENSE. Fourni tel quel, sans garantie. Conçu et éprouvé sur le terrain lors d'un incident réel par l'équipe d'InstaWP.