
Détections Zeek et Suricata pour « php2shell » CVE-2026-109618 et CVE-2026-109619
Détections Zeek et règles Suricata pour les indicateurs HTTP associés à « php2shell » CVE-2026-109618 / CVE-2026-109619, RCE potentielle dans la gestion mémoire longjmp() de PHP. Les résultats identifient un trafic suspect ou des logiciels potentiellement affectés.
Nécessite Zeek 7.0.0 ou version ultérieure. Installer avec le gestionnaire de paquets Zeek :
zkg install https://github.com/corelight/php2shell-detect
Chargez les paquets installés avec @load packages dans votre configuration Zeek.
Pour une extraction directe, chargez /path/to/php2shell-detect/scripts.
Le paquet utilise les API standard Zeek HTTP, file-analysis, notice et cluster.
Le paquet inspecte les longueurs des noms de champs POST, certaines structures de données sérialisées et les en-têtes MIME répétés. Il corrèle également des transactions suspectes liées à l'aide des cookies de session configurés. Les en-têtes de réponse fournissent un inventaire distinct des versions PHP. Le trafic doit être visible par l'analyseur HTTP de Zeek ; le HTTP chiffré nécessite un déchiffrement avant inspection.
Tous les types de notices sont sous PHP2SHELL:: :
| Notice | Observation |
|---|---|
PHP_Crash_Sequence | Transactions HTTP suspectes liées au sein d'une même session |
Multipart_Header_Flood | Répétition excessive d'en-têtes MIME reconnus |
Large_Form_Key | Nom de champ de formulaire encodé en URL anormalement long |
Serialized_Integer_Overflow | Jeton entier sérialisé anormalement grand |
Serialized_Integer_Collisions | Motif de clé entière sérialisée reconnu |
Serialized_String_Collisions | Motif de clé chaîne sérialisée reconnu |
Serialized_Duplicate_Array | Motif d'entrée de tableau sérialisé répété |
Serialized_Object_Repetition | Motif d'objet sérialisé répété |
Potentially_Affected_PHP_Version | L'en-tête de réponse annonce une version dans la plage affectée configurée |
Les résultats sont écrits dans le notice.log standard ; le paquet ne crée
aucun flux de journal supplémentaire. Le champ sub de la notice fournit un
contexte borné tel que le nom d'en-tête, la profondeur de transaction, les
comptages et un court échantillon échappé du corps POST. Les échantillons sont
limités à 64 octets bruts avant échappement par défaut ; définissez
notice_body_sample_bytes=0 pour les omettre. Les cookies et leurs empreintes
sont utilisés uniquement en mémoire et ne sont pas journalisés par ce paquet.
Par défaut, chaque indicateur de requête distinct peut émettre une notice par
transaction. Les correspondances répétées du même indicateur sont supprimées.
Définissez detect_only_once=T pour arrêter l'inspection du corps après la
première détection de requête dans chaque transaction. Les notices d'inventaire
de version sont indépendantes des détections de requête.
Tous les paramètres utilisent l'espace de noms PHP2SHELL:: :
| Paramètre | Valeur par défaut | Effet |
|---|---|---|
detect_only_once | F | Signaler chaque indicateur de requête distinct ; T arrête après la première détection |
max_trans_depth | 3 | Inspecter les trois premières transactions HTTP par connexion ; 0 signifie toutes |
inspect_cookies | T | Utiliser les cookies de session pour la corrélation |
session_cookie_names | {"PHPSESSID"} | Noms de cookies utilisés pour associer les sessions |
correlation_window | 1 min | Âge maximal de l'état de corrélation de session en attente |
max_pending_sessions | 1000 | Limite des entrées conservées dans chaque table de corrélation |
inspect_post_bodies | T | Inspecter les données d'entité POST et les en-têtes MIME |
http_body_analysis_byte_depth | 8388608 | Plafond conservateur de 8 MiB sur le travail d'inspection du corps POST, partagé entre les parties MIME ; 0 désactive la livraison du corps |
body_overlap_bytes | 256 | Chevauchement conservé pour les motifs traversant les fragments de corps |
large_form_key_bytes | 65536 | Seuil en octets sur le fil pour les noms de formulaire |
multipart_header_threshold | 128 | En-têtes MIME reconnus répétés nécessaires pour une détection |
notice_body_sample_bytes | 64 | Nombre maximal d'octets bruts du corps par échantillon de notice ; 0 omet les échantillons |
detect_affected_php_versions | T | Activer l'inventaire des versions à partir des en-têtes de réponse |
php_version_notice_interval | 1 hr | Supprimer les notices de version par IP de serveur, tous ports et versions confondus |
php_fixed_patch_versions | 8.2: 35, 8.3: 36, 8.4: 27, 8.5: 12 | Premier correctif de correction provisoire par branche |
Par exemple :
redef PHP2SHELL::detect_only_once = T;
redef PHP2SHELL::notice_body_sample_bytes = 0;
redef PHP2SHELL::session_cookie_names += { "custom_session" };
L'inspection POST utilise des blocs d'analyse de fichiers avec un chevauchement borné, plutôt que l'assemblage de corps entiers. Le comptage des noms de formulaires respecte les séparateurs de valeurs et la terminaison NUL brute. Seules les entités POST éligibles reçoivent un analyseur ; les budgets de corps et les limites de transaction restreignent intentionnellement la portée de la détection. Ces indicateurs sont incomplets et peuvent également correspondre à du trafic bénin.
Dans un cluster Zeek, les workers routent les petites observations de session vers les proxies avec Cluster::publish_hrw(). Les deux étapes pour la même session atteignent le même proxy, qui les met en correspondance et déclenche directement PHP_Crash_Sequence. La notice conserve l'ID de connexion, l'UID et la profondeur de transaction du suivi ; peer_descr identifie le proxy. Les workers ne conservent pas les enregistrements complets de connexion ou HTTP pour les callbacks.
Les déclencheurs et les suivis non appariés expirent après correlation_window, avec max_pending_sessions limitant chaque table. Les proxies conservent le premier suivi non apparié pour chaque clé de session. Un déclencheur recherche directement cette clé pour gérer les messages arrivant dans l'ordre inverse ; les suivis non appariés ultérieurs pour la même clé sont fusionnés jusqu'à ce que cette entrée corresponde ou expire. La mise en correspondance utilise les horodatages d'observation et le client, le serveur, le port du serveur, l'hôte HTTP et le digest de session. Zeek en mode autonome corrèle localement. Une connectivité proxy normale est requise.
Les notices de proxy utilisent la suppression standard des notices, indexée par UID et profondeur de transaction, pour correlation_window. Cela est indépendant des résultats des workers et n'arrête pas l'inspection des corps par les workers. Des correspondances simultanées pour différents cookies de session sur différents proxies peuvent encore produire des notices en double avant que la suppression du cluster ne se propage.
Les en-têtes de réponse externes Server et X-Powered-By sont vérifiés, y compris les réponses aux requêtes GET. Les noms d'en-têtes sont insensibles à la casse. La borne inférieure affectée est PHP 5.4.0. Les seuils suivants supposent que le prochain correctif après les dernières versions stables vérifiées le 18 octobre 2026 corrigera les deux bugs :
| Branche | Dernière version stable au moment de la vérification | Première version corrigée provisoire |
|---|---|---|
| 8.2 | 8.2.34 | 8.2.35 |
| 8.3 | 8.3.35 | 8.3.36 |
| 8.4 | 8.4.26 | 8.4.27 |
| 8.5 | 8.5.11 | 8.5.12 |