
Detecciones de Zeek y Suricata para "php2shell" CVE-2026-109618 y CVE-2026-109619
Detecciones de Zeek y reglas de Suricata para indicadores HTTP asociados con "php2shell" CVE-2026-109618 / CVE-2026-109619, posible RCE en el manejo de memoria longjmp() de PHP. Los hallazgos identifican tráfico sospechoso o software potencialmente afectado.
Requiere Zeek 7.0.0 o posterior. Instalar con el Zeek Package Manager:
zkg install https://github.com/corelight/php2shell-detect
Cargue los paquetes instalados con @load packages en su configuración de Zeek.
Para una instalación directa desde el repositorio, cargue /path/to/php2shell-detect/scripts.
El paquete utiliza las API estándar de Zeek para HTTP, análisis de archivos, avisos y clústeres.
El paquete inspecciona las longitudes de los nombres de campos POST, determinadas estructuras de datos serializados y encabezados MIME repetidos. También correlaciona transacciones sospechosas relacionadas mediante las cookies de sesión configuradas. Los encabezados de respuesta proporcionan un inventario separado de versiones de PHP. El tráfico debe ser visible para el analizador HTTP de Zeek; el HTTP cifrado requiere descifrado antes de la inspección.
Todos los tipos de aviso están bajo PHP2SHELL:::
| Aviso | Observación |
|---|---|
PHP_Crash_Sequence | Transacciones HTTP sospechosas relacionadas dentro de una misma sesión |
Multipart_Header_Flood | Repetición excesiva de encabezados MIME reconocidos |
Large_Form_Key | Nombre de campo de formulario codificado en URL inusualmente largo |
Serialized_Integer_Overflow | Token entero serializado inusualmente grande |
Serialized_Integer_Collisions | Patrón de clave entera serializada reconocido |
Serialized_String_Collisions | Patrón de clave de cadena serializada reconocido |
Serialized_Duplicate_Array | Patrón de entrada de array serializado repetido |
Serialized_Object_Repetition | Patrón de objeto serializado repetido |
Potentially_Affected_PHP_Version | El encabezado de respuesta anuncia una versión dentro del rango afectado configurado |
Los resultados se escriben en el notice.log estándar; el paquete no crea ningún flujo de registro adicional. El campo sub del aviso proporciona contexto acotado, como el nombre del encabezado, la profundidad de la transacción, los recuentos y una breve muestra escapada del cuerpo POST. Las muestras se limitan a 64 bytes sin procesar antes del escapado de forma predeterminada; establezca notice_body_sample_bytes=0 para omitirlas. Las cookies y sus resúmenes se utilizan solo en memoria y este paquete no las registra.
De forma predeterminada, cada indicador de solicitud distinto puede emitir un aviso por transacción. Las coincidencias repetidas del mismo indicador se suprimen. Establezca detect_only_once=T para detener la inspección del cuerpo tras el primer hallazgo en la solicitud de cada transacción. Los avisos de inventario de versiones son independientes de los hallazgos en las solicitudes.
Todas las opciones utilizan el espacio de nombres PHP2SHELL:::
| Opción | Valor predeterminado | Efecto |
|---|---|---|
detect_only_once | F | Informa cada indicador de solicitud distinto; T se detiene tras el primer hallazgo |
max_trans_depth | 3 | Inspecciona las tres primeras transacciones HTTP por conexión; 0 significa todas |
inspect_cookies | T | Utiliza las cookies de sesión para la correlación |
session_cookie_names | {"PHPSESSID"} | Nombres de cookies utilizados para asociar sesiones |
correlation_window | 1 min | Antigüedad máxima del estado de correlación de sesión pendiente |
max_pending_sessions | 1000 | Límite de entradas retenidas en cada tabla de correlación |
inspect_post_bodies | T | Inspecciona los datos de entidad POST y los encabezados MIME |
http_body_analysis_byte_depth | 8388608 | Límite conservador de 8 MiB en el trabajo de inspección del cuerpo POST, compartido entre las partes MIME; 0 desactiva la entrega del cuerpo |
body_overlap_bytes | 256 | Solapamiento retenido para patrones que cruzan fragmentos del cuerpo |
large_form_key_bytes | 65536 | Umbral de bytes en la transmisión para el nombre de formulario |
multipart_header_threshold | 128 | Encabezados MIME reconocidos repetidos necesarios para un hallazgo |
notice_body_sample_bytes | 64 | Máximo de bytes sin procesar del cuerpo por muestra de aviso; 0 omite las muestras |
detect_affected_php_versions | T | Habilita el inventario de versiones a partir de los encabezados de respuesta |
php_version_notice_interval | 1 hr | Suprime los avisos de versión por IP de servidor entre puertos y versiones |
php_fixed_patch_versions | 8.2: 35, 8.3: 36, 8.4: 27, 8.5: 12 | Primer parche corregido provisional por rama |
Por ejemplo:
redef PHP2SHELL::detect_only_once = T;
redef PHP2SHELL::notice_body_sample_bytes = 0;
redef PHP2SHELL::session_cookie_names += { "custom_session" };
La inspección POST utiliza fragmentos de análisis de archivos con solapamiento acotado, en lugar de ensamblar cuerpos completos. El conteo de nombres de formulario respeta los separadores de valores y la terminación NUL sin procesar. Solo las entidades POST elegibles reciben un analizador; los presupuestos de cuerpo y los límites de transacciones restringen intencionalmente el alcance de la detección. Estos indicadores son incompletos y también pueden coincidir con tráfico benigno.
En un clúster de Zeek, los workers enrutan pequeñas observaciones de sesión a los proxies con Cluster::publish_hrw(). Ambas etapas para la misma sesión llegan al mismo proxy, que las empareja y genera PHP_Crash_Sequence directamente. El aviso conserva el ID de conexión, el UID y la profundidad de transacción del seguimiento; peer_descr identifica al proxy. Los workers no conservan los registros completos de conexión o HTTP para las devoluciones de llamada.
Los disparadores y los seguimientos no emparejados expiran tras correlation_window, con max_pending_sessions limitando cada tabla. Los proxies conservan el primer seguimiento no emparejado para cada clave de sesión. Un disparador busca esa clave directamente para manejar mensajes que llegan en orden inverso; los seguimientos no emparejados posteriores para la misma clave se fusionan hasta que esa entrada coincida o expire. La coincidencia utiliza las marcas de tiempo de observación y el cliente, servidor, puerto del servidor, host HTTP y digest de sesión. Zeek en modo independiente correlaciona localmente. Se requiere conectividad normal con el proxy.
Los avisos de proxy utilizan la supresión de avisos estándar basada en UID y profundidad de transacción para correlation_window. Esto es independiente de los hallazgos de los workers y no detiene la inspección de cuerpos de los workers. Las coincidencias simultáneas para diferentes cookies de sesión en distintos proxies aún pueden producir avisos duplicados antes de que se propague la supresión del clúster.
Se comprueban las cabeceras de respuesta externas Server y X-Powered-By, incluidas las respuestas a GET. Los nombres de las cabeceras no distinguen mayúsculas de minúsculas. El límite inferior afectado es PHP 5.4.0. Los siguientes umbrales asumen que el siguiente parche tras las últimas versiones estables comprobadas el 18 de octubre de 2026 abordará ambos errores:
| Rama | Última versión estable al momento de la comprobación | Primera versión corregida provisional |
|---|---|---|
| 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 |