eness/php2shell-CVE-2026-109618-CVE-2026-109619-PoC
php2shell is the name given to two critical pre-auth remote code execution flaws, CVE-2026-109618 and CVE-2026-109619, in PHP core's session upload progress handler (php_session_rfc1867_callback), where zend_hash_update frees live zval pointers that are later reclaimed and redirected into zend_call_function to run zif_system. This repository ships poc_109618.py, a fully automated four-stage HTTP exploit that leaks ASLR offsets via Set-Cookie headers against php:8.4.26-apache on Debian Bookworm, along with a root-cause C source patch, mitigation scripts to disable session.upload_progress, and WAF/ModSecurity/Lighttpd/Apache rules plus detection guidance for anomalous PHP worker child processes. Confirmed PHP versions include 8.4.4 and 8.2.34, with EOL branches (5.x, 7.x, 8.0, 8.1) left without official vendor patches.
What it is
php2shell is the name for CVE-2026-109618 and CVE-2026-109619, two pre-auth RCE flaws in PHP core, rated CVSS v4.0 9.2. Details leaked on October 20 (2026), ahead of coordinated disclosure. The repository by eness holds a working exploit, poc_109618.py, plus mitigations. watchTowr reproduced CVE-2026-109618. Huntress and Florian Roth (process-watcher) are monitoring it. The page demonstrates only 109618 and does not describe 109619 separately.
How it works
php_session_rfc1867_callback in ext/session/session.c keeps two raw zval * pointers (post_bytes_processed, current_file_bytes_processed) into live HashTables. A progress update re-reads session data, and zend_hash_update() frees the old tree. The dangling pointers are then reclaimed by crafted zend_fcall_info and zend_internal_function structures, and zend_call_function() runs system().
The PoC defeats ASLR over plain HTTP in four stages:
- Rotate the prefork worker to get a clean heap.
- Send an oversized multipart field (
--huge-mb, default 12MB) to force OOM and leak the Zend MM chunk base throughSet-Cookie: PHPSESSID. - Leak the
ZVAL_PTR_DTORpointer throughSet-Cookieto compute thelibphp.sobase. - Forge a fake HashTable inside a 167-byte
zend_string, withpDestructorpointing atzif_system. It overwritesPS(http_session_vars), and freeing the session data runs the command.
The command lives inside that string, so inline commands are capped at 14 bytes (MAX_CMD = 14). Longer payloads need a short trigger such as sh</tmp/c.
Preconditions / Affected
session.upload_progress.enabled = 1, which is the PHP default, and a multipart POST.- The default exploit profile targets mod_php under Apache prefork with
display_errors = 1,memory_limit = 8M(or below--huge-mb),max_input_vars = 1000,session.use_cookies = 1andsession.use_strict_mode = 0. - Calibrated for
php:8.4.26-apacheon Debian 12 (--profile bookworm) and for custom Apache 2.4.68 builds (--profile lab). Other layouts need--zif-offsetand--dtor-offset. Local Docker targets can be auto-profiled viadocker/offsets.py. - Confirmed on php-src 8.4.4 and 8.2.34. The page says PHP 5, 6, 7 and 8 "may be affected". EOL branches (5.x, 7.x, 8.0, 8.1) get no official patch.
What to do
Disable the feature (file uploads keep working), then reload the service:
session.upload_progress.enabled = Offphp_admin_flag[session.upload_progress.enabled] = offThe second line is for FPM pool files such as /etc/php/*/fpm/pool.d/www.conf. The repo's helper script:
sudo ./quick-fix/run.sh --check
sudo ./quick-fix/run.sh --dry-run
sudo ./quick-fix/run.sh
sudo ./quick-fix/run.sh --revertWhen building from source, apply patch/session-upload-progress-counters.patch, which stores the counters as zend_long and adds php_session_rfc1867_sync_counters():
git apply --check /path/to/patch/session-upload-progress-counters.patch
git apply /path/to/patch/session-upload-progress-counters.patchThen rebuild, install and restart. For PHP 5.6, 7.4, 8.0 and 8.1, the page links third-party backports in Anton-Barinov/php2shell-patches. They build side by side into /opt/php-<ver>-patched.
Other controls in the repo:
- FrankenPHP:
php_ini session.upload_progress.enabled 0inside thefrankenphpblock. - ModSecurity:
apache/modsecurity-php2shell.confdenies requests whoseARGS_NAMESequalPHP_SESSION_UPLOAD_PROGRESS(rule id 1026109618). - Apache and Lighttpd:
apache/.htaccessandlighttpd/php2shell.confblock POST, PUT and PATCH requests withmultipart/form-dataon paths that take no uploads. - Cloudflare: templates are in
cloudflare-rule-fix/.
For detection, alert on PHP workers (php-fpm, php-cgi, php-cgi.exe, httpd, apache2) spawning:
- shells (
/bin/sh,/bin/bash,cmd.exe,powershell.exe); pythonorperl;curl,wget,ncorcertutil.exe;- reverse-shell strings (
/dev/tcp/,fsockopen,mkfifo); - recon commands (
whoami,id,uname -a,ipconfig).
Where no EDR is present, run process-watcher in observe mode. After suspected compromise, isolate the host, keep web and PHP logs, and check /tmp and /var/tmp for dropped files.
Caveats
- Vendor patches were scheduled for about October 21 at 14:00 UTC. The page does not confirm release or give fixed version numbers.
- The page warns against blocking on the PHPSESSID cookie alone, because it breaks valid sessions. Blanket multipart blocking breaks uploads, so scope it to non-upload routes.
- The exploit is tuned to specific builds. Success elsewhere depends on correct offsets and a matching configuration.
- The author states the repo is for authorized research only.
Organisations named here
- php_session_rfc1867_callback
- zend_call_function
- zif_system
CVEs named here
- CVE-2026-109618
- CVE-2026-109619
Technologies named here
- PHP core
- poc_109618.py
- Official Docker PHP image
- docker/offsets.py
- Apache HTTP Server
- process-watcher
- WordPress
- quick-fix/run.sh
- patch/session-upload-progress-counters.patch
- Drupal
- Joomla
- Anton-Barinov/php2shell-patches
- cloudflare-rule-fix/
- Magento
- frankenphp/Caddyfile-snippet
- OpenCart
- cPanel
- lighttpd/php2shell.conf
- Plesk
- apache/modsecurity-php2shell.conf
- FrankenPHP
- apache/.htaccess
- lighttpd
- PHP
- Docker
- Cloudflare
- Huntress
- WatchTowr
Techniques named here
- Remote ASLR bypass via OOM-induced memory leak
- Remote base address leak via session serialization alignment
- HTTP worker rotation for clean heap state
- Detection via anomalous child process monitoring
- Use-after-free
Threat actors named here
- PHP2Shell
Related in Offensive Security