All articles
24 October 2026
10 min read

php2shell after the patch: exploitation and fallout

By Tim Rutte, Cloud & Software ArchitectTopicLegacy & Modernization

A weathered white picket fence with a blue picket firmly fitted; in front of it lie two broken old pickets, a hammer and nails.

As of 24 October 2026, 21:00 UTC. All times in UTC unless stated otherwise.

On 21 October the PHP team closed the two critical flaws CVE-2026-109618 and CVE-2026-109619 with PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. What was known before and on release day is in php2shell: what is confirmed about the critical PHP flaws.

This article records what happened in the three days after. It only reports what a named source says, and it separates observations from claims. Where sources contradict each other, both are given.

The key points

  • There are a great many attack attempts. As of this writing, one successful attack on a real target has been publicly confirmed, reported by Palo Alto Networks Unit 42.
  • Sophos reported a successful exploitation on 22 October and withdrew it five hours later.
  • CISA, Germany’s BSI and Rapid7 know of no confirmed successful exploitation. Neither CVE is in the CISA KEV catalog.
  • According to Rapid7 and Sansec, the public exploits only work under narrow conditions, not against a default installation.
  • On 23 October the PHP team announced another flaw, CVE-2026-115560. There is no patch yet; the stopgap is the same as before.
  • The patch itself has side effects: several possible regressions have been reported against 8.5.12 and 8.4.27, none confirmed so far.

Attacks: many attempts, little evidence

The reports from security companies in chronological order:

TimeReportSource
17 OctA php2shell exploitation attempt in Amazon’s honeypots, four days before the patchAWS Security Blog
21 Oct, approx. 02:00The first proofs of concept appear; judging by payloads and infrastructure, the attempts that follow come from several actorsAWS Security Blog
21 Oct, 03:02Cloudflare enables protective rules for all WAF customers, about nine hours before disclosureCloudflare
21 OctHadrian speaks of exploitation “at scale”; most attacks used the session upload progress pathThe Register
by 22 OctCloudflare CEO Matthew Prince on X: thousands of attempts in the ten hours before disclosure, tens of thousands 45 minutes after, hundreds of thousands after two hours and millions sinceThe Register
22 Oct, 16:18Sophos reports a successful exploitation with the Mirai variant “Potassium” as payloadSophos
22 Oct, 21:21Sophos corrects itself: telemetry shows scanning and a few failed attempts, the payload was not deliveredSophos
22 OctSansec: mass exploitation is less likely than expected on release daySansec
23 Oct, 12:30 PTUnit 42 describes a successful attack on a European government entityUnit 42
24 OctRapid7: no exploitation observed, but multiple reports of attemptsRapid7

The only reported hit. According to Unit 42, within two hours of initial exploitation the attackers had obtained password hashes and multi-factor authentication secrets, set up an NTLM relay tunnel into Active Directory and attempted to become domain admin. Their reconnaissance output was structured with delimiters such as ==SHELLUSER==, which Unit 42 reads as being made for an AI model to parse. I have not found a second, independent source for this case.

The Sophos correction. On 22 October at 16:18 Sophos wrote of a successful exploitation. At 21:21 came the sentence “we are correcting that assessment”: customer telemetry showed scanning and a small number of failed attempts, and there was no evidence of a successful compromise through these flaws. Anyone who reported in the hours in between picked up the first version.

Numbers without a denominator. Cloudflare’s millions count requests that triggered a rule, not vulnerable servers and not break-ins. Cloudflare’s own blog gives no number and only says attackers mutated their payloads to try to get around the rules. Unit 42 counts over 22.6 million exposed instances that are “potentially vulnerable”. That is an estimate of the attack surface, not a count of vulnerable systems.

What the authorities say

BodyStatusStatement
CISA (US)Alert of 21 Oct, revised 23 OctNo successful exploitation observed. Organizations that cannot update immediately or run PHP 8.1 or older should take the systems offline.
CISA KEVCatalog version 2026.10.23CVE-2026-109618 and CVE-2026-109619 are not in the catalog, so there is no deadline for US federal agencies either.
BSI (Germany)Cyber security warning, version 1.2 of 22 Oct, level 3 / orangeNo confirmed reports of compromised systems from regulated industry or the federal administration. Reports that the patches are incomplete and can be bypassed “have been refuted”.
CERT-EUAdvisory 2026-018, version 1.2 of 23 OctAdds CVE-2026-115560.
NCSC (UK)21 Oct, modified 23 OctAnyone not updating immediately should first check the system for evidence of compromise and for “backdoors installed by an attacker”.

The BSI also lists products that ship PHP and for which the vendors have published their own notices, including F5, Citrix NetScaler, pfSense, QNAP, Synology and cPanel. If you run such appliances, you depend on the vendor’s update, not on the PHP release.

How good the public exploits are

Since 20 October, numerous repositories with “php2shell” in their name have appeared on GitHub. What the experts say about how well they work:

  • Rapid7: each public proof of concept demonstrates code execution only against a specific combination of operating system, PHP version and web server, and none appears “broadly reliable”. Rapid7 itself has a working exploit only under narrow lab conditions.
  • Sansec: “The public exploits do not work against a default PHP installation.”
  • Red Hat rates the flaw differently, as “Important” with a CVSS 3.1 score of 8.1. Its reasoning: RHEL uses PHP-FPM by default, whose workers exit on early initialization failures before reaching the corrupted structures. Code execution there is “difficult in practice”.

This matches the PHP team’s advisory of 21 October, which confirms a complete exploit for mod_php and explicitly none for PHP-FPM in the case of CVE-2026-109618. At the same time, Rapid7 warns that a more portable technique could emerge at any time.

A new flaw: CVE-2026-115560

On 23 October the PHP team published an informational advisory on php.net. It recommends setting session.upload_progress.enabled=0 until the next regular bugfix release “to fully protect from an unlikely RCE vector”.

According to the PHP team, the flaw only occurs when all of the following apply:

  • the application sets session.serialize_handler to php_binary or php_serialize in its configuration,
  • switches it to php at runtime with ini_set() before session_start(),
  • and session upload progress is enabled.

Applications that never switch the handler at runtime can keep the feature enabled, according to the PHP team. If you already applied the setting as a stopgap on 21 October, no further action is needed. A full advisory is to follow with the next release; the PHP team gives no date. As of this writing there is no 8.5.13 or 8.4.28.

Since 24 October the PHP issue tracker carries a proposal to switch session.upload_progress.enabled off by default (issue #24648).

What the patch changes and what it triggers

The fix for CVE-2026-109618 (“Avoid state corruption via bailout”) changes how PHP reacts to running out of memory. memory_limit no longer raises the error immediately but deferred. There is a new setting, memory_hard_limit_percent: if this hard limit is exceeded, the process exits with exit code 137 instead of raising a catchable error.

Since the release, several bugs have been reported against it in the PHP issue tracker. All are still at “Needs Triage” or have no status; none is confirmed:

IssueReportedContent
#2449221 Oct, 18:08sprintf(), pack() and bin2hex() end the process with _exit(137) where 8.5.11 still raised a catchable out-of-memory error
#2449321 Oct, 18:13The upload progress handler in 8.5.12 destroys the whole session when a stored object has certain property names
#2449721 Oct, 19:05memory_hard_limit_percent reports a wrong default value
#2463124 Oct, 03:40A deferred out-of-memory error raised during compilation is dropped when compilation fails

For operations this means: if you see workers ending with exit code 137 after the update, think of the new hard limit first, not of an attack.

Who shipped fixed packages when

SourceStatus
Debian 12 and 13Fixed on release day (DLA-4848-1, DSA-6574-1). In unstable and forky php8.4 8.4.27-1 is fixed, the php8.2 package in unstable is not yet
UbuntuFixed on release day, older releases through Ubuntu Pro (USN-8948-1, USN-8948-2)
Red Hat Enterprise Linux 8, 9, 10RHSAs of 21 Oct, EUS, AUS and SAP variants on 23 Oct. The php:8.4 module on RHEL 9 is still marked “Affected”
remirepoPackages for 8.2.35, 8.3.36, 8.4.27 and 8.5.12 on 22 Oct at 12:58, one day after the release
FrankenPHPVersion 1.13.2 with the patched PHP versions on 21 Oct at 18:19, 1.13.3 on 23 Oct
Laravel CloudAll running applications patched without a redeploy (as of 23 Oct, 08:31)
Laravel ForgePatched versions from PHP 5.6 to 8.5; on Ubuntu 20.04 and older no update is possible, Forge recommends a new server
Laravel VaporRedeploy required; no patch for PHP 8.0 and 8.1

Two patterns stand out. First, every platform that runs PHP for its customers has a different answer, from “already done” to “move elsewhere”. Second, everything below PHP 8.2 depends on distributions and vendors that backport; the PHP project itself only provided source backports for 7.4 to 8.1. The routes available for these versions: php2shell on PHP 7.4, 8.0 and 8.1. From January that applies to PHP 8.2 as well: PHP 8.2 ends on 31 December.

The dispute over the embargo

In its post on the release, the PHP Foundation named three points at which information got out before the coordinated date. The third has drawn the most attention:

  • The CVE numbers circulated from around 15:00 on 20 October, with a wrong score and a wrong time.
  • Calif mistakenly published a video of its proof of concept around 20:00.
  • Chainguard published ready-built images containing the fix on 21 October at 07:41, “more than six hours before the coordinated release”. That let anyone study the patch in binary form while everyone else was still waiting.

According to TechTarget, Chainguard CEO Dan Lorenc explained the move on LinkedIn: “This decision was based on how easily we were able to independently discover the vulnerability and build an exploit”. Media differ on whether he apologized. TechTarget reports that he regretted the extra strain on the Foundation and the maintainers, The Register that he did not apologize. I have not found a Chainguard post of its own on the matter.

Clint Gibler, head of cyber research at OpenAI, wrote according to TechTarget: “We were intending for the patch to go live Thursday, but a rumor/leak started Tuesday”. The Foundation itself calls the months-long delay in fixing the flaw “a structural failure” and announces that its security team will make decisions by majority in future.

What the official bodies recommend now

Summarized from the PHP team, CISA, BSI and NCSC, without additions of my own:

  1. Update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or to a distribution package with both CVE numbers in its changelog. According to the PHP team and the BSI, this is the only complete protection.
  2. Keep session.upload_progress.enabled=0 until the next bugfix release, because of CVE-2026-115560. Set it in php.ini, the FPM pool or the server configuration, not via ini_set() or .user.ini.
  3. Take offline what cannot be updated, explicitly including PHP 8.1 and older (CISA).
  4. Check for compromise before a late update, in particular for backdoors (NCSC).
  5. Secure appliances with built-in PHP through their vendors’ notices (BSI, NCSC).

Frequently asked questions

Is php2shell being exploited at scale? There are attempts at scale. As of this writing, CISA, the BSI and Rapid7 know of no confirmed successful exploitation at scale. One successful attack has been publicly described, by Unit 42.

I updated on 21 October. Do I need to do anything else? Because of CVE-2026-115560, the PHP team recommends setting session.upload_progress.enabled=0 until the next release. Only applications that switch the session serializer at runtime are affected.

Is the patch incomplete? According to the BSI, reports saying so have been refuted. What has been reported are regressions, bugs the patch may have introduced, not bypasses.

Why is php2shell not in the CISA KEV catalog? Only flaws with evidence of exploitation are added. CISA says it has not observed successful exploitation.

Sources

If you want to keep track of your versions continuously rather than only at the next leak, you need patch management that covers servers and images, not just the packages in the repository.