Web App 7 min de leitura

php2shell: como LFI, upload e filter chains viram RCE em PHP (e como validar)

Guia defensivo sobre php2shell: como LFI, upload inseguro, phar e PHP filter chains viram RCE, CVEs reais e ferramentas públicas para validar e corrigir.

Também em ENESPT
php2shell: como LFI, upload e filter chains viram RCE em PHP (e como validar)

Procurando as CVEs PHP2Shell de outubro de 2026 (CVE-2026-109618 e CVE-2026-109619)? Leia o que fazer agora.

Resumo: "php2shell" não é uma única ferramenta, mas uma família de técnicas que transformam uma falha PHP comum — Local/Remote File Inclusion, upload inseguro, desserialização via phar://, log poisoning e as modernas PHP filter chains — em execução de código (RCE) ou web shell. Este guia é defensivo: foca em como detectar, validar com ferramentas públicas e corrigir cada caminho, sem fornecer exploits prontos.

Quase toda cadeia de comprometimento grave em aplicações PHP termina no mesmo lugar: o atacante consegue fazer o interpretador rodar código dele. O ponto de partida varia — um parâmetro que entra em include, um formulário de upload mal validado, uma biblioteca que abre arquivos com phar:// — mas o destino é sempre a shell. Entender essas pontes é o primeiro passo para fechá-las.

O que significa "php2shell"

O termo descreve a transição de uma primitiva fraca para RCE. Uma leitura de arquivo arbitrária, isoladamente, já é grave; mas a preocupação real do time de defesa é quando essa leitura (ou escrita, ou inclusão) pode ser escalada até executar comandos no servidor. Mapear essas transições é exatamente o que fazemos num pentest de aplicação web.

As pontes mais comuns

  • Local File Inclusion (LFI) para RCE. Um parâmetro controlado pelo usuário que chega a include/require permite incluir arquivos do servidor. Classicamente, isso exigia um arquivo "envenenável" (logs, sessões). Hoje, a técnica de PHP filter chain removeu esse pré-requisito.
  • Upload inseguro. Validação por extensão ou Content-Type, diretórios de upload executáveis, ou renomeação previsível permitem subir um .php e acessá-lo direto.
  • Desserialização via phar://. Operações de arquivo sobre um caminho phar:// controlado podem acionar desserialização de metadados e cadeias de gadgets.
  • Log/session poisoning. Injetar PHP em um recurso que depois é incluído (log de acesso, arquivo de sessão).

PHP filter chains: por que a LFI ficou mais perigosa

A técnica de filter chain, publicada pela Synacktiv em 2022, foi um divisor de águas. Encadeando conversões de charset iconv dentro de php://filter, é possível forjar bytes arbitrários em memória a partir de um sink que apenas lê um arquivo. Na prática: uma LFI que antes era considerada "só leitura" passou a permitir RCE sem precisar de upload, sem arquivo gravável e sem acesso a logs. Para o defensor, a lição é direta: não trate mais nenhuma file inclusion como baixo risco. Fonte: thehacker.recipes — PHP wrappers and streams.

Técnica, CVE de exemplo e como validar

Técnica CVE / exemplo Como validar (ambiente autorizado) Correção
Upload inseguro para web shell CVE-2024-11635 (WP File Upload, RCE, CVSS 10) Tentar enviar arquivo não esperado e verificar se fica em diretório servido/executável Allow-list de tipos por magic bytes, diretório sem execução, nomes aleatórios
Upload não autenticado via REST CVE-2025-13329 (File Uploader for WooCommerce, CVSS 9.8) Checar endpoints REST que recebem arquivos sem capability/nonce Autenticação e autorização no endpoint; validar tipo no servidor
Injeção em parâmetro de comando (mailer) CVE-2016-10033 (PHPMailer < 5.2.18, CVSS 9.8) Conferir versão da dependência (composer.lock) Atualizar a lib; validar/sanitizar o remetente
LFI para RCE (filter chain) Técnica Synacktiv (classe, não CVE única) Verificar se parâmetros alcançam include/require com wrappers php:///data:// Allow-list de arquivos incluíveis; nunca concatenar input em include
Desserialização phar:// GHSA phar-stream-wrapper Mapear chamadas de arquivo que aceitam caminho controlado stream_wrapper_unregister('phar') quando não usado

Ferramentas públicas para validar (uso defensivo)

Use estas ferramentas apenas em sistemas que você está autorizado a testar. Elas confirmam exposição antes de o atacante confirmar.

synacktiv/php_filter_chain_generator

Script Python que gera cadeias de php://filter para avaliar se um sink de inclusão é explorável. No contexto defensivo, serve para provar reachability de um parâmetro suspeito até include e priorizar a correção. Repositório: https://github.com/synacktiv/php_filter_chain_generator.

PayloadsAllTheThings (categoria File Inclusion)

Coleção de referência muito reputada com a taxonomia de LFI/RFI e wrappers PHP. Excelente para montar casos de teste e checklists de revisão. Repositório: https://github.com/swisskyrepo/PayloadsAllTheThings.

projectdiscovery/nuclei

Scanner baseado em templates YAML. Há templates públicos para LFI, path traversal e padrões de RCE. Rode com nuclei -u https://alvo -tags lfi,rce para uma triagem rápida e reproduzível em pipeline. Repositório: https://github.com/projectdiscovery/nuclei.

wpscanteam/wpscan

Para o ecossistema WordPress, onde a maioria dos CVEs de upload/RCE aparece em plugins. wpscan --url https://alvo --enumerate vp lista plugins vulneráveis conhecidos. Repositório: https://github.com/wpscanteam/wpscan.

sullo/nikto

Scanner de servidor web clássico, útil para achar arquivos expostos, diretórios de upload abertos e configurações padrão. Repositório: https://github.com/sullo/nikto.

semgrep, Psalm e PHPStan (análise estática)

A validação mais barata é no código. Semgrep (https://github.com/semgrep/semgrep) encontra padrões como input chegando em include/system. Psalm (https://github.com/vimeo/psalm) e PHPStan (https://github.com/phpstan/phpstan) rastreiam taint e tipos, sinalizando dados não confiáveis que alcançam sinks perigosos. Rode-os no CI para barrar a ponte antes do deploy.

O que mudou no PHP 8.x

O PHP 8 reduziu — mas não eliminou — alguns caminhos. A desserialização automática de metadados phar em operações de arquivo comuns foi removida; o RCE só volta se o código chamar explicitamente Phar::getMetadata(). allow_url_include continua Off por padrão, dificultando RFI remota direta. Mas filter chains, uploads inseguros e LFI local continuam plenamente viáveis — a superfície mudou de lugar, não desapareceu. Fonte: pentesterlab — PHAR Deserialization.

Checklist de correção

  • Nunca concatene input em include/require; use allow-list fixa de arquivos.
  • Valide uploads por magic bytes, sirva uploads de um domínio/diretório sem execução de PHP.
  • Mantenha allow_url_include=Off e remova wrappers não usados.
  • Rode análise estática (Semgrep/Psalm/PHPStan) no CI e scanners (nuclei/wpscan) na homologação.
  • Atualize dependências e monitore CVEs dos plugins/libs que você usa.

Validar essas pontes exige método e autorização — é o que separa um pentest de um scanner automático. Se você roda APIs além do app PHP, veja também nosso guia de pentest de API e de BOLA/IDOR.

Perguntas frequentes

"php2shell" é um malware?

Não. É um termo guarda-chuva para técnicas que escalam uma falha PHP até execução de código. O risco é a classe de vulnerabilidade na sua aplicação, não um arquivo específico.

Atualizar para PHP 8 me protege?

Ajuda em phar e RFI, mas não resolve upload inseguro, LFI local nem filter chains. Correção de código e configuração continuam obrigatórias.

Um WAF é suficiente?

Um WAF reduz ruído e barra payloads óbvios, mas filter chains e uploads bem construídos frequentemente passam. Trate o WAF como camada, não como correção.

Quanto custa validar isso num pentest?

Depende do tamanho da aplicação e do número de sinks. Veja nossa referência de quanto custa um pentest para escopar.