Technical Advisory_ PHP2Shell Pre-Auth RCE

Technical Advisory: PHP2Shell Pre-Auth RCE (CVE-2026-109618, CVE-2026-109619)

Share this Share on email Share on twitter Share on linkedin Share on facebook

[CRITICAL] | CVSS v4.0 9.2 | No exploitation observed by Bitdefender | Patch immediately

TL;DR

PHP2Shell is a pair of critical pre-authentication remote code execution flaws (CVE-2026-109618 and CVE-2026-109619, CVSS v4.0 9.2) in the PHP worker process, and every unpatched PHP installation serving web requests is at risk, with Apache servers running mod_php at highest risk. Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35 now; on 8.1 or older, which have no official fix, move to a supported branch. Bitdefender has not observed exploitation and Bitdefender Labs and the MDR team are monitoring; to use the access the flaws give them, attackers must act on the server, and GravityZone detections cover those actions. For exact remediation steps including how to identify affected systems and assess for prior compromise, see What To Do below.

Advisory History

2026-10-22: Initial publication. Bitdefender telemetry shows no PHP2Shell exploitation attempts as of this date. Bitdefender Labs and the MDR team are monitoring the situation.

Situation

The flaws were first discovered by lcfr_hax of Calif, which reported an unconditional remote code execution with a shared root cause to PHP on 2026-08-11. OpenAI independently reported the same root cause that day, Wiz Research reported on 2026-08-24, and OpenAI sent further attack vectors on 2026-09-18 (The PHP Foundation, “Today’s PHP security release and how we’re strengthening PHP security”, October 2026). Wiz Research demonstrated unauthenticated remote code execution against the WordPress, Drupal and Joomla container images and credits frontier AI models with substantially lowering the barrier to exploit development.

The coordinated disclosure held until two days before the planned release. On 2026-10-20 at about 15:00 UTC the CVE IDs began circulating online with a wrong release time and a CVSS score of 10.0 (the actual score is 9.2). PHP published its pre-announcement early at 19:30 UTC and moved the release forward from 2026-10-22 to 2026-10-21 at 14:00 UTC. At about 20:00 UTC Calif mistakenly published a video showing its proof of concept working against a number of targets. PHP says no technical details leaked, but the video contributed to the faster development of various proofs of concept. On 2026-10-21 at 07:41 UTC Chainguard published container images containing the fix more than six hours before the release, breaking the embargo. PHP released the fixed versions at 14:00 UTC and published PHP, “Security advisory 2026-10-21-5”, October 2026 with them (The PHP Foundation, October 2026). PHP states that its security team identified no functional exploits at the time of release.

Datadog Security Labs, “PHP2Shell critical vulnerabilities”, October 2026 reports that AWS saw exploitation attempts from 2026-10-17, and describes broad untargeted scanning. Bitdefender has not independently confirmed this. Operational guidance is maintained by NCSC-NL, “PHP2Shell operational page”, October 2026 and in CERT-EU, “Security advisory 2026-018”, October 2026.

Several GitHub repositories claim to host proof-of-concept (PoC) exploits. JFrog, “PHP2Shell: all you need to know”, October 2026 reports that some are pranks, one of which changes the victim’s wallpaper. Treat every unofficial PoC as untrusted code.

wp2-advisory-image1

Bitdefender telemetry has observed no PHP2Shell exploitation attempts as of publication, and Bitdefender Labs and the MDR team are monitoring the situation. This is a time-bound observation and not evidence that the threat is overstated. Any change will be recorded in Advisory History.

A Disclosure Is Not an Exploitation

Much of the early coverage of PHP2Shell blurs two different events, and the difference changes what you should do.

A vulnerability disclosure says a flaw exists, how severe it could be, and which versions fix it. The CVSS score of 9.2 describes what an attacker could do, not what any attacker has done. A disclosure carries no evidence that anyone is attacking anything.

A proof of concept is code that demonstrates the flaw. Proofs of concept range from working research tools to broken or malicious fakes, as the repositories above show. A working proof of concept lowers the cost of an attack but is not an attack.

Exploitation in the wild means someone has used the flaw against real systems that did not belong to them, and defenders have the evidence: requests, crashes, shells, files. Only this stage justifies statements such as “customers are being compromised.”

PHP2Shell sits between the second and third stages. It is disclosed and patched. Working proofs of concept exist in researchers’ hands, and Calif’s video showed one against a number of targets. PHP’s team saw no functional exploits at release. Datadog attributes exploitation attempts to AWS from 2026-10-17, which we have not confirmed, and Bitdefender telemetry shows none. Bitdefender Labs and the MDR team are watching for the next step.

Two conclusions follow, and they point the same direction. Do not treat the absence of confirmed attacks as a reason to wait, because the flaw needs no login and no application bug, and the proofs of concept and fixed code are public. And do not treat the severity score as proof of compromise: patch first, then check for compromise using the signals in What To Do, instead of assuming the worst.

How It Can Be Exploited

PHP runs behind the web server through a SAPI (Server API), the interface that hands each request to PHP. The two most common are mod_php, where PHP is loaded directly into the Apache web server’s own processes, and PHP-FPM, a separate pool of PHP worker processes that the web server forwards requests to. Both CVEs are memory corruption bugs, meaning the attacker causes PHP to read or write memory it should not, inside those worker processes.

On mod_php, exploitation happens during request initialization, before any application code runs. We assess that PHP2Shell is a runtime bug, not an application bug: on mod_php, CMS updates, plugin hygiene and application hardening do not change exposure. The attacker needs no login and no flaw in WordPress, Drupal or the custom code behind the site.

We assess with high confidence that exploitation attempts will follow. Calif’s video of a working proof of concept, Wiz’s demonstrations against common CMS container images, and Wiz’s report that frontier AI models lowered the cost of building exploits all shorten the path from disclosure to attack. The attack follows the established pattern for internet-facing remote code execution: scanning first, though version fingerprinting is unreliable here, then initial access through one of two paths. CVE-2026-109618 uses a single oversized request to corrupt memory while PHP is still setting the request up. CVE-2026-109619 reuses memory left behind by an earlier request on the same worker. No public source yet documents the automated phase, the hand-off to human operators, or post-exploitation activity for PHP2Shell specifically. The established pattern for comparable flaws is a first shell, a reverse shell back to attacker infrastructure, a webshell for persistent access, tool downloads, privilege escalation and persistence. These are the stages defenders should prepare for, not observed PHP2Shell behavior.

Exposure requires an unpatched PHP branch serving web requests. The demonstrated application-independent path is mod_php. CVE-2026-109619 additionally needs session.upload_progress.enabled left at its default of on, and attacker requests landing on the same worker, while its fatal-error-backtrace path applies to PHP 8.5 only. Several things limit how many attempts succeed: CVE-2026-109618 also requires defeating ASLR (address space layout randomization, which places code at unpredictable memory addresses), the same-worker requirement constrains CVE-2026-109619, and public PoCs are unreliable. Other factors widen the blast radius: no authentication, no application flaw needed on mod_php, and a default-on setting in the CVE-2026-109619 path. Wiz reports versions back to PHP 5.4 are affected, and branches 7.4, 8.0 and 8.1 have no official fix. The version string is unreliable in both directions: distribution backports fix the bug without changing the version, so scanners flag patched hosts, while “latest available” on an end-of-life branch still means vulnerable. Exploitation attempts are reported by a named third party and are expected; successful exploitation at scale is not established.

Hunting guidance from other vendors, including Datadog, points defenders at crash evidence: memory exhaustion errors at initialization and Apache segmentation faults. A successful exploit can return HTTP 200 and leave the worker running. Crash logs measure attempts, not compromises.

If you have confirmed exposure, skip ahead to What To Do.

How It Works

CVE-2026-109618 (out-of-memory corruption). An out-of-memory condition (PHP running out of its allowed memory) interrupts PHP while request data is only partly initialized, and the cleanup routine then treats the half-built data as valid. Datadog describes the trigger as an unauthenticated POST request with a single very long form field name, about 3.5 MB in the lab. When the attempt crashes or fails, PHP logs a memory exhaustion error reported as “Unknown on line 0”.

wp2-advisory-image2

CVE-2026-109619 (stale global state). Request-owned state survives after its memory is freed, and a later request handled by the same worker reuses it. This is a use-after-free: the program keeps using a pointer to memory it has already released, which an attacker can refill with data they control. The path requires session.upload_progress.enabled, the setting that tracks file upload progress in the user’s session and is on by default. The fatal-error-backtrace path applies to PHP 8.5 only.

wp2-advisory-image3

On Apache, a crashed worker appears in the error log as AH00052, the message Apache writes when a child process exits on a signal such as a segmentation fault. A successful exploit can avoid both this entry and the memory exhaustion error.

What To Do

The steps below expand on the immediate actions summarized in the TL;DR.

1. Identify Exposure

Read the PHP version and the Server API line from a phpinfo page served by the web server: a one-line file containing <?php phpinfo(); placed temporarily in the web root, which prints the running build’s configuration. Delete it immediately afterward, because it exposes that configuration to anyone who requests it. Do not rely on php -v, which reports the command-line binary and not necessarily the build the web server runs. On Apache, apachectl -M | grep -i php lists a loaded PHP module if mod_php is in use; systemctl list-units | grep php shows running php-fpm services. For distribution packages, search the package changelog for the CVE IDs, because a backported fix may not change the version number: on RHEL-family systems, rpm -q --changelog php-common | grep -E 'CVE-2026-10961[89]'; on Debian or Ubuntu, apt changelog php8.x-common | grep -E 'CVE-2026-10961[89]', substituting your branch for 8.x. For containers, check base image tags, especially WordPress, Drupal and Joomla images.

 SAPI  Exploitability
 mod_php  Application-independent RCE demonstrated
 PHP-FPM  Susceptible; see the open PHP-FPM note in How it Works
 php-cgi, FrankenPHP, LiteSpeed  In scope per PHP; no public exploitability analysis

2. Patch or Mitigate

Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. Branches 7.4, 8.0, 8.1 and older have no official fix; moving to a supported branch is the only reliable answer, and unofficial backports are unvetted. PHP states: “there are no complete mitigations; updating is the only safe choice.” Where patching must wait:

 Mitigation (all partial)  Addresses
 session.upload_progress.enabled=0; on PHP 8.5 also fatal_error_backtraces=0  CVE-2026-109619
 pm.max_requests=1 on PHP-FPM (each worker exits after one request, breaking the same-worker requirement; costs a process start per request)  CVE-2026-109619 on FPM
 memory_limit=-1 combined with request-size limits at the web server or proxy and container memory limits; do not use the operating system’s per-process limits (RLIMIT_AS, RLIMIT_DATA) for this  CVE-2026-109618
 WAF or reverse-proxy blocking  Both, partial

Restart all PHP workers after any configuration change; running workers keep the old settings.

3. Assess for Prior Compromise

A clean error log does not clear a host. Look for:

  • Very large requests in proxy or WAF logs, consistent with a multi-megabyte form field name. Request bodies are often not logged, so look at request size. This applies to CVE-2026-109618 only; no log signature has been published for CVE-2026-109619.
  • “Unknown on line 0” memory exhaustion errors and AH00052 entries (failed or crashed attempts).
  • Shell processes whose parent is a web worker (apache2, httpd, php-fpm, php-cgi).
  • New script files in upload, cache and tmp directories.

Start the lookback at 2026-10-17, the earliest attempts reported by Datadog. If you find a compromise, rotate the secrets the PHP process could read: application database credentials, API keys in environment variables or configuration files, and cloud credentials present on the host.

4. Monitor Ongoing

Watch this advisory, the PHP advisory and CISA’s Known Exploited Vulnerabilities (KEV) catalog for updates. Keep alerting on child processes of web workers, and keep software inventory current in GravityZone so hunting can be scoped to hosts running PHP.

Indicators of Compromise

Bitdefender telemetry shows no PHP2Shell exploitation attempts as of publication and we have no indicators of compromise to share.

GravityZone Coverage

The PHP2Shell exploit is memory corruption inside the PHP worker, so GravityZone detection focuses on what the attacker does with the access it gives: starting a shell, opening a reverse shell, planting a webshell, downloading tools, escalating privileges and persisting. These actions are where the attack becomes visible, and where the detections below fire.

Bitdefender MDR provides 24/7 threat monitoring and active response, and the MDR team is actively hunting for PHP2Shell together with Bitdefender Labs. MDR uses software inventory to scope hunts to systems running PHP, so keeping inventory current in GravityZone helps.

External Attack Surface Management (EASM) applies because the vulnerable PHP service is internet-facing: it identifies exposed assets from outside the perimeter without an agent, unlike Risk Management, which scans managed endpoints. EASM detects the PHP version on exposed assets, so it can show which of your internet-facing services run an affected version.

wp2-advisory-image4

 GravityZone Risk Management detects the PHP version installed on managed endpoints and compares it with data from the National Vulnerability Database (NVD) and the security advisories of specific Linux distributions (Ubuntu, CentOS and Red Hat). It flags vulnerable versions and the CVEs that apply to them.

The rules below come from Endpoint Detection and Response (EDR), Advanced Threat Control (ATC), and Proactive Hardening and Attack Surface Reduction (PHASR). Rules marked blocking stop the post-exploitation action, not the exploit.

Linux

Three detections work; however, PHP is deployed (Apache module, PHP-FPM or php-cgi):

  • First shell: Anomaly.Process.NewProcessStartedShell
  • Reverse shell: EDR.PhpReverseShell, ATC.BashReverseShell.X (blocking)

The rest of the Linux detections are tied to the web worker process and fire for Apache mod_php and php-cgi, not when the parent process is PHP-FPM:

  • First shell: EDR.WebServiceSpawnShell
  • Reverse shell: EDR.WebReverseShell (incident), the generic reverse-shell rule family
  • Hands-on activity: EDR.SuspiciousWebServerBehaviour and .2, EDR.Generic.Nexus.WebServer
  • Webshell: EDR.WebServiceWriteScript

Windows

On Windows, PHP typically runs as php-cgi.exe, and alerts such as SuspiciousExecution.PotentialPHPWebshell already monitor php-cgi and other web server configurations. ATC has heuristics that detect command shells started by php-cgi.exe when post-exploitation actions follow through those shells, such as enumeration, credential dumping or adding a new user to the machine. Because both flaws require heap manipulation (the attacker shaping how PHP lays out memory), Process Introspection also detects suspicious process creation from memory pages that do not belong to a loaded module. Process Introspection checks the state of a process during key operations such as creating a child process, which is where an exploited PHP worker would start a shell.

  • Hands-on recon: SuspiciousExecution.PotentialPHPWebshell (104852)
  • Webshell: SuspiciousServerRootFile (100942), WebShellCreation (102198)
  • Reverse shell: PossibleReverseShellSocketPipeChild and Parent (103945, 103946), PythonReverseShell (102194), the NetCat rules, Empire.Stager.WAR (105626)
  • Tool download: CertutilDownload, PotentialIngressToolTransferViaCURL
  • Persistence: NewScheduledTask, PowershellScheduledTaskCreated
  • PHASR (blocking): whoami, certutil, curl and PowerShell downloads, account creation, local admin group changes, schtasks

macOS (PHP under Apache httpd or php-fpm)

  • First shell: EDR.WebService.ShellSpawned
  • Reverse shell: EDR.Metasploit.PhpMeterpreter, EDR.Metasploit.ReversePhpSsl.N and Payload.ReversePhpSSL.Y, ATC.Metasploit.Payload.ReversePhpSSL.X (blocks on execution), the reverse-shell rule family, PHASR Bash reverse shell and Netcat (blocking)
  • Tool download: Anomaly.Process.DownloaderNewArguments, PHASR Curl (blocking)
  • Hands-on activity: Anomaly.Process.NewSubprocessesStarted, EDR.HiddenFileExecution
  • Persistence: EDR.SuspiciousCrontabModification, PHASR.Crontab.InstallOtherUser (blocking)

Want to keep up with threats like this one? Subscribe to our Ctrl-Alt-DECODE newsletter