← back
CVE-2012-1823criticalunder attackCWE-77

CVE-2012-1823

100Vexday Risk Score

Patch now. It under exploitation confirmed by CISA and has a working public exploit.

ssvc Actcvss 9.8epss 100%
from disclosure to weapon0 days
Published on NVDMay 11
1st PoCMay 4
metasploitMay 3
CISA KEV+3605d
exploitation probability
100%top 1% of all CVEs
observed exploitation
yesCISA + VulnCheck
23 public exploit(s)
Action required by CISAfederal deadline: 2022-04-15

Apply updates per vendor instructions.

Summary

Falha crítica em php-cgi (PHP antes de 5.3.12 e 5.4.x antes de 5.4.2) que permite execução remota de código não autenticada quando o PHP é executado em modo CGI puro (não via mod_php ou php-fpm). O impacto é real e generalizado: a vulnerabilidade foi explorada em massa contra painéis Parallels Plesk desde 2013 e continua no catálogo KEV da CISA, mas só afeta quem expõe o binário php-cgi diretamente como handler CGI — configurações com Apache+mod_php ou php-fpm não são vulneráveis a esta CVE específica.

Technical detail

O problema está em sapi/cgi/cgi_main.c. Pela especificação histórica de CGI (indexed queries, herdada do padrão ISINDEX), quando a query string de uma requisição não contém um caractere '=', o servidor deve repassar essa string como argumentos de linha de comando ao programa CGI. O php-cgi implementa isso, mas falha em bloquear que esses 'argumentos' sejam interpretados pelo parser de opções da própria CLI do PHP (php_getopt) — especificamente há uma omissão de skip para o caso 'd' do getopt, que deveria impedir que switches de linha de comando fossem processados quando o binário está rodando como CGI.

How it’s exploited

Um atacante não autenticado envia uma requisição HTTP cuja query string começa com '-' e não contém '=', usando URL-encoding para embutir flags de CLI do PHP (por exemplo -s para expor o código-fonte do script, ou -d para redefinir diretivas de php.ini). Combinando -d allow_url_include=1 e -d auto_prepend_file=php://input com um corpo de requisição contendo código PHP, o atacante consegue que o php-cgi execute esse código antes do script original, obtendo RCE com os privilégios do processo web. A exploração exige uma única requisição, sem autenticação, e a única pré-condição real é que o servidor invoque php-cgi diretamente como CGI (mod_cgid do Apache, IIS com CGI, ou qualquer script-alias que mapeie para o binário) — é isso que tornou os painéis Plesk 9.0-9.2.3, que usavam um alias phppath/php apontando para php-cgi, alvo fácil de exploração ativa documentada (VU#673343, exploit público de Kingcope na Full Disclosure). Existem módulo Metasploit, template Nuclei e PoC pública, o que mantém a falha sob varredura oportunista constante mesmo mais de uma década depois.

Versions

Affected
PHP anterior a 5.3.12; PHP 5.4.x anterior a 5.4.2 — quando configurado para rodar como CGI (php-cgi binário invocado diretamente pelo servidor web).
Fixed in
PHP 5.3.12 e 5.4.2 corrigem a falha original, com a ressalva do próprio fornecedor de que não cobrem todas as variações do problema (recomendada a regra de mod_rewrite como camada extra). Distribuições e fornecedores de terceiros publicaram backports próprios: openSUSE, Red Hat (RHSA-2012-0546), Apple (atualização de setembro/2012) e HP-UX Web Server Suite v3.24 com PHP 5.2.17.

How to protect

Atualizar para PHP 5.3.12 ou 5.4.2 (ou versões posteriores dos respectivos ramos). Importante: o próprio PHP declarou publicamente que essas versões não corrigem todas as variações do problema de argumentos via CGI, e recomendou como camada adicional uma regra de mod_rewrite que bloqueia requisições cuja query string não contenha '=' e comece com '-' (RewriteCond %{QUERY_STRING} ^[^=]*$ seguido de RewriteCond bloqueando o padrão de '-'). Essa regra é um paliativo real e de baixo custo, mas não substitui o patch. A mitigação estrutural mais sólida é abandonar o uso de php-cgi puro como handler CGI e migrar para php-fpm (FastCGI) ou mod_php, que o próprio fornecedor afirma não serem afetados por este vetor. Não funciona como mitigação apenas restringir a extensão .php via configuração de tipo de conteúdo sem tratar a query string, nem confiar que WAFs genéricos bloqueiem todas as variações — o próprio fornecedor reconheceu bypasses da correção original, e uma variante mais recente em ambientes Windows (CVE-2024-4577, corrigida em PHP 8.3.8/8.2.20/8.1.29) mostrou que o problema de fundo (repassar query string como argv para php-cgi) persistiu por mais de uma década em certas configurações de locale.

How to detect

Procurar em logs de acesso do servidor web requisições GET ou POST para endpoints .php (ou mapeados para o handler CGI) cuja query string não contenha '=' e comece com '-' — especialmente sequências decodificadas como '-s', '-d', '-c' ou '-n' isoladas na URL. Correlacionar com corpos de requisição contendo marcadores de código PHP (ex. '<?php') quando a query string sugerir uso de '-d auto_prepend_file=php://input' é forte indicativo de tentativa de RCE, não apenas de disclosure de código-fonte. Como existem PoC pública, módulo Metasploit e template Nuclei amplamente distribuídos desde 2012, tráfego de varredura oportunista contra esse padrão é comum e não indica necessariamente comprometimento — a ausência desse padrão nos logs, porém, é um sinal razoavelmente confiável de que a técnica clássica não foi tentada.

Researched and written with AI from the vendor advisory and public analysis, with the sources above. Always confirm the fixed version in the official advisory before acting.
sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not properly handle query strings that lack an = (equals sign) character, which allows remote attackers to execute arbitrary code by placing command-line options in the query string, related to lack of skipping a certain php_getopt for the 'd' case.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Affected products
n/a · n/a
⚠ Public resources, to assess the exposure of systems you control or are authorized to test. Test only with authorization.