ThreatIntelligence-IncidentResponse

php2shell: Why One Exploit Doesn’t Work Everywhere


php2shell raised fears of mass exploitation. A week of testing by our research team found that working exploits had to be fitted to each target’s exact PHP setup. Systems that share one build, such as network appliances, are the exception: one tuned exploit can reach every device that runs it.

Key takeaways

  1. The five vulnerable PHP sites we exposed to the internet were not compromised, and public proofs-of-concept (PoCs) that go beyond version checks do not reliably confirm whether a host is vulnerable. Exploitation has been confirmed elsewhere, on researcher honeypots and on some network appliances.
  2. In realistic environments, turning php2shell into remote code execution usually takes an exploit built for the specific target. That is hard, not impossible, and it puts php2shell in a different category from Log4Shell, even though both received near-maximum severity ratings. Where many systems share one build, such as network appliances, a single calibrated exploit can work against all of them.
  3. Patch now, starting with internet-facing management interfaces, network appliances, and end-of-life PHP branches. Tenable Nessus and Tenable One Web App Scanning have had version-based detection since October 21.

Background

On October 20, 2026, PHP announced two vulnerabilities, and on October 21 released fixes for flaws that can allow unauthenticated remote code execution. CVE-2026-109618 is an out-of-memory handling flaw. CVE-2026-109619 is a use-after-free flaw caused by stale state shared between requests on the same worker. Each has a CVSSv4 score of 9.2. For a full breakdown of affected versions, fixes and mitigations, see our frequently asked questions blog post.

This post covers what happened after the disclosure, based on what our team observed directly.

From disclosure to headline in under 48 hours

php2shell got big fast. Details of the vulnerabilities leaked online before the official release. Within two days, the vulnerability had a name, a logo and coverage in mainstream media.

Several websites went offline as a precaution, as described in our threat actor response blog post. Censys’s php2shell dashboard, which tracks PHP services by reported version, showed about 30.3 million PHP services still on an affected version on October 29, though a matching version does not mean a system can be exploited.

The comparison with Log4Shell came up early, but the two are very different to exploit. With Log4Shell (CVE-2021-44228), attackers only had to send a short piece of text to a vulnerable application, for example in a login form or a web request. If the application logged that text, the attack worked. The same text worked against almost any vulnerable target without changes, so attackers could launch it at scale within hours, and many of those attacks succeeded.

php2shell is different. Exploitation depends on the state of the heap, the process manager in use, worker reuse and how memory is laid out on a given build. php2shell drew attention quickly, but attackers can’t exploit it as easily as Log4Shell.

What changed while we were testing

Several developments that matter for defenders came after our research began:

  • On October 24, honeypots run by Perplexity researcher Adel Karimi recorded 35 successful shell executions across three sensors running PHP 8.4.26 under Apache mod_php with a single worker, a configuration that favors the exploit.
  • On October 26, CISA added CVE-2026-109618 and CVE-2026-109619 to its Known Exploited Vulnerabilities (KEV) catalog. Federal civilian agencies have until October 29 to remediate.
  • The same day, security firm Dream reported an attack chain that combined php2shell with a Linux kernel privilege escalation flaw, Fragnesia (CVE-2026-46300). Dream says the campaign rooted “25 PAN-OS firewall and management servers across the United States, Japan, Taiwan, and South Korea.” Palo Alto Networks’ Unit 42 says it independently verified the same attacker’s tooling and confirmed the reported results. We have not verified these findings ourselves.
  • On October 28, CISA added Fragnesia to the KEV catalog and noted that it can be chained with php2shell to run commands as root. By October 29, Palo Alto Networks reported active exploitation targeting internet-exposed PAN-OS management interfaces.

These reports are consistent with what we found. The exploit has to be calibrated to a specific build. Network appliances often run the same software across many devices, so one calibrated exploit can reach many of them. That is where we expect targeted exploitation to keep growing.

What we observed during our exploit research

Exposed targets

To measure real-world activity, we kept five vulnerable PHP sites reachable from the internet: four through the evening of October 24, and one still running in a standard, vulnerable configuration at the time of writing.

Over that period, we observed mass exploitation attempts that matched php2shell exploitation patterns. None of our targets had been compromised as of October 29.

Other organizations have reported exploitation attempts and, in the cases described above, successful exploitation. Amazon Threat Intelligence says php2shell is “now seeing broad exploitation attempts in the wild.” Our data does not contradict these reports. It shows that attempts, even at scale, were not enough to compromise a default installation in our environment. Attempts and successful compromises are two different numbers, and in the first days after a disclosure people often treat them as the same.

Public proofs-of-concept

We collected and tested almost all public PoCs. An early lead was php2shell poc, published by researcher Daniel Púa (devploit). It let us reproduce the exposure on multiple 8.4 and 8.5 environments with specific configurations. From there, we did deeper research, including white-box testing and code and patch comparison, and achieved remote code execution on PHP 7.4.33.

What we learned from this research is that the exploit inadvertently reveals a clean discriminator: the same multipart POST that begins stage 1 produces a different allocator response on patched vs. unpatched PHP. No heap corruption, no crash, no shell, just a measurable size difference in how the server handles the request. That became signal 1: a large filename in the multipart request produces a measurably different allocation size on vulnerable versions than on fixed versions, because the patched allocator rounds to a corrected size class. Same request, same PHP – different memory behavior depending solely on whether the UAF patch is present.

Tenable Research identified a second signal as well: the compact amplification sequences that exercise the UAF window’s existence without triggering corruption. The session upload-progress oracle watches for the crash/recover pattern that vulnerable versions exhibit under controlled amplification.

These two signals became a stateful probe that a Nessus ‘direct check’ plugin could detect. However, the probe would miss some vulnerable systems and flag some patched ones as vulnerable.

The memory corruption is real, and PHP confirms memory disclosure as one of the impacts. Turning it into code execution on a target is difficult and unique to each target. Our working RCE required an exploit tuned to the target’s environment, including its PHP build, SAPI, extensions and runtime configuration. A payload that works against one lab setup does not carry over to a different distribution package or a different PHP-FPM pool configuration.

AI-accelerated research: Useful, but it needs checking

AI agents sped up our reverse engineering and testing, and they also produced at least one convincing false positive. During a multi-hour session, an agent built a working shell against our PHP-FPM lab containers and reported it as confirmation of CVE-2026-109618 and CVE-2026-109619. It was not. The agent had used a local file inclusion weakness that we had added to the lab, a different attack class that does not exist in default PHP deployments. A researcher caught the error by checking the exploit chain against the vulnerability’s mechanics.

The lesson applies to anyone reading exploitation claims this week: a real shell is not proof that a specific CVE was used. We also ran into inconsistent responses from AI tools when doing authorized exploit validation, which slowed parts of the work.

White-box testing

The GDB analysis and heap geometry research below show why: there is no universal offset. Code execution is a real exposure yet it is not as simple as portrayed. The RCE we achieved on PHP 7.4.33 worked only once the exploit matched that one setup. A profile that achieves a shell against one lab container does not carry over to a different distribution package, a different PHP-FPM pool configuration, or a different memory limit.

The chunk-relative offsets pictured in the ‘heap geometry capture method’ visuals below reference _zend_array at chunk+0x572a0, arData at chunk+0x64b80. These values illustrate the measurement method and are specific to PHP 8.3.35 built from the docker-library bookworm image on amd64. A Debian-packaged PHP 8.3.35, or a PHP 8.3.35 built with different extensions, produces different chunk geometry values. We used GDB against the live worker to measure the actual values for a given target.

Summary of research artifacts

Our failure to show that mass exploitation is quick or easy does not make this vulnerability harmless. A well-resourced attacker who wants a specific target can build that exploit, and AI-assisted tooling shortens the time it takes. It does make mass exploitation of the Log4Shell kind much less likely. The exception is any population of systems that share one build, such as network appliances, where the cost of calibration is paid once.

GDB analysis of a PHP workerHeap geometry capture method

Why exploitation is hard

When possible, Tenable Research releases exposure direct checks to help customers detect exploitable vulnerabilities within their environments. These direct checks depend on finding reliable and safe methods of exercising a vulnerability in a way that simulates an exploit without triggering any destructive actions. This typically involves first researching how to develop an exploit, then figuring out how to test that safely.

Our research found the php2shell exposure difficult to reproduce broadly, even with white-box testing and GDB attached to processes, and even with AI agents analyzing runtime memory and source code for weaknesses and leads in parallel. What we learned from this research helps to inform us on the practical realities of real-world exploitation:

  • php2shell is a multi-stage memory corruption chain. A direct check triggering an out-of-memory condition alone does not fully guarantee the asset is also exposed to remote code execution.
  • In-memory offsets are version and system specific. The chunk-relative structure offsets required for heap manipulation change with every PHP patch release and system/software combination. Gaps in an inventory of known offsets and platforms could make a vulnerable system look patched (false-negative).
  • The OOM trigger depends on application-controlled memory limits. Whether the condition fires depends on the configured memory_limit and on whether the application overrides it via ini_set, PHP_VALUE, or PHP_ADMIN_VALUE per-request directives.
  • The use-after-free requires reuse of the PHP worker across consecutive requests. Under mod_php, keep-alive pins a connection to one worker; under FPM, session affinity (PHPSESSID) is required. Both depend on SAPI and process-manager settings. For example, pm.max_requests recycles workers and breaks the use-after-free chain with no visible sign, so the check returns a false negative.
  • The exploit crashes PHP workers. Workers appear to respawn reliably, but a direct check that intentionally degrades performance could still affect production systems.

What can we learn from this

Inevitably, when a remote code execution vulnerability is discovered in a broadly deployed core component of the services we use, a knee-jerk reaction is triggered that creates significant fears of mass exploitation and extreme risk. While we do not want to downplay the dangers of this vulnerability, it is valuable to understand the practicalities of exploitation in the real world versus the fear that is built around a CVE during the regular news cycle. In this case, that nuance points remediation first at internet-facing assets, especially appliances such as network infrastructure management interfaces, and anything else that runs a common, basic deployment that reduces overall complexity.

Prioritization matters more as AI finds more vulnerabilities

Calif, OpenAI and Wiz are credited with finding php2shell. Calif says AI assisted the discovery. We expect the number of disclosed vulnerabilities to keep rising as these tools improve, and many of them will come with high base scores. Patching everything rated critical at the speed of the news cycle will not be possible.

Security teams need to understand what a vulnerability takes to exploit, not only how bad the worst case is:

  • Is there a public exploit that works without changes, or only a crash PoC?
  • Does exploitation depend on a non-default configuration, a specific build or prior access?
  • Is the vulnerable component reachable from the internet in your environment?
  • Has anyone observed successful compromise, as opposed to scanning?

Exploit prediction scores such as EPSS, Tenable’s Vulnerability Priority Rating (VPR) and confirmed exploitation sources such as CISA’s KEV catalog help answer these questions. They work better alongside an analysis of the vulnerability itself than in place of one.

Patch anyway

Our observations do not mean php2shell should be ignored. The conditions for exploitation exist, exploit development will improve and targeted attacks against high-value PHP applications are plausible. Updating to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or applying your distribution’s fixed packages, remains the recommendation. For end-of-life branches, plan an upgrade. Until then, apply the configuration mitigations described in our FAQ and limit internet exposure, starting with appliance management interfaces. For network appliances, PHP version numbers do not apply: use your vendor’s fixed build or its interim mitigations.

What we are recommending is a different order of work. Patch or isolate internet-facing network appliances, management interfaces, and end-of-life PHP systems now. For the rest of your PHP estate, patch on your critical schedule, and check that less publicized vulnerabilities that are easy to exploit in your environment are not waiting behind php2shell.

Get more information

Join Tenable’s Research Special Operations (RSO) Team on Tenable Connect for further discussions on the latest cyber threats.

Learn more about Tenable One, the Exposure Management Platform for the modern attack surface.



Source link