
Script de triage en lecture seule pour les sites WordPress après PHP2Shell (CVE-2026-109618, CVE-2026-109619). Vérifie les signes de compromission et écrit un rapport par site.
Un script de triage en lecture seule pour les sites WordPress après PHP2Shell (CVE-2026-109618 et CVE-2026-109619), la paire de bugs critiques d'exécution de code à distance dans le moteur PHP divulgués le 21 octobre 2026.
Corriger PHP ferme la porte, mais les honeypots d'Amazon ont enregistré une tentative d'exploitation le 17 octobre, quatre jours avant la divulgation publique, alors que les bugs étaient encore sous embargo. Il s'agit de l'activité la plus ancienne publiée à ce jour, et non du jour où les attaques ont commencé ; considérez-la donc comme un plancher. Tout site qui était joignable sur un PHP non corrigé pendant cette fenêtre peut déjà héberger une porte dérobée, et la mise à jour de PHP ne la supprimera pas. Ce script vérifie un ou plusieurs sites WordPress à la recherche des traces qu'un attaquant disposant de l'exécution de code laisse typiquement derrière lui, et écrit un rapport Markdown pour chacun.
Un troisième bug, CVE-2026-115560, a été annoncé le 23 octobre. Il n'existe
pas encore de version corrigée : les versions ponctuelles d'octobre (8.2.35,
8.3.36, 8.4.27, 8.5.12) ne le couvrent pas, et le correctif est attendu avec la
prochaine version régulière en novembre. php.net demande à chacun de définir
session.upload_progress.enabled=0 dans php.ini ou dans le pool PHP-FPM en
attendant. Le script vérifie si cela a été fait.
Il ne modifie ni ne supprime jamais rien. Il liste, vérifie et rapporte. Ce qu'il faut faire des résultats vous appartient.
| Zone | Vérification |
|---|---|
| PHP | Version CLI installée vs. les versions corrigées (8.2.35, 8.3.36, 8.4.27, 8.5.12). Signale les branches en fin de vie, qui n'ont reçu aucune version de php.net ; voir Branches PHP plus anciennes. |
| Progression d'upload | Si session.upload_progress.enabled=0, l'atténuation de CVE-2026-115560, est défini là où cela compte : la vue propre de PHP-FPM (php-fpm -i), chaque php.ini lisible, conf.d, les pools FPM et la configuration Apache. Les .user.ini et .htaccess au niveau du site sont signalés mais non pris en compte, car php.net indique qu'ils ne fonctionnent pas pour ce réglage. |
| Intégrité du cœur | wp core verify-checksums par rapport à wordpress.org |
| Intégrité des extensions | wp plugin verify-checksums --all, et liste les extensions premium/personnalisées qu'il ne peut pas vérifier |
| Uploads | Tout fichier exécutable en PHP sous wp-content/uploads (ignore les stubs « Silence is golden ») |
| Modifications récentes | Fichiers PHP et de configuration modifiés depuis le début de la fenêtre (par défaut 2026-10-17). Les packs de traduction WordPress (wp-content/languages/**/*.l10n.php) sont comptés séparément une fois qu'ils passent un test de forme strict ; un fichier qui échoue à ce test est signalé. |
| Hooks de prépension | auto_prepend_file / auto_append_file dans .user.ini, .htaccess, php.ini |
| Extensions must-use | Contenu de wp-content/mu-plugins (s'exécute à chaque requête, masqué de la liste normale des extensions) |
| Motifs de code | Signatures classiques de web-shell (eval(base64_decode(...)), $_POST[...](), etc.) dans wp-content |
| Utilisateurs | Tous les administrateurs, et tout compte enregistré pendant la fenêtre |
| Base de données | siteurl/home, options et articles contenant des scripts injectés ou du code obfusqué |
| Cron | Événements planifiés WP-Cron |
| Journaux | Journaux d'accès : réponses 5xx par jour pour la fenêtre vs. une référence allant jusqu'à 7 jours avant, plus les URL renvoyant des 5xx pendant la fenêtre. Journaux d'erreurs et PHP-FPM : plantages de workers (segfault/bus error). |
| Serveur | La crontab de l'utilisateur du site et les authorized_keys SSH |
| Docker | Chaque conteneur en cours d'exécution avec un binaire php : la version de PHP à l'intérieur, et si le conteneur exécute encore une version plus ancienne que l'image sur disque (tirée mais non recréée) |
WP-CLI est exécuté avec --skip-plugins --skip-themes afin qu'une extension ou
un thème piégé ne puisse pas s'exécuter pendant la vérification.
Sur chaque machine vérifiée :
bash 3.2+, find, grep et sort -V (standard sur les hôtes Linux ; fonctionne aussi depuis un poste de travail macOS standard)php dans le PATH, pour la vérification de versionPour les sites distants : accès par clé SSH depuis la machine sur laquelle vous exécutez le script. Le script s'exécute lui-même via SSH ; rien ne doit être installé sur l'hôte distant au-delà de ce qui précède.
curl -O https://raw.githubusercontent.com/brentmartinmiller/php2shell-check/main/php2shell-check.sh
chmod +x php2shell-check.sh
# One site
./php2shell-check.sh /var/www/example.com
less php2shell-reports/*.md
# Every site on the box
printf '%s\n' /var/www/*/public_html > sites.txt
./php2shell-check.sh sites.txt
cat php2shell-reports/SUMMARY.md
Exécutez-le en tant qu'utilisateur qui possède les fichiers du site lorsque c'est possible. Il fonctionne en tant que root
(WP-CLI reçoit --allow-root), mais les vérifications de crontab et de clé SSH inspectent alors
celles de root au lieu de celles de l'utilisateur web.
git clone https://github.com/brentmartinmiller/php2shell-check.git
cd php2shell-check
cp sites.txt.example sites.txt # edit: one site per line
./php2shell-check.sh sites.txt
Pour chaque entrée user@host:path, le script se connecte en SSH, s'y exécute, et
rapporte le rapport dans php2shell-reports/ sur votre machine. Rien n'est
installé sur l'hôte distant. SSH s'exécute avec BatchMode=yes, donc un accès par clé fonctionnant sans invite de mot de passe est requis.
La plupart des hébergeurs mutualisés (Hostinger, SiteGround, Bluehost et similaires) proposent SSH mais
n'ont souvent pas wp dans le path. Vérifiez avec which wp. S'il est absent,
téléchargez WP-CLI une fois dans votre répertoire personnel et indiquez-le au script :
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
WP="php $HOME/wp-cli.phar" ./php2shell-check.sh domains/example.com/public_html
Sans WP-CLI, les vérifications du système de fichiers s'exécutent quand même et le rapport indique ce qui a été ignoré. Dans les deux cas, demandez directement à l'hébergeur quand il a déployé le PHP corrigé, car c'est la seule chose qu'une vérification au niveau du compte ne peut pas voir.
sites.txt contient un site par ligne, soit un chemin local, soit user@host:path.
Les chemins distants relatifs sont relatifs au répertoire personnel de l'utilisateur SSH. Les lignes
commençant par # sont ignorées. Voir sites.txt.example. Le fichier est dans
.gitignore afin que les noms d'hôte des clients ne finissent pas dans un commit.
Les ports SSH non standard, les clés et les hôtes de rebond se configurent dans ~/.ssh/config :
Host client-a
HostName 203.0.113.10
Port 2222
User deploy
IdentityFile ~/.ssh/client-a
Puis listez le site comme client-a:/var/www/html.
php -v sur un hôte Docker ne vous apprend rien sur les conteneurs, et tirer
une image figée ne corrige rien tant que le conteneur n'est pas recréé à partir
de celle-ci. Le site d'une équipe est resté sur 8.3.35 pendant trois jours après
le pull, précisément pour cette raison.