
# Laboratório CTF baseado em Docker demonstrando CVE-2024-4577, injeção de argumentos PHP-CGI que leva a RCE. Inclui PHP 5.4.1 CGI vulnerável, scripts de exploração e recuperação de flag.
Um laboratório Docker autossuficiente, do zero, que demonstra o primitivo
real de injeção de argumentos → Execução Remota de Código por trás da
CVE-2024-4577.
Explore-o via http://localhost:8080, obtenha um shell e leia a flag de
dentro do contêiner.
Esta é uma vulnerabilidade genuína, não simulada. O contêiner compila um binário PHP 5.4.1 CGI sem patch e o conecta ao Apache exatamente da forma como hosts vulneráveis reais são configurados. Não há nenhum "if password == flag" falso em lugar algum — a única maneira de obter a flag é realmente alcançar a execução de código.
O payload característico da CVE-2024-4577 usa %AD (um hífen suave). Esse truque
só funciona no Windows, porque a codificação de caracteres "Best-Fit" do Windows
converte o byte 0xAD em um - real (0x2D) depois que o patch da CVE-2012-1823
do PHP já verificou a string de consulta. Essa conversão de codificação é feita pelo
próprio Windows — ela não acontece dentro de um contêiner Docker Linux normal.
Portanto, um laboratório Linux fiel e executável na sua máquina reproduz o mesmo
primitivo exato de RCE — injeção de opções php-cgi através da URL → -d auto_prepend_file=php://input → execução de código — usando a forma literal -
(que é o bug pai da CVE-2024-4577, a CVE-2012-1823). A única
diferença em relação a um alvo real da CVE-2024-4577 no Windows é a camada de
bypass de codificação %AD→-, que este README documenta por completo (veja
Como funciona e
poc.http).
| Este laboratório Linux | CVE-2024-4577 real (Windows) | |
|---|---|---|
| Componente vulnerável | php-cgi | php-cgi |
| Primitivo de RCE | -d auto_prepend_file=php://input | idêntico |
| Delimitador na URL | - literal | %AD (best-fit → -) |
| Contorna o patch de 2012? | N/A (PHP anterior ao patch) | Sim, via best-fit do Windows |
| Roda no Win 11 Home + Docker Desktop | ✅ | ❌ (precisa de contêineres Windows) |
Se você precisar especificamente da reprodução bit a bit do %AD no Windows, você
precisa de um host Docker com suporte a contêineres Windows (Windows Server / Win Pro
poc.http para referência.CVE-2024-4577 — Injeção de Argumentos PHP CGI levando à Execução Remota de Código. Descoberta pela DEVCORE (Orange Tsai / Angelboy), divulgada em 2024-06-06.
Quando o PHP é implantado em modo CGI (ou o binário php-cgi.exe está de outra
forma acessível) no Windows com certos locales de sistema (Chinês Tradicional/
Simplificado, Japonês e outros), o servidor web passa a string de consulta HTTP para
php-cgi como argumentos de linha de comando. Um atacante pode contrabandear opções
de linha de comando do php-cgi (-d ...) para dentro dessa string de consulta. A
conversão de codepage best-fit do Windows transforma o byte de hífen suave 0xAD
(%AD) em um hífen ASCII -, que escapa do endurecimento da CVE-2012-1823 e permite
que o atacante defina diretivas INI arbitrárias do PHP — mais utilmente
auto_prepend_file=php://input com allow_url_include=1, que executa o corpo da
solicitação fornecida pelo atacante como PHP. Resultado: execução remota de código
não autenticada. Foi armada na natureza em poucos dias (por exemplo, ransomware
TellYouThePass).
O CGI passa a string de consulta como argv. De acordo com a RFC 3875, se a
string de consulta de uma solicitação CGI contém nenhum = não codificado,
o servidor a divide em +, decodifica cada palavra por URL e passa as palavras
ao programa CGI como argumentos de linha de comando. O php-cgi portanto recebe
argv controlado pelo atacante.
O php-cgi analisa esses argv como opções. Historicamente, o php-cgi
interpretava -d key=value, -T, etc. desse argv. Alimentar
-d allow_url_include=1 -d auto_prepend_file=php://input faz o PHP executar
o corpo da solicitação como código → CVE-2012-1823.
A correção da CVE-2012-1823 é incompleta no Windows. O patch de 2012 adicionou
uma proteção em sapi/cgi/cgi_main.c: aproximadamente "se a string de consulta
(bruta) começa com - e não tem =, pule a análise de opções (skip_getopt)."
Um atacante que envia um - literal agora é bloqueado.
A codificação best-fit derrota a proteção (o bug de 2024). No Windows, o PHP
converte a linha de comando usando o codepage do locale com mapeamento best-fit
habilitado. O atacante envia %AD (byte 0xAD, hífen suave). No momento da
verificação da proteção, o primeiro byte é 0xAD, não -, então skip_getopt
não é definido. Depois, quando o PHP realmente constrói o argv, o Windows
mapeia por best-fit 0xAD → -, então o getopt agora vê -d. A injeção de
opções dispara depois da verificação que deveria impedi-la. Esse ordenamento
verificar-depois-converter é toda a vulnerabilidade.
Neste laboratório Linux, os passos 1–2 são reproduzidos exatamente com um php-cgi que é anterior ao patch do passo 3, então a forma literal
-funciona e demonstra o RCE idêntico. O passo 4 é a camada exclusiva do Windows, documentada mas não executada (o Linux não tem conversão best-fit).
Corrigida em 8.3.8, 8.2.20, 8.1.29. Portanto, vulneráveis:
Condições: sistema operacional Windows; PHP rodando como CGI ou php-cgi.exe
exposto (a configuração padrão do XAMPP no Windows é vulnerável); um locale
afetado para o caminho best-fit. (O bug pai CVE-2012-1823 — o primitivo que este
laboratório executa — afeta qualquer sistema operacional que rode um php-cgi anterior
à correção de 2012 nesta configuração.)
cve-2024-4577-lab/ ├── Dockerfile # builds the lab: compiles unpatched PHP 5.4.1 CGI + Apache ├── Dockerfile.vulhub # fallback: prebuilt vulnerable base image (if compile fails) ├── docker-compose.yml # one-command build+run, maps localhost:8080 -> 80 ├── start.sh # container entrypoint (Apache foreground) ├── exploit.sh # one-shot RCE PoC (bash + curl) ├── poc.http # raw HTTP requests (Linux payload + real Windows %AD payload) ├── app/ │ └── index.php # ordinary web page (NOT itself vulnerable) ├── config/ │ ├── apache-vhost.conf # the vulnerable Apache <-> php-cgi wiring │ └── php.ini # minimal php.ini (cgi.force_redirect=0, etc.) ├── flag.txt # the flag (copied to /flag.txt in the container) └── README.md # this file
## 5. Pré-requisitos
- **Docker Desktop** (Windows/macOS) ou Docker Engine (Linux).
Windows 11 Home: instale o Docker Desktop com o backend **WSL 2** (padrão).
→ https://www.docker.com/products/docker-desktop/
- `curl` para exploração (`curl.exe` já vem integrado no Windows 10/11; também está
disponível no Git Bash / WSL / macOS / Linux).
- Acesso à internet **durante o build** (baixa o código-fonte do PHP 5.4.1).
## 6. Instruções de build
Abra um terminal na pasta `cve-2024-4577-lab/`.
### Opção A — docker compose (recomendada)```bash
docker compose up --build -d