Repository navigation
php2shell verification v1.0.0 (2026-10-24)
php2shell verification report — v1.0.0 (2026-10-24)
Independent verification of CVE-2026-109618 / CVE-2026-109619 and the follow-up advisory
CVE-2026-115560. Lab-only: official PHP images, loopback traffic, disposable containers. No
production system was touched.
TL;DR
- Pre-auth RCE reproduced in the lab: 3/3 with
display_errors=On+ ASLR on; 3/3 with
display_errors=Off+ ASLR off (lab 8M override). 8.4.27 control: 0/5. - The forged-cookie channel discloses heap, not the session table. 47 Zend MM bin-64
free-list pointers reveal the id chunk base; the session HashTable is never in the window.
The leak narrowslibphpto a 1.88 MB window (~481 pages) with a fixed page offset; it does
not pin ASLR. - The
Off+ ASLR-on route is closed by both tested mechanisms. The leak does not exist on
FPM (payload A exits the worker), and onmod_phpthe leak's OOM clears the stale
BG(unserialize)state that chain E needs. post_max_sizeis not enforced on chunked bodies on unpatched branches (8.2.34, 8.3.35,
8.4.26mod_php): a chunked 30 MB multipart parses in full and a chunked 70 MB multipart
OOMs at defaults. 8.4.27/8.5.12 reject chunked bodies over the limit; FPM does not parse
chunked bodies; nginx body caps apply.- Chain D (stale
EG+ forgedzend_objectspray): the OOM precondition is confirmed, but
EG(objects_store),vm_stackandcurrent_execute_dataare identical at
php_request_shutdownbefore and after the OOM. The stale-EG step is not supported by our
measurements; only the OOM precondition is. - CVE-2026-115560: condition reproduced (
php_binaryconfig + runtimeini_set()tophp
beforesession_start()) as a decode failure without a memory-safety symptom. Inconclusive
until the full advisory is public.
What changed in this revision
- Corrected the "no leak" claim: the forged cookie does disclose heap; what it never
discloses is the session HashTable. - Corrected the "default limits stop the primitive" boundary: true for
Content-Lengthbodies
and the published payload sizes; chunked bodies bypasspost_max_sizeon unpatched
mod_php, and the 8.4.27/8.5.12 patch closes that route. - Added the closure of the
Off+ ASLR-on route (FPM negative + leak/E-OOM exclusivity), the
chain DEGmeasurement and the bounded 115560 attempt. - Added CVE-2026-115560 to the disclosure timeline and remediation guidance.
Contents
| File | Contents |
|---|---|
REPORT.md |
Full technical report |
RESUMEN.md |
Executive summary (ES) |
EVIDENCE.md |
Sanitized lab evidence and matrices (sections 1-12) |
validation/ |
PS(id) vs HashTable matrix and conclusions |
detection/ |
Additive Suricata and Sigma rules |
tooling/ |
oom_reach.py, forged_cookie_check.py, labkit/ |
raw/ |
Redacted raw lab captures |
POCS.md, COVERAGE.md, METHODOLOGY.md, REMEDIATION.md, FAQ.md, REFERENCES.md |
Supporting documents |
Defensive guidance
- Patch to 8.4.27 / 8.3.36 / 8.2.35 / 8.5.12.
- Keep stock resource limits; cap request bodies at the proxy (nginx
client_max_body_size
applies to chunked requests; ApacheLimitRequestBodydefaults to unlimited). session.use_strict_mode=1,session.use_only_cookies=1; disablesession.upload_progress
if unused. For CVE-2026-115560,session.upload_progress.enabled=0until the next regular
release.- Deploy the detection rules in
detection/(forged-cookie, groom signatures, abort bursts).
Assets
php2shell-REPORT.pdf— technical report (EN)php2shell-RESUMEN.pdf— executive summary (ES)SHA256SUMS— checksums of the assets
Scope and responsible use
This material is for defensive research, patch verification and controlled testing. No exploit
code is redistributed; public PoCs are reviewed by URL in POCS.md. Do not use the described
techniques against systems you do not own or have explicit authorization to test. For
vulnerabilities in PHP itself, follow the PHP project security process.