vulnerabilities php2shell vulnerabilidade

PHP2Shell: Aviso Crítico CVE-2026-109618 & CVE-2026-109619 e Matriz de Versões

php2shell.run Research Lab •

PHP2Shell: Aviso Crítico CVE-2026-109618 & CVE-2026-109619 e Matriz de Versões

<time datetime="2026-10-23">Verificado em 23 de outubro de 2026</time> · Fontes: php.net, GitHub Security Advisories GHSA-w8hw-w9fx-j79w / GHSA-6wmf-4rv5-p3rp

Em 21 de outubro de 2026, a equipe do core do PHP e diversos pesquisadores de segurança publicaram duas vulnerabilidades críticas conhecidas coletivamente como PHP2Shell: CVE-2026-109618 e CVE-2026-109619. A pontuação CVSS v4.0 é 9,2 (Critical). Um atacante não autenticado pode executar comandos arbitrários do sistema operacional no contexto do worker do servidor web ou do PHP-FPM (www-data, nginx, apache). O ponto decisivo: o defeito está no núcleo C da engine PHP, na manipulação de uploads multipart RFC1867 e no tratamento de erros do Zend Memory Manager (ZMM). Middleware de framework, validação de entrada e a maioria das regras de WAF agem tarde demais ou não agem.


1. Matriz de vulnerabilidades e fatos confirmados

CaracterísticaCVE-2026-109618CVE-2026-109619
ClasseCorrupção de estado de memória no caminho OOMEstado global residual / Use-After-Free (UAF)
CVSS v4.09,2 (Critical)9,2 (Critical)
AutenticaçãoNenhuma (não autenticado)Nenhuma (não autenticado)
Exposição padrãosession.upload_progress ativo por padrãosession.upload_progress ativo por padrão
Momento do gatilhoParsing do corpo da requisição (antes do código do usuário)Parsing e teardown da sessão
Ambientes afetadosPHP-FPM, Apache mod_php, FrankenPHP, LiteSpeedPHP-FPM, Apache mod_php, FrankenPHP, LiteSpeed
Versões afetadasPHP 5.4–8.5PHP 5.4–8.5

A faixa afetada é PHP 5.4 a 8.5. Resumos que citam 5.x–8.4 estão errados: o ramo 8.5 também é vulnerável antes da 8.5.12. Como session.upload_progress está On por padrão desde o PHP 5.4, praticamente todos os runtimes de produção não explicitamente endurecidos estão na superfície de ataque — independentemente de a aplicação usar sessões.


2. Ciclo de vida do ataque: comprometimento antes da execução da aplicação

O perigo central do PHP2Shell é o momento em que o código C vulnerável executa. Ele roda durante o streaming HTTP, antes que index.php, roteadores de framework ou regras de WAF em nível de aplicação entrem em ação.

                [ REQUISIÇÃO HTTP POST ENTRANTE ]
        (qualquer caminho: /index.php, /login, /404 inexistente)
                             │
                             ▼
 ┌─────────────────────────────────────────────────────────┐
 │ Camada SAPI da engine PHP (núcleo C)                    │
 │  - lê headers, Content-Type: multipart/form-data        │
 └───────────────────────────┬─────────────────────────────┘
                             ▼
 ┌─────────────────────────────────────────────────────────┐
 │ ext/session/session.c :: php_session_rfc1867_callback() │
 │  - detecta PHP_SESSION_UPLOAD_PROGRESS                  │
 │  - cacheia ponteiro bruto: cached_post_bytes            │
 │  - [FALHA CRÍTICA] OOM / reset de sessão ocorre        │
 │  - memória FREED -> ponteiro se torna DANGLING          │
 └───────────────────────────┬─────────────────────────────┘
            ┌────────────────┴────────────────┐
            ▼                                 ▼
   [ requisições normais ]            [ exploit PHP2Shell ]
   código da aplicação roda           spray de fake zval
   (Laravel, WordPress)               hijack de vtable -> system()
            ▼                                 ▼
   resposta normal                    [ RCE ALCANÇADO ]
                              (antes do código do usuário rodar!)

Consequências diretas:

  1. Gatilho pré-execução: o callback dispara durante o parsing, não após o roteamento.
  2. Sem formulário de upload necessário: qualquer endpoint acessível — inclusive um handler 404 — basta.
  3. Sessões irrelevantes: mesmo que a aplicação nunca chame session_start(), o caminho fica ativo enquanto a opção estiver globalmente ligada.

3. Causa raiz: cached_post_bytes, longjmp e ZMM

Em ext/session/session.c, durante o progresso de upload, ponteiros zval brutos da HashTable de sessão são copiados para variáveis estáticas de processo.

/* ext/session/session.c — modelo simplificado */
static zval *cached_post_bytes;
static zval *cached_file_bytes;

static int php_session_rfc1867_callback(unsigned int event,
                                        void *event_data,
                                        void **extra)
{
    switch (event) {
    case MULTIPART_EVENT_START: {
        zval *progress = php_session_get_progress_entry();
        ZVAL_LONG(&progress->value.bytes_processed, 0);

        /* FALHA: endereço bruto de zval interno cacheado globalmente */
        cached_post_bytes = &progress->value.bytes_processed;
        cached_file_bytes = &progress->value.files[0].bytes_processed;
        break;
    }
    case MULTIPART_EVENT_FILE_DATA:
        Z_LVAL_P(cached_post_bytes) += chunk_len;
        break;
    }
    return SUCCESS;
}

Quando a sessão é recarregada (session_reread()) ou a entrada é substituída via zend_hash_update(), zval_ptr_dtor devolve o chunk ao Zend Memory Manager. Os ponteiros globais, porém, não são invalidados. O próximo chunk escreve em memória liberada:

*cached_post_bytes += chunk_len;  /* write UAF clássico */

CVE-2026-109618 chega ao mesmo destino por outro caminho, através do tratamento de erros de exaustão de memória. Quando memory_limit é excedido, o PHP executa um bailout baseado em longjmp(). Se um OOM ocorrer no meio do streaming RFC1867, antes que as estruturas intermediárias estejam totalmente inicializadas, a rotina de cleanup processa objetos parcialmente inicializados. Os metadados dos bins do ZMM ficam inconsistentes; alocações subsequentes podem receber chunks sobrepostos. Ambas as CVE resultam em um caminho de escrita válido em memória liberada, diferindo apenas no gatilho.


4. Versões oficiais corrigidas e ramos EOL

Ramo PHPVulnerávelPrimeira versão seguraAção
PHP 8.5< 8.5.128.5.12atualizar imediatamente
PHP 8.4< 8.4.278.4.27atualizar imediatamente
PHP 8.3< 8.3.368.3.36atualizar imediatamente
PHP 8.2< 8.2.358.2.35atualizar no suporte de segurança
PHP 8.1 / 8.0 / 7.4 e anteriorestodassem release upstreambackport da distribuição ou workaround

Para PHP 8.1 e anteriores não há mais releases upstream. Use backports do Ubuntu Pro, Debian LTS, CloudLinux ou RHEL, ou aplique a mitigação temporária até lá.


5. Ações imediatas para operadores

5.1 Verificar runtime e pacotes

php -v
php-fpm -v
dpkg -l | grep -E '^ii\s+php[0-9.]*-(fpm|cli|common)'
rpm -qa | grep -i '^php'
zgrep -E "CVE-2026-10961[89]" /usr/share/doc/php*/changelog* 2>/dev/null
php-fpm -t

5.2 Mitigação imediata sem downtime

; /etc/php/8.x/fpm/php.ini
session.upload_progress.enabled = Off
; /etc/php/8.x/fpm/pool.d/www.conf
php_admin_flag[session.upload_progress.enabled] = off
sudo systemctl reload php8.3-fpm
sudo kill -USR2 "$(cat /var/run/php-fpm.pid)"
php -r 'echo "upload_progress=", ini_get("session.upload_progress.enabled"), PHP_EOL;'

Essa opção desativa apenas o callback legado de barra de progresso. Uploads normais via $_FILES, move_uploaded_file() e APIs modernas do navegador funcionam inalterados.

5.3 Indicadores de comprometimento

find /var/www -type f -mtime -2 -ls 2>/dev/null | head -50
ps -eo pid,user,lstart,cmd | awk '$2=="www-data"||$2=="nginx"'
ss -tpn | grep ESTAB | grep -E 'www-data|php-fpm'

6. Perguntas frequentes

P: session.upload_progress.enabled = Off quebra uploads normais? Não. A diretiva controla apenas o callback de progresso introduzido no PHP 5.4. Armazenamento de arquivos, caminhos temporários e $_FILES não são afetados.

P: Um WAF é suficiente? Não. Payloads reais frequentemente ficam abaixo de 500 bytes, escapando de limites de tamanho. Além disso, a requisição é parseada antes que roteamento e regras de WAF em nível de aplicação tenham efeito. A única solução robusta é o patch ou a desativação no nível da engine.

P: O que muda em 8.5.12? A vida útil dos ponteiros globais RFC1867 e a ordem das rotinas de cleanup no bailout OOM foram corrigidas. 8.4.27, 8.3.36 e 8.2.35 contêm a mesma correção como backport.


7. Referências

  • php.net Security Releases de 21 de outubro de 2026
  • GitHub Security Advisory GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
  • GitHub Security Advisory GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
  • Ubuntu Security Tracker, Debian Security Tracker, Red Hat CVE Database
  • Ferramenta de diagnóstico: https://php2shell.run/checker/

Este documento serve exclusivamente à defesa e remediação. Código de exploit não é fornecido. Alterações em produção devem seguir change management controlado.