Le 21 octobre 2026, le projet PHP a publié les correctifs de deux failles critiques du moteur lui-même, CVE-2026-109618 et CVE-2026-109619, que chercheurs et presse ont baptisées PHP2Shell. Le lendemain matin, nous avons posé une question simple à notre propre outil : un client qui aurait lancé Darkmoon ce jour-là sur un site PHP vulnérable aurait-il été prévenu ? Non. Les agents ont lu la version vulnérable exacte dans les en-têtes de réponse, puis l’ont rangée parmi les simples divulgations d’information. Cet article documente ce résultat négatif, ce que nous avons modifié dans les agents, la validation face à un témoin corrigé, et ce qui ne va pas encore.
Le périmètre, d’emblée. Il s’agit de détecter une CVE du runtime (une faille située sous l’application, dans l’interpréteur qui la sert) et de prouver un niveau de correctif par HTTP. Nous n’avons pas exploité PHP2Shell, nous ne publions aucun élément d’exploitation, et rien ici ne prétend que Darkmoon détecte toutes les vulnérabilités PHP. Chaque validation décrite est un essai unique, sur un lab que nous avons construit.
PHP2Shell en une page
Les deux failles sont publiques et corrigées. Tout ce qui suit provient des avis PHP, de la NVD et du CERT-EU, lus à la source [1][3][4][7]. L’avis de php.net n’emploie pas le surnom ; Wiz, Huntress et Help Net Security, si [8][9][10].
| Élément | CVE-2026-109618 | CVE-2026-109619 |
|---|---|---|
| Titre php-src | RCE via OOM corruption | RCE via stale global state |
| Cause (avis) | longjmp() sur manque de mémoire : des données de requête restent à moitié initialisées, le nettoyage les croit valides | un état global pointe encore vers la mémoire libérée d’une requête ; la requête suivante du même worker l’utilise avant réinitialisation |
| Versions affectées | < 8.2.35, < 8.3.36, < 8.4.27, < 8.5.12 | idem |
| Versions corrigées | 8.2.35, 8.3.36, 8.4.27, 8.5.12 | idem |
| CVSS v4.0 (PHP, CNA) | 9,2, AV:N/AC:H/AT:P/PR:N/UI:N | 9,2, même vecteur |
| CVSS 3.1 (NVD) | 9,8 | 8,1 |
| CWE (NVD) | CWE-416 | CWE-416 |
Le mécanisme, au niveau utile à un défenseur. Quand une requête manque de mémoire, PHP l’abandonne en sautant hors du contexte courant. À certains endroits, ce saut survient alors que des structures de requête ne sont qu’à moitié construites, et le nettoyage qui suit les lit comme si elles étaient complètes [3]. La seconde faille concerne un état qui survit à sa requête : un worker conserve un pointeur global vers une mémoire qui appartenait à la requête précédente, et du code exécuté très tôt dans la requête suivante (l’avis cite les diagnostics INI précoces et la progression d’envoi de session) peut la lire ou la libérer [4]. Le correctif de la première supprime ce saut pour les manques de mémoire. Il s’agit de bugs de sûreté mémoire du moteur : le code applicatif n’y change rien, et Wiz note qu’un simple « Hello World » sur une version affectée peut être vulnérable [8].
Deux détails de notation comptent pour le tri. Le score du CNA est CVSS v4.0 9,2 pour les deux ; la NVD, avec son propre calcul CVSS 3.1, donne 9,8 et 8,1 [5][6]. Les outils qui lisent la NVD afficheront donc d’autres chiffres pour le même avis. Par ailleurs, au moment où nous écrivons, aucune des deux CVE ne figure au catalogue Known Exploited Vulnerabilities de la CISA (version 2026.10.23) [12]. Cette absence ne prouve pas qu’il n’y a pas d’exploitation : le CERT-EU indique que des preuves de concept initiales « commencent à circuler » [7], et Help Net Security relaie un signalement d’Amazon Threat Intelligence faisant état d’une tentative d’exploitation captée par ses honeypots le 17 octobre, avant la divulgation [10] ; nous ne l’avons pas vérifié nous-mêmes. Le 23 octobre, php.net a publié un autre problème, moins risqué, dans la même zone (CVE-2026-115560, progression d’envoi de session sous une configuration inhabituelle) [2] ; il n’est pas couvert par ce travail.
Conditions d’exploitation, vues du défenseur
- Ni authentification ni bug applicatif. Il suffit d’atteindre un point d’entrée PHP en HTTP.
- Tous les SAPI qui servent des requêtes web sont concernés : PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, LiteSpeed. php.net juge mod_php le plus exposé, avec une exploitation démontrée avant l’exécution du moindre code applicatif [1].
- La réutilisation des workers compte pour CVE-2026-109619 : il faut une requête « productrice » et une requête « consommatrice » traitées par le même worker [4].
- La fiabilité varie. Selon Wiz, l’exploitation doit s’adapter à la disposition mémoire de chaque cible, et les différences de version, de configuration ou d’application peuvent casser les hypothèses d’un exploit [8]. Ce n’est pas une raison d’attendre : le même billet décrit une RCE non authentifiée sur des images WordPress, Drupal et Joomla standard.
- Le trafic d’attaque est un trafic multipart inhabituel. Wiz conseille de surveiller des requêtes multipart atypiques suivies d’erreurs de limite mémoire ou de rafales de HTTP 500, des cookies de session démesurés ou malformés, et un renouvellement inexpliqué des workers ; Huntress ajoute les workers PHP qui lancent des shells ou des outils de téléchargement [8][9].
Politique de divulgation de cet article
Pourquoi les numéros de version trompent
Puisque nos agents ne doivent pas exploiter un bug de corruption mémoire, la preuve doit être la version. Cela paraît trivial, jusqu’à ce qu’on regarde d’où viennent les versions.
- La CLI n’est pas le runtime web. Le jour même, nous avons vérifié l’une de nos propres applications PHP exposées sur Internet. Les binaires
phpen ligne de commande présents sur la machine annonçaient des versions sans rapport avec celle qui servait le site. Seule une sonde éphémère exécutée par le SAPI web a donné la vraie réponse (déjà corrigée, en l’occurrence). Notre déploiement relance désormais cette sonde à chaque mise en production et échoue sous le plancher corrigé. - Proxys et CDN peuvent mentir dans les deux sens. Un en-tête
X-Powered-Bypérimé peut survivre à une mise à jour derrière un cache : un seul en-tête ne suffit pas. - Les distributions rétroportent. Une chaîne comme
8.1.2-1ubuntu2.xou+debNuMpeut contenir le correctif sans que le numéro amont change. - Les versions masquées sont courantes. Avec
expose_php=Off, il n’y a rien à lire, et deviner à partir de l’OS ou de la version du CMS n’est pas une preuve.
Méthode : un lab, une seule variable
Pour mesurer la détection plutôt que raconter une anecdote, nous avons monté un lab A/B : deux conteneurs issus des images officielles, la dernière 8.3 vulnérable et la première corrigée, qui servent la même application de 20 lignes (une session et un formulaire d’envoi de fichier, les chemins de requête dont parlent les avis). Le conteneur corrigé sert de témoin négatif : si Darkmoon le signale aussi, la détection ne vaut rien.
# labs/php2shell/docker-compose.yml (notre lab interne ; extrait : commentaires d'en-tête,
# noms de conteneurs et politique de redémarrage omis)
name: darkmoon-labs-php2shell
services:
php2shell-vulnerable:
image: php:8.3.35-apache # dernière 8.3 avant le correctif
ports: ["127.0.0.1:19110:80"]
volumes: ["./app:/var/www/html:ro"]
php2shell-patched:
image: php:8.3.36-apache # témoin négatif : ne doit PAS être signalé
ports: ["127.0.0.1:19111:80"]
volumes: ["./app:/var/www/html:ro"]
# app/index.php : 20 lignes, session_start() et un formulaire d'envoi multipartLes deux campagnes ont reçu la même consigne, au mot près, qui ne mentionne ni PHP ni aucune CVE ; le même modèle (claude-opus-4-6) ; le même conteneur d’outils. Seuls changeaient les fichiers des sept agents de la famille PHP. La consigne, conservée en anglais comme elle a été envoyée :
TARGET: http://127.0.0.1:19110 and http://127.0.0.1:19111. Two internet-facing
web applications of a customer (authorized lab, full scope, black-box). Run a
complete security assessment of both, dispatch the right specialists, report
every vulnerability with evidence, and finalize the campaign.D’abord, un résultat négatif
La campagne 1 (22 octobre, 08:17 UTC) a tourné avec les fichiers d’agents en service depuis juillet. Bilan : 39 findings, dont 0 critique, 0 élevé, 14 moyens, 20 faibles et 5 informatifs. L’agent PHP a bien lu PHP/8.3.35, et l’a classé ainsi :
// campagne 1 (agents en service depuis juillet), extrait du finding enregistré
{ "title": "Server Version and Technology Stack Disclosure via HTTP Headers",
"severity": "info", "cvss_score": 0.0, "cve": null, "status": "confirmed",
"endpoint": "http://127.0.0.1:19110/", "discovered_by_agent": "php" }
evidence.raw_response: "Server: Apache/2.4.69 (Debian) X-Powered-By: PHP/8.3.35"Trois causes, toutes visibles dans les journaux de session :
- Ce que sait le modèle. Il a été entraîné avant le 21 octobre : il ne peut pas savoir que la 8.3.35 est devenue vulnérable la veille.
- Ce que sait le scanner. Les templates Nuclei locaux dataient du 26 septembre et tournaient sans vérification de mise à jour. Un rejeu du 23 octobre n’a trouvé aucun template citant l’une ou l’autre CVE dans ce dossier. En amont, un template avait déjà été publié (vulnx l’indiquait le 22 octobre) : une boîte à outils à jour l’aurait eu, la nôtre non, comme beaucoup d’installations réelles.
- Un outil disponible, jamais appelé. vulnx, qui interroge une base de vulnérabilités à jour, était installé et autorisé ; les deux sessions de l’agent PHP de la campagne 1 l’ont appelé zéro fois. Les agents se contentaient de la passe Nuclei générique commune à tous,
-tags exposure,misconfig,tech-detect.
La donnée était là. Aucun maillon ne la reliait à une CVE publiée la veille.
Ce que nous avons changé dans les agents
Darkmoon repose sur un orchestrateur (pentest) qui identifie la cible et lance des agents spécialisés ; un agent est un fichier de consigne Markdown exécuté par le moteur dans les limites d’une liste d’outils autorisés (voir comment les empreintes techniques déclenchent les agents PHP et l’architecture des agents spécialisés). Nous n’avons touché qu’aux fichiers d’agents, en deux commits, tous deux publiés sur le dépôt public[13][14] :
| Commit (ASCIT31/Dark-Moon) | Date | Contenu | Statut |
|---|---|---|---|
| 9dbb9c4 | 22 oct. 2026 | bloc PHP RUNTIME CVE CHECK dans php, wordpress, drupal, joomla, magento, moodle, prestashop ; le signal PHP de l’orchestrateur transmet la ligne X-Powered-By / Server brute ; un script générateur ; un garde-fou de non-régression | implémenté, testé en lab, publié |
| 2b20a2c | 25 oct. 2026 | bloc TARGETED VULN SWEEP dans 36 agents web et services, une ligne TECH PROFILE par agent (tags Nuclei et requête vulnx) ; script générateur ; garde-fou de non-régression | implémenté, testé sur un passage d’agent, publié |
Bloc 1 : le contrôle des CVE du runtime PHP (voie rapide)
Un bloc identique à l’octet près, produit par tools/agent-build/php_runtime_cves.py et inséré entre marqueurs dans les sept agents de la famille PHP. Les CVE du runtime vivent sous l’application : un agent WordPress ou Drupal qui étudie le CMS et ses extensions ne regarderait jamais l’interpréteur. Le bloc s’exécute une fois par hôte et port PHP, avant les modules applicatifs, en six étapes : relever passivement la version sur deux réponses servies par PHP ; comparer par branche aux versions corrigées ; ne jamais exploiter ; qualifier ; pousser un finding avec la preuve brute et la remédiation de php.net ; puis lancer une recherche vulnx bornée pour les CVE du runtime plus récentes que la table.
Bloc 2 : le balayage ciblé (généralisation)
Une table écrite à la main marche pour une CVE et vieillit dès qu’on l’écrit. Trois jours plus tard, nous avons généralisé la méthode plutôt que la table : chaque agent web ou de service qui identifie un produit et une version embarque le même balayage, cadré par une seule ligne de profil (pour l’agent PHP, nuclei tags: php,apache,fpm et vulnx query: php). Il ne se déclenche qu’une fois un produit confirmé, jamais sur une cible nue ; interroge d’abord vulnx, peu coûteux, qui dit si un template Nuclei existe ; ne lance Nuclei que sur les identifiants de CVE trouvés ; ne se rabat sur une passe par tags, bornée aux sévérités critique et élevée, que si aucune version n’a pu être lue ; et tient dans un budget de 90 secondes. Un produit qui relève d’un autre agent est signalé à l’orchestrateur, pas scanné sur place. Les 15 agents qui n’identifient pas de produit web versionné (fournisseurs cloud, IaC et gestion de configuration, Docker et Kubernetes, GitHub, identité et Active Directory, firmware, mobile, LLM, l’agent navigateur et l’orchestrateur lui-même) sont exclus à dessein.
Pourquoi vulnx d’abord : des mesures uniques prises pendant la mise au point donnent environ 2 s pour une recherche vulnx, environ 4,6 s pour Nuclei limité à un identifiant de CVE, et 45 à 48 s pour la passe par tags la plus lourde essayée (1 283 templates WordPress contre une cible qui n’en relevait pas). Trier par coût garde le balayage dans son budget.
Frontière open source
Détection et qualification
La ligne la plus lourde de conséquences du bloc est une règle de qualification. Darkmoon plafonne normalement à « faible » tout finding qu’il ne peut pas démontrer, règle que nous gardons parce qu’une simple correspondance de version n’est en général pas une preuve. Appliqué ici, ce plafond aurait noyé une RCE critique parmi les divulgations d’en-têtes. Le bloc pose donc une exception explicite et étroite : quand l’avis de l’éditeur nomme exactement la version observée, l’avis tient lieu d’impact démontré. Le statut estconfirmed (version-matched), jamais exploited ; la sévérité est celle de l’avis. L’exception a trois garde-fous : la version doit être lue sur deux réponses PHP (sinon le finding reste non confirmé), un suffixe de distribution la ramène à « potentiellement vulnérable, élevé » avec la consigne de vérifier l’avis de l’éditeur, et une version masquée ne produit aucun finding.
Résultats de validation
| Essai | Date (UTC) | Ce qui a tourné | Résultat |
|---|---|---|---|
| Campagne 1, référence | 22 oct., 08:17 | campagne complète, agents de juillet | 39 findings, 0 critique ; PHP 8.3.35 classé en info sur 19110 |
| Campagne 2, après bloc 1 | 22 oct., 09:08 | même consigne, modèle, outils ; 7 agents PHP remplacés | 37 findings, 1 critique : PHP2Shell sur 19110 seulement ; rien sur PHP2Shell pour 19111 |
| Rejeu | 23 oct., 07:36 | les commandes curl de l’agent, à la main | 19110 PHP/8.3.35, 19111 PHP/8.3.36 ; 0 template Nuclei local pour ces CVE |
| Balayage, agent PHP seul | 25 oct. | bloc 2, agent php lancé directement sur le conteneur vulnérable | vulnx search et vulnx id sur les deux CVE, Nuclei positif, finding critique poussé, aucun scan à l’aveugle |
| Balayage, campagne complète | 25 oct. | orchestrateur sur le conteneur vulnérable | l’orchestrateur n’a pas lancé l’agent PHP ; il a trouvé lui-même CVE-2026-109618 par de larges passes Nuclei et l’a classée en déni de service ; voir les limites |
| Garde-fou de non-régression | 25 oct., 18:35 | tools/check-no-regression.sh sur le dépôt public | PASS : bloc 1 dans les 7 agents, bloc 2 présent dans tous les agents profilés et absent ailleurs |
Le finding critique de la campagne 2, tel qu’enregistré :
// campagne 2 (7 agents de la famille PHP remplacés, rien d'autre), extrait du finding enregistré
{ "title": "PHP runtime vulnerable to PHP2Shell unauthenticated RCE
(CVE-2026-109618, CVE-2026-109619): PHP 8.3.35",
"severity": "critical", "cvss_score": 9.2, "status": "confirmed",
"plugin_or_component": "php 8.3.35 (mod_php / Apache 2.4.69)",
"endpoint": "http://127.0.0.1:19110/", "mitre_attack_id": "T1190" }
evidence.commands: curl -sk -o /dev/null -D - --max-time 15 http://127.0.0.1:19110/
curl -sk -o /dev/null -D - --max-time 15 http://127.0.0.1:19110/index.php
evidence.explanation: "... consistently identified via the X-Powered-By header on two
independent PHP-served routes ... Not exploited by design ..."Sur le témoin corrigé, l’agent a écrit à 09:17:34 que la 8.3.36 est la version corrigée et qu’aucun finding de runtime n’était à pousser ; la synthèse de la campagne précise que le port 19111 est corrigé. La recherche vulnx bornée a listé les deux CVE (1,9 s) et l’agent en a conclu qu’aucune autre CVE du runtime ne s’appliquait.
Nous publions aussi les imperfections visibles dans les journaux, car elles font partie du résultat. Les commandes du bloc utilisent timeout, absent de la liste d’outils autorisés de Darkmoon : le premier appel a échoué et l’agent a relancé avec curl --max-time. Le premier envoi du finding critique a été refusé faute de description, puis corrigé 25 secondes plus tard. Le modèle a d’abord écrit « This is the fixed version », puis « wait, let me re-check », avant de conclure correctement. Enfin, dans la campagne 2, l’orchestrateur, qui lit le fichier de l’agent avant de le lancer, a ajouté de lui-même dans le contexte transmis pour 19111 que cette cible tourne en version corrigée ; pour la cible vulnérable, le contexte ne contenait que des faits. Dans les deux cas, la connaissance venait du nouveau bloc, pas de la consigne.
Limites et faux positifs
Ce que cette détection ne voit pas
- Les versions masquées. Avec
expose_php=Offet aucune version ailleurs, le bloc 1 ne signale rien, par construction. Un sondage actif répondrait, à un coût que nous refusons sur des cibles en production. - Les rétroportages. Un paquet de distribution corrigé peut porter un vieux numéro amont. Le bloc le signale « potentiellement vulnérable » : c’est un faux positif chaque fois que l’éditeur a bien rétroporté le correctif, et seul son avis tranche.
- Les en-têtes périmés. La double lecture repère un proxy qui injecte un en-tête incohérent, pas un proxy qui réécrit toutes les réponses de la même façon.
- Un essai par condition. Ce sont des démonstrations reproductibles sur un lab, pas des statistiques. Les sorties du modèle varient d’un essai à l’autre.
Ce que nous avons trouvé de travers dans notre propre travail
- La règle « non destructif » n’est pas imposée par la ligne de commande. Le balayage interdit d’ajouter les tags
intrusiveoudos, mais le template Nuclei amont de CVE-2026-109618 est un template de détection active par plantage qui porte lui-même le tagintrusive, et une passe par tags produit (-tags php,...) le sélectionne. C’est exactement ce qui s’est produit le 25 octobre contre notre lab. La voie précise (nuclei -id <CVE>) sélectionnerait le même template, puisque le bloc laisse à l’agent le soin de juger si un template est non destructif. Le correctif consiste à exclure explicitement ces tags ; il est conçu, pas encore implémenté. - Le texte du finding a repris des affirmations tierces non vérifiées. Dans ce même essai du 25 octobre, le finding poussé portait le 9,8 de la NVD au lieu du 9,2 de l’avis inscrit dans le bloc, et sa description affirmait une « exploitation active » sur la foi de la sortie de vulnx (données VulnCheck KEV), que nous n’avons pas vérifiée et que le KEV de la CISA ne mentionne pas. La sévérité était juste ; le récit allait plus loin que nos preuves.
- L’agent a pris la voie de repli. Dans le même essai, la version était connue : la doctrine demande Nuclei sur les seuls identifiants de CVE trouvés ; l’agent a lancé la passe par tags bornée. Le résultat était juste, le chemin n’était pas celui écrit.
- Sans lancement de l’agent, pas de bloc. Sur une cible unique et simple, l’orchestrateur fait parfois le travail lui-même au lieu de lancer un spécialiste. Dans la campagne complète du 25 octobre, il a lancé de larges passes Nuclei (l’une avec un délai de dix minutes), trouvé la CVE grâce au template et l’a classée en déni de service. Les blocs n’aident que si l’agent spécialisé tourne vraiment.
- Le bruit hors sujet demeure. Les deux campagnes signalent un « envoi de fichier sans restriction », de sévérité moyenne, sur les deux conteneurs. L’application ne stocke jamais le fichier ; la synthèse de la campagne 2 le dit, mais le finding reste.
- Les scanners ont aussi leurs faux positifs. Le README du scanner d’Assetnote note qu’un PHP corrigé peut renvoyer la même réponse HTTP 500 vide qu’un PHP vulnérable lorsqu’une sonde dépasse
memory_limit[11]. Détection par plantage et détection par version échouent à des endroits différents : c’est pourquoi nos findings portent ensemble la preuve de version et l’avis.
Prouver le correctif et remédier
Ce que nous faisons sur nos propres systèmes, et ce que dit la remédiation du finding. D’abord, prouver la version du runtime qui sert les requêtes, pas celle d’un binaire présent sur la machine :
# 1. ce que dit le SAPI web (en-têtes), sur deux routes servies par PHP
curl -sk -o /dev/null -D - https://app.example/ | grep -i -E 'x-powered-by|server'
curl -sk -o /dev/null -D - https://app.example/index.php | grep -i -E 'x-powered-by|server'
# 2. si expose_php=Off masque la version : une sonde éphémère au nom aléatoire,
# servie par le MÊME vhost (déposer, lire une fois, supprimer ; jamais de phpinfo() en ligne)
<?php echo PHP_VERSION, ' ', PHP_SAPI, ' upload_progress=', ini_get('session.upload_progress.enabled');
# 3. comparer par branche : corrigé si >= 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12
# (paquets de distribution : lire l'avis de l'éditeur, le correctif peut être rétroporté)- Mettre à jour vers 8.2.35, 8.3.36, 8.4.27, 8.5.12 ou plus, ou vers le rétroportage de l’éditeur pour les branches en fin de vie (PHP a publié des rétroportages minimaux en sources pour 7.4, 8.0 et 8.1), puis redémarrer tous les workers. Seule la mise à jour corrige complètement [1].
- En attendant, réduire l’exposition (php.net, mesures toutes partielles) :
memory_limit=-1fixé là où l’application ne peut pas le modifier ; unpost_max_sizebas (8M, ou 32M si des envois sont nécessaires) avecupload_max_filesizeen dessous ;session.upload_progress.enabled=0dans php.ini ou la configuration du pool, pas viaini_set()ni.user.ini; en 8.5,fatal_error_backtraces=0. Ne pas remplacer parRLIMIT_ASouRLIMIT_DATA. Le CERT-EU ajoute des limites de taille de corps au niveau du serveur web ou du proxy, et des limites mémoire de conteneur ou de cgroup [7]. - En faire un critère de mise en production. Notre propre déploiement interroge le SAPI web après chaque release et échoue sous le plancher corrigé ; nous avons aussi vérifié à la main qu’un corps de requête trop gros est refusé par le serveur web (HTTP 413) avant que PHP ne l’analyse. Masquer la version (
expose_php=Off) relève de la bonne hygiène et ne corrige rien.
Un écart relevé en écrivant cet article : php.net cite memory_limit=-1 parmi les mesures d’attente, et le texte de remédiation de notre bloc publié ne le mentionne pas. Il sera ajouté à la prochaine révision du bloc.
Perspectives
Chaque point porte son statut réel.
- Envisagé : exclure les templates
intrusive,dos,fuzzdans toutes les commandes du balayage ; remplacertimeoutpar l’enveloppe autorisée dans le bloc 1 ; ajoutermemory_limit=-1à la remédiation. - Envisagé : faire lancer l’agent PHP par l’orchestrateur dès qu’une version du runtime PHP est vue, pour que les blocs s’exécutent aussi sur les cibles simples.
- Envisagé : publier le lab. Il vit aujourd’hui dans un dépôt interne ; l’extrait compose ci-dessus, avec une petite page qui ouvre une session et affiche un formulaire d’envoi, suffit à le reconstruire.
- Question ouverte : quand retirer le bloc 1. Une fois le balayage éprouvé sur davantage de CVE, une table écrite à la main deviendra une dette de maintenance ; d’ici là, c’est le seul chemin validé face à un témoin négatif.
Ressources complémentaires
- github.com/ASCIT31/Dark-Moon : le moteur et les agents open source. Les blocs décrits ici se trouvent dans
conf/agents/php.md(marqueursdarkmoon:php-runtime-cvesetdarkmoon:targeted-vuln-sweep), leurs générateurs danstools/agent-build/. - github.com/ASCIT31/Darkmoon-Benchmarks : nos campagnes de benchmark d’agents de pentest LLM autonomes sur des labs vulnérables, menées par l’équipe Darkmoon. Son périmètre est l’évaluation de pentest par LLM ; il ne contient pas ce lab PHP et ne valide aucune affirmation de cet article. La méthode de ces campagnes est décrite dans notre article sur le benchmark de pentest par LLM.
- À lire aussi : les cibles CMS PHP comme WordPress, et à quoi ressemble un résultat propre sur un site durci.
Références
- PHP Group, « Security advisory: Critical remote code execution vulnerabilities, update now », archive des actualités php.net, 21 octobre 2026 (entrée 2026-10-21-5), et « Upcoming Critical PHP Security Release », 20 octobre 2026. www.php.net/archive/2026.php#2026-10-21-5
- PHP Group, « Informational advisory: Session upload progress » (CVE-2026-115560), php.net, 23 octobre 2026. www.php.net/archive/2026.php#2026-10-23-1
- Avis php-src GHSA-w8hw-w9fx-j79w, « RCE via OOM corruption » (CVE-2026-109618). github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w
- Avis php-src GHSA-6wmf-4rv5-p3rp, « RCE via stale global state » (CVE-2026-109619). github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
- NIST NVD, CVE-2026-109618 (fiche lue via l’API NVD 2.0 le 25 octobre 2026). nvd.nist.gov/vuln/detail/CVE-2026-109618
- NIST NVD, CVE-2026-109619 (fiche lue via l’API NVD 2.0 le 25 octobre 2026). nvd.nist.gov/vuln/detail/CVE-2026-109619
- CERT-EU, Security Advisory 2026-018, « Critical Vulnerabilities in PHP », v1.2, 23 octobre 2026. cert.europa.eu/publications/security-advisories/2026-018
- Wiz Research, billet de recherche « PHP2Shell » (découverte, chronologie, pistes de détection). www.wiz.io/blog/php2shell-php-rce
- Huntress (J. Hammond), « Rapid Response: php2shell, Leaked Critical PHP Vulnerabilities », 20 et 21 octobre 2026. www.huntress.com/blog/php2shell-leaked-critical-php-vulnerabilities
- Help Net Security (M. Zorz), « PHP2Shell: Critical PHP vulnerabilities patched, update now! », 21 et 22 octobre 2026. www.helpnetsecurity.com/2026/10/21/php2shell-php-vulnerabilities-patched-cve-2026-109618-cve-2026-109619/
- Assetnote, php2shell-scanner (README : conception des sondes, impact réseau, faux positifs). github.com/assetnote/php2shell-scanner
- CISA, catalogue Known Exploited Vulnerabilities, flux JSON (version 2026.10.23, consultée le 25 octobre 2026). www.cisa.gov/known-exploited-vulnerabilities-catalog
- Darkmoon, commit 9dbb9c4, « feat(agents): PHP runtime CVE check — detect PHP2Shell », ASCIT31/Dark-Moon, 22 octobre 2026. github.com/ASCIT31/Dark-Moon/commit/9dbb9c4
- Darkmoon, commit 2b20a2c, « feat(agents): signal-driven targeted vuln sweep across the web/service agents », ASCIT31/Dark-Moon, 25 octobre 2026. github.com/ASCIT31/Dark-Moon/commit/2b20a2c
La preuve plutôt que le discours : le benchmark de remédiation Pro (correctifs retestés contre l'exploit) · Darkmoon face aux autres outils de pentest IA.
← Tous les articles