
Detecções Zeek e Suricata para "php2shell" CVE-2026-109618 e CVE-2026-109619
Detecções Zeek e regras Suricata para indicadores HTTP associados ao "php2shell" CVE-2026-109618 / CVE-2026-109619, potencial RCE no tratamento de memória longjmp() do PHP. Os achados identificam tráfego suspeito ou software potencialmente afetado.
Requer Zeek 7.0.0 ou superior. Instale com o Zeek Package Manager:
zkg install https://github.com/corelight/php2shell-detect
Carregue os pacotes instalados com @load packages na sua configuração do Zeek.
Para um checkout direto, carregue /path/to/php2shell-detect/scripts.
O pacote utiliza as APIs padrão de HTTP, análise de arquivos, notices e cluster do Zeek.
O pacote inspeciona comprimentos de nomes de campos POST, estruturas selecionadas de dados serializados e cabeçalhos MIME repetidos. Também correlaciona transações suspeitas relacionadas usando cookies de sessão configurados. Os cabeçalhos de resposta fornecem um inventário separado de versões do PHP. O tráfego deve estar visível para o analisador HTTP do Zeek; HTTP criptografado requer descriptografia antes da inspeção.
Todos os tipos de notice estão sob PHP2SHELL:::
| Notice | Observação |
|---|---|
PHP_Crash_Sequence | Transações HTTP suspeitas relacionadas dentro de uma sessão |
Multipart_Header_Flood | Repetição excessiva de cabeçalhos MIME reconhecidos |
Large_Form_Key | Nome de campo de formulário codificado em URL incomumente longo |
Serialized_Integer_Overflow | Token inteiro serializado incomumente grande |
Serialized_Integer_Collisions | Padrão reconhecido de chave inteira serializada |
Serialized_String_Collisions | Padrão reconhecido de chave de string serializada |
Serialized_Duplicate_Array | Padrão repetido de entrada de array serializado |
Serialized_Object_Repetition | Padrão repetido de objeto serializado |
Potentially_Affected_PHP_Version | O cabeçalho de resposta anuncia uma versão dentro do intervalo afetado configurado |
Os resultados vão para o notice.log padrão; o pacote não cria nenhum stream
de log adicional. O campo sub do notice fornece contexto limitado, como nome
do cabeçalho, profundidade da transação, contagens e uma pequena amostra
escapada do corpo POST. As amostras são limitadas a 64 bytes brutos antes do
escaping por padrão; defina notice_body_sample_bytes=0 para omiti-las. Os
cookies e seus digests são usados apenas em memória e não são registrados por
este pacote.
Por padrão, cada indicador de requisição distinto pode emitir um notice por
transação. Correspondências repetidas do mesmo indicador são suprimidas.
Defina detect_only_once=T para interromper a inspeção do corpo após a
primeira descoberta de requisição em cada transação. Os notices de inventário
de versão são independentes das descobertas de requisição.
Todas as configurações usam o namespace PHP2SHELL:::
| Configuração | Padrão | Efeito |
|---|---|---|
detect_only_once | F | Relata cada indicador de requisição distinto; T interrompe após a primeira descoberta |
max_trans_depth | 3 | Inspeciona as três primeiras transações HTTP por conexão; 0 significa todas |
inspect_cookies | T | Usa cookies de sessão para correlação |
session_cookie_names | {"PHPSESSID"} | Nomes de cookies usados para associar sessões |
correlation_window | 1 min | Idade máxima do estado pendente de correlação de sessão |
max_pending_sessions | 1000 | Limite de entradas retidas em cada tabela de correlação |
inspect_post_bodies | T | Inspeciona dados de entidade POST e cabeçalhos MIME |
http_body_analysis_byte_depth | 8388608 | Teto conservador de 8 MiB no trabalho de inspeção do corpo POST, compartilhado entre partes MIME; 0 desativa a entrega do corpo |
body_overlap_bytes | 256 | Sobreposição retida para padrões que cruzam chunks do corpo |
large_form_key_bytes | 65536 | Limite em bytes de transmissão para nome de formulário |
multipart_header_threshold | 128 | Cabeçalhos MIME reconhecidos repetidos necessários para uma descoberta |
notice_body_sample_bytes | 64 | Máximo de bytes brutos do corpo por amostra de notice; 0 omite as amostras |
detect_affected_php_versions | T | Ativa o inventário de versões a partir dos cabeçalhos de resposta |
php_version_notice_interval | 1 hr | Suprime notices de versão por IP de servidor entre portas e versões |
php_fixed_patch_versions | 8.2: 35, 8.3: 36, 8.4: 27, 8.5: 12 | Primeiro patch corrigido provisório por branch |
Por exemplo:
redef PHP2SHELL::detect_only_once = T;
redef PHP2SHELL::notice_body_sample_bytes = 0;
redef PHP2SHELL::session_cookie_names += { "custom_session" };
A inspeção POST usa chunks de análise de arquivo com sobreposição limitada, em vez de montar corpos inteiros. A contagem de nomes de formulário respeita separadores de valor e terminação NUL bruta. Apenas entidades POST elegíveis recebem um analisador; os orçamentos de corpo e os limites de transação restringem intencionalmente o escopo de detecção. Esses indicadores são incompletos e também podem corresponder a tráfego benigno.
Em um cluster Zeek, os workers encaminham pequenas observações de sessão para os proxies com Cluster::publish_hrw(). Ambos os estágios para a mesma sessão chegam ao mesmo proxy, que os correlaciona e gera PHP_Crash_Sequence diretamente. O aviso retém o ID de conexão, o UID e a profundidade de transação do follow-up; peer_descr identifica o proxy. Os workers não retêm registros completos de conexão ou HTTP para callbacks.
Triggers e follow-ups não correspondidos expiram após correlation_window, com max_pending_sessions limitando cada tabela. Os proxies retêm o primeiro follow-up não correspondido para cada chave de sessão. Um trigger consulta essa chave diretamente para lidar com mensagens que chegam em ordem inversa; follow-ups não correspondidos posteriores para a mesma chave são coalescidos até que essa entrada corresponda ou expire. A correspondência usa timestamps de observação e o cliente, servidor, porta do servidor, host HTTP e digest da sessão. O Zeek standalone correlaciona localmente. É necessária conectividade normal com o proxy.
Os avisos de proxy usam a supressão padrão de avisos com chave baseada em UID e profundidade de transação para correlation_window. Isso é independente das descobertas dos workers e não interrompe a inspeção de corpo dos workers. Correspondências simultâneas para diferentes cookies de sessão em proxies diferentes ainda podem produzir avisos duplicados antes que a supressão do cluster se propague.
Os cabeçalhos de resposta externos Server e X-Powered-By são verificados, incluindo respostas a GET. Os nomes dos cabeçalhos não diferenciam maiúsculas de minúsculas. O limite inferior afetado é o PHP 5.4.0. Os seguintes limites assumem que o próximo patch após as versões estáveis mais recentes verificadas em 18 de outubro de 2026 abordará ambos os bugs:
| Branch | Versão estável mais recente no momento da verificação | Primeira versão corrigida provisória |
|---|---|---|
| 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 |
Versões corrigidas configuradas e patches posteriores no mesmo branch não geram alerta. Branches sem um limite configurado permanecem candidatos. Sufixos comuns de fornecedores usam a versão numérica subjacente. Os banners podem estar ausentes, ser reescritos ou refletir uma build de fornecedor com correções backportadas, portanto, estes são apenas indícios de inventário.