Shopping cart

Subtotal $0.00

View cartCheckout

Building better devs

TnewsTnews
  • Home
  • Notícias
  • PHP2Shell: Um POST HTTP Dá Shell em Qualquer Servidor PHP
Notícias

PHP2Shell: Um POST HTTP Dá Shell em Qualquer Servidor PHP

Email : 15

Acordou, checou o Hacker News e quase derrubou o café

Se você é dev PHP (ou mantém qualquer servidor que roda PHP), o dia 21 de outubro de 2026 entrou pra história. Duas vulnerabilidades críticas no core do PHP, batizadas de PHP2Shell, ganharam patches de emergência depois que um exploit vazou antes da hora e atacantes já estavam explorando servidores ao redor do mundo. O nome não é exagero: um único POST HTTP é o suficiente para ganhar shell no seu servidor.

Vamos direto ao que importa: o que são essas falhas, como funcionam, quem está em risco e o que você precisa fazer agora.

O que é o PHP2Shell

PHP2Shell é o nome dado ao exploit que explora duas vulnerabilidades de execução remota de código (RCE) no interpretador PHP:

CVE CVSS v4.0 Tipo
CVE-2026-109618 9.2 (Crítico) RCE não autenticado
CVE-2026-109619 9.2 (Crítico) RCE não autenticado

O ponto crucial: essas falhas não estão em nenhum framework, plugin ou biblioteca. Estão no próprio PHP. Isso significa que não importa se você roda WordPress, Laravel, Drupal, Magento, Joomla ou aquele sistema legado que ninguém tem coragem de mexer. Se o servidor responde requisições PHP, ele é vulnerável.

Como o exploit funciona (a parte técnica)

Aqui é onde a coisa fica feia de verdade. O PHP, antes de executar qualquer linha do seu código, faz o parsing das requisições HTTP. Quando você envia um POST com Content-Type: multipart/form-data, o interpretador processa o corpo da requisição automaticamente, incluindo o gerenciamento de progresso de uploads via session.upload_progress.

As duas CVEs exploram primitivas de use-after-free no heap dentro desse processamento:

  • CVE-2026-109618: explora o handler de session.upload_progress, que faz bookkeeping de uploads em andamento
  • CVE-2026-109619: explora o próprio parser de multipart/form-data, que roda para qualquer POST multipart, independente de upload progress estar habilitado


POST /qualquer-script.php HTTP/1.1
Content-Type: multipart/form-data; boundary=----exploit
Content-Length: ...

------exploit
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
[payload crafted para triggerar use-after-free]
------exploit--

O atacante envia uma requisição multipart cuidadosamente construída. O PHP processa essa requisição antes de qualquer middleware, firewall de aplicação ou autenticação entrar em cena. O use-after-free permite controlar a execução e, pronto: shell no servidor.

Eu já vi muita CVE crítica, mas poucas com esse nível de superfície de ataque. Qualquer script PHP exposto na internet serve como ponto de entrada. Não precisa de login, não precisa de formulário de upload, não precisa de nada. Só um POST.

A timeline do desastre

A sequência de eventos parece saída de um thriller de cibersegurança:

Data/Hora (UTC) Evento
20/out, manhã Screenshots do exploit PHP2Shell (creditado a Calif.IO) vazam no Hacker News
20/out, tarde Pesquisadores da watchTowr confirmam que as vulnerabilidades são reais e reproduzem a CVE-2026-109618
20/out, noite PHP Foundation antecipa o release em 24 horas
21/out, 07:43 Primeiros ataques detectados in-the-wild, antes do patch sair
21/out, 14:00 Patches oficiais liberados
21/out, 14:15 Exploração em massa esperada e confirmada

Percebe o problema? O exploit vazou um dia inteiro antes do patch. E os primeiros ataques aconteceram mais de 6 horas antes da correção ser publicada. Quem não estava monitorando de perto ficou exposto por horas.

Versões afetadas e corrigidas

Aqui entra a parte que vai tirar o sono de muita gente:

Branch PHP Versão corrigida Status
PHP 8.5 8.5.12 Corrigido
PHP 8.4 8.4.27 Corrigido
PHP 8.3 8.3.36 Corrigido
PHP 8.2 8.2.35 Corrigido
PHP 8.1 e anteriores Sem patch End of Life

A PHP Foundation só libera patches para branches com suporte ativo. Se você roda PHP 8.1, 8.0, 7.x ou (Deus me livre) PHP 5.x: não vai ter correção oficial.

E aqui vem o número que dói: pesquisadores estimam que 884 mil hosts rodando versões end-of-life nunca vão receber esse patch. São quase um milhão de servidores permanentemente vulneráveis. Muitos deles são aquele e-commerce de PME que “está funcionando, não mexe”, aquele blog WordPress esquecido ou aquele painel administrativo legado que ninguém quer migrar.

WordPress, Laravel, Drupal: todo mundo na mira

Vou ser direto: se o seu site roda em PHP, ele era vulnerável. Não interessa o framework.

  • WordPress: 43% da web roda WordPress. Todo WordPress roda PHP. Faça as contas.
  • Laravel: seu artisan serve ou PHP-FPM atrás do nginx? Vulnerável.
  • Drupal: mesma situação.
  • Magento/WooCommerce: lojas online processando pagamentos. Com shell no servidor, o atacante tem acesso a tudo.
  • APIs em PHP: aquele microserviço que “é só uma API simples” também aceita POST multipart.

A falha está no runtime, não no seu código. Você pode ter 100% de cobertura de testes, usar OWASP top 10 como checklist diário, rodar SAST/DAST no pipeline. Nada disso ajuda quando o buraco está no interpretador.

Como verificar se você está vulnerável

Primeiro passo: descubra qual PHP está rodando.


# No servidor
php -v

# Via phpinfo (crie um arquivo temporário, delete depois!)
echo "<?php phpinfo(); ?>" > /tmp/check.php
php /tmp/check.php | grep "PHP Version"
rm /tmp/check.php

# Checar TODOS os binários PHP no sistema
find / -name "php" -o -name "php-fpm" -o -name "php-cgi" 2>/dev/null | while read bin; do
  echo "$bin: $($bin -v 2>/dev/null | head -1)"
done

Se a versão for menor que 8.2.35, 8.3.36, 8.4.27 ou 8.5.12, você precisa atualizar agora. Não amanhã, não na próxima sprint, não no próximo deploy agendado. Agora.

Para ambientes com Docker:


# Checar imagens PHP em uso
docker images | grep php
docker ps --format '{{.Names}} {{.Image}}' | grep php

# Atualizar imagem base
docker pull php:8.4-fpm
docker pull php:8.3-fpm
# Rebuild e redeploy

Para quem usa gerenciadores de pacotes:


# Debian/Ubuntu
sudo apt update && sudo apt upgrade php*

# CentOS/RHEL (com Remi repo)
sudo dnf update php*

# macOS (Homebrew)
brew update && brew upgrade php

Mitigações temporárias (se não pode atualizar agora)

Atualizar é a única solução real. Mas se você precisa de tempo para testar o patch antes de aplicar em produção, existem mitigações parciais:

1. Desabilitar upload progress no php.ini:


; /etc/php/8.x/fpm/php.ini
session.upload_progress.enabled = Off
session.use_strict_mode = On

Isso mitiga a CVE-2026-109618, mas não a CVE-2026-109619, que afeta o parser multipart diretamente.

2. Bloquear requisições multipart no web server:


# nginx - bloquear multipart/form-data globalmente
# CUIDADO: isso quebra uploads e formulários!
if ($content_type ~* "multipart/form-data") {
    return 403;
}


# Apache - mesmo efeito
RewriteEngine On
RewriteCond %{CONTENT_TYPE} multipart/form-data [NC]
RewriteRule .* - [F,L]

Obviamente, bloquear multipart/form-data vai quebrar qualquer formulário que faça upload de arquivos. É uma medida de emergência, não uma solução.

3. WAF rules (Cloudflare, AWS WAF, etc.):

Se você usa Cloudflare, crie uma regra customizada para bloquear POSTs multipart em endpoints que não precisam de upload. Isso reduz a superfície sem quebrar tudo.

4. Isolar servidores PHP antigos:

Se você tem servidores rodando PHP 7.x ou 8.1 que não vão receber patch, a melhor opção é tirá-los da internet. Coloque atrás de uma VPN, restrinja o acesso por IP ou, melhor ainda, comece a planejar a migração.

Como detectar se você já foi comprometido

Se o seu servidor estava exposto entre 20 e 21 de outubro (ou se roda uma versão sem patch), vale fazer uma varredura:


# Procurar processos suspeitos spawned por PHP
ps aux | grep -E "(php|php-fpm)" | grep -v grep

# Checar se PHP spawnou shells
find /var/log -name "*.log" -newer /tmp/check_date -exec grep -l "sh\|bash\|wget\|curl\|nc " {} \;

# Procurar webshells comuns
find /var/www -name "*.php" -newer /tmp/check_date -exec grep -lE "(eval\(|base64_decode\(|system\(|exec\(|passthru\()" {} \;

# Checar crontabs novos
crontab -l
ls -la /etc/cron.d/

Indicadores de comprometimento incluem:

  • Processos filhos de PHP executando sh, bash, cmd.exe ou powershell.exe
  • Uso de curl, wget, nc a partir do contexto do PHP
  • Padrões de reverse shell: /dev/tcp/, fsockopen, mkfifo
  • Comandos de reconhecimento: whoami, id, uname -a
  • Novos arquivos .php em diretórios de upload ou temporários

Se encontrar qualquer sinal, preserve os logs antes de tudo. Depois isole o servidor, identifique o vetor de entrada e faça a análise forense. Não limpe e siga em frente, porque o atacante pode ter deixado backdoors que você ainda não encontrou.

O problema dos 884 mil servidores sem patch

Esse é o elefante na sala que pouca gente está discutindo. Quase um milhão de servidores PHP rodando versões end-of-life vão permanecer vulneráveis indefinidamente. E a maioria desses servidores não tem um sysadmin dedicado monitorando CVEs.

São hospedagens compartilhadas com dezenas de sites cada. São VPSs contratadas em 2019 e esquecidas. São aqueles projetos “temporários” que viraram permanentes. São ERPs internos rodando PHP 7.2 que “custam muito caro pra migrar”.

Para esses casos, a comunidade open source já começou a se mobilizar. O projeto php2shell-protection no GitHub oferece regras de mitigação para Apache que bloqueiam requisições multipart antes de chegarem ao PHP. Não é um patch, mas é melhor que nada.

Alguns provedores de hospedagem maiores (como Cloudways e SiteGround) já forçaram atualizações automáticas. Mas hospedagens menores e servidores auto-gerenciados vão depender de quem administra se dar conta do problema.

Por que isso aconteceu: o parsing que ninguém auditava

Uma reflexão que vale a pena fazer: como um bug no parsing de multipart/form-data sobreviveu desde o PHP 5.4 (lançado em 2012) até 2026? São 14 anos.

A resposta é que essa parte do código do PHP é uma das mais antigas e menos auditadas. O parsing de requisições HTTP é tão fundamental que todo mundo assume que “já foi resolvido”. É infraestrutura invisível. Ninguém escreve testes para o parser de multipart do runtime, porque isso “não é responsabilidade do desenvolvedor da aplicação”.

Só que é responsabilidade de alguém. E durante 14 anos, essas primitivas de use-after-free ficaram ali, esperando. O código do session.upload_progress foi adicionado no PHP 5.4 para permitir que desenvolvedores mostrassem barras de progresso de upload sem precisar de extensões externas. Uma feature de conveniência que virou um vetor de ataque crítico.

Isso me lembra do Heartbleed, do Log4Shell e de tantas outras vulnerabilidades em componentes que “todo mundo usa mas ninguém olha”. A diferença é que o PHP roda em mais de 75% dos sites com server-side scripting identificável. A superfície de ataque é absurda.

Checklist de emergência

Para facilitar, aqui vai um checklist direto:

  • • Identificar TODAS as instâncias PHP no seu ambiente (servidores, containers, lambdas, shared hosting)
  • • Verificar a versão de cada uma com php -v
  • • Atualizar para 8.2.35, 8.3.36, 8.4.27 ou 8.5.12 (conforme o branch)
  • • Se não puder atualizar imediatamente: aplicar mitigações temporárias (desabilitar upload progress + WAF rules)
  • • Se roda PHP 8.1 ou anterior: planejar migração urgente ou isolar da internet
  • • Verificar logs em busca de sinais de comprometimento entre 20 e 21 de outubro
  • • Procurar webshells e backdoors em diretórios web
  • • Notificar a equipe de segurança e documentar as ações tomadas
  • • Monitorar advisories do PHP nos próximos dias para detalhes adicionais

O que esperar nos próximos dias

Com o exploit público e o patch disponível, a corrida agora é entre quem atualiza e quem explora. A experiência com vulnerabilidades similares (como a CVE-2024-4577, também em PHP/CGI) mostra que bots automatizados começam a escanear a internet inteira em questão de horas após o patch sair. Quem não atualizou até agora já está em risco elevado.

Espere também um aumento de webshells aparecendo em sites comprometidos, campanhas de ransomware mirando servidores PHP desatualizados e, infelizmente, supply chain attacks usando sites legítimos comprometidos como distribuição de malware.

Se você mantém servidores PHP, esse é o tipo de vulnerabilidade que justifica parar tudo e atualizar. Não é hyperbole. CVSS 9.2, RCE não autenticado, exploit público, ataques confirmados. Prioridade máxima.

Fonte de inspiração: Upcoming critical PHP security release, php.net e PHP2Shell: Critical PHP RCE, Sansec

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts