ASLR-bypassing RCE PoC for PHP's session.upload_progress chain (CVE-2026-109618 / CVE-2026-109619). Single file, no gdb, no /proc - addresses leaked in-band via Set-Cookie. PHP 8.4.26 & 8.5.11.
# PHP2SHELL
**HTTP-only, ASLR-bypassing remote code execution for PHP** — a single-file proof of concept for
**CVE-2026-109618** and **CVE-2026-109619** (the `session.upload_progress` / RFC 1867 memory-safety
chain, *"php2shell"*). No debugger, no `/proc`, no binary blob: addresses are leaked **in-band over
HTTP** and the payload multipart body is built on the fly.

> ⚠️ For **authorized security testing, research and education only**, against systems you own or
> are explicitly permitted to test. The affected versions are **already patched** (see below) and the
> underlying techniques are public. See [Disclaimer](#disclaimer).
---
## What it does
A single unauthenticated HTTP request flow against an Apache + `mod_php` target leaks enough memory
through the `Set-Cookie` response header to defeat ASLR, then reclaims a dangling session reference to
redirect a destructor pointer to `zif_system`, executing a command as the web user — **without relying
on any `disable_functions`-restricted PHP function** (the execution happens through memory corruption).
```
stage 1 OOM before RINIT leaves PS(id) dangling → a forged zend_string
makes Set-Cookie disclose the Zend MM chunk base ⟶ heap ASLR bypass
stage 2 a 56-byte HashTable overlaps PS(id)+0x18 so its pDestructor
(a libphp pointer) lands in Set-Cookie ⟶ libphp ASLR bypass
stage 3 dangling PS(http_session_vars) is reclaimed with a fake array +
execute_data; pDestructor = zif_system ⟶ command execution
```
Everything is in-band HTTP: the two leaks come from `Set-Cookie`, worker rotation is triggered by a
crashing request, and the fire is plain `multipart/form-data` POSTs.
## Status
| PHP branch (latest affected) | In-band ASLR leak | Full RCE |
|---|:---:|:---:|
| **8.5.11** (x86_64) | ✅ | ✅ |
| **8.4.26** (x86_64) | ✅ | ✅ |
| 8.3.35 (x86_64) | ✅ | ⏳ stage-3 geometry not cali