PHP php2shell (CVE-2026-109618 / CVE-2026-109619): session.upload_progress, check vs exploit
Admin · October 22, 2026 · 91 views
PHP core emergency: session.upload_progress and the php2shell chain
CVE-2026-109618 and CVE-2026-109619 are the php2shell research pair in PHP core: multipart upload handling tied to session.upload_progress can hit a use-after-free / memory corruption path (618 trigger) and, with build-specific primitives, 619 code execution. Vendor rating CVSS 9.2 Critical. Research name: php2shell.
Public PoC catalog entry: CVE-2026-109618 on pocbit.org. Repository: murrez/php2shell (not the legacy CVE-2026-109618 repo name).
| | |
|---|---|
| 618 | Trigger / memory corruption chain (multipart timing, progress session) |
| 619 | Follow-on RCE primitive — requires zend_call_function offset per binary |
| Emergency fix | 8.2.35, 8.3.36, 8.4.27, 8.5.12+ (per branch) |
| Partial config | session.upload_progress.enabled = Off — not a substitute for patch |
What defenders should assume
| Signal | Meaning |
|--------|---------|
| X-Powered-By: PHP/x.y.z below fix level | Patch candidate — banner may be hidden (CDN, expose_php=Off) |
| check → likely_vulnerable | Version math on banner — still not proof of exploitable UAF on that host |
| exploit → upload_accepted / inconclusive | Common on random production sites without lab monitor |
| exploit → armed | Strong lab signal when check_progress.php shows progress keys during stall |
| exploit → rce_hit | 619 + valid --call + command marker in body |
The bundled tool separates passive inventory (GET-only check, JSONL bulk) from active multipart tests (exploit, smart 618 multi-path). Use check for wide exposure scans; keep exploit lists small (many POSTs per host in smart mode).
Cross-read: how to prioritize critical CVEs, CVE PoC testing step by step, reading vendor security advisories, PoCbit CVE Detector.
Mechanism (high level)
- Client sends multipart upload with
PHP_SESSION_UPLOAD_PROGRESS(and related session upload fields). - Stall, micro, or session fixation variants probe how the server interleaves upload progress and session handling.
- On vulnerable builds, that timing can corrupt internal state (618).
- 619 is not portable: exploiters need
--call 0x…for the exact PHP binary (FPM, distro package, ASLR layout).
0x4148’s public lab (documented upstream) is the right place to prove armed — not your production customer site.
Defender checklist
| # | Action | Detail |
|---|--------|--------|
| 1 | Package version | php -v, php-fpm, container base image — map branch to emergency build |
| 2 | Patch | Distro security repo or official PHP builds — verify backports (banner can lag) |
| 3 | php.ini / pool | Set session.upload_progress.enabled = Off where product allows — after patch plan |
| 4 | Edge | Rate-limit large multipart POSTs to index.php / upload endpoints |
| 5 | Inventory | python poc.py check -f domains.txt -o results.jsonl — authorized assets only |
| 6 | Do not | Mass exploit against third parties; legal and noise risk |
python poc.py check https://example.com/index.php
python poc.py check -f targets.txt -o results.jsonl --workers 16
python poc.py exploit http://127.0.0.1:19268/index.php --monitor --stall 1.5
python poc.py exploit https://target.example/ -o one-host.json
Patch validation (lab)
- Run 0x4148 php2shell Docker lab or equivalent pinned vulnerable PHP.
exploit … --monitor --stall 1.5→ expectexploit_status=armedwhen progress endpoint reflects upload state.- Upgrade PHP to fixed build on same image; repeat — trigger should fail or not arm.
- Treat 619 validation as binary-specific research, not a generic scanner outcome.
FAQ
Banner says PHP 8.4 — are we safe?
Compare patch level to 8.4.27+ on that branch. PHP/8.4 without patch is branch_only in the PoC — patch unknown, not automatically safe.
Cloudflare hides PHP version
Then no_php_version in check output — run version checks on origin (SSH, deployment manifest).
Is disabling upload progress enough?
It reduces attack surface for this class but vendor guidance is patch first; other session/upload bugs won’t be covered by one ini toggle.
One CVE or two?
618 and 619 are paired IDs for trigger vs execution stage; PoCbit page cve-2026-109618 documents both with links to CVE-2026-109619.
Bottom line
php2shell is PHP core — patch 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12+ on every FPM and mod_php tier, verify versions on the origin, and use murrez/php2shell check for inventory and exploit only in labs or tightly scoped authorized tests.