PHPanic: Two Critical Flaws Put Web Servers at Risk of Remote Code Execution

Two critical PHP flaws expose web servers to remote code execution. Jordan Newman examines exploitation conditions, forensic limitations, and a Sigma detection rule.

Jordan Newman

Author

Oct 21, 2026

Published

19 min

Read time

Updated 26 October 2026, 14:43 GMT: We’ve revised the exploitation assessment and timeline to reflect new research and corrected reporting. This update expands the investigation guidance, adds campaign-specific indicators, and explains PHP’s additional session upload progress advisory and its implications for mitigation.

PHP is a server-side scripting language that powers a substantial portion of the internet, underpinning everything from small websites to major content management systems such as WordPress. Its widespread adoption makes vulnerabilities in the PHP interpreter particularly concerning, as a single flaw can potentially expose millions of web applications.

On 21 October 2026, the PHP development team released emergency security updates addressing two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, collectively dubbed PHP2Shell. Both can enable unauthenticated remote code execution (RCE). Exploitation does not require the actor to log-in, upload any malicious PHP script, or exploit application-level logic: the flaws are in PHP itself. Actual exploitability depends on the PHP version, server integration, configuration, and reachable execution paths.

In a demonstrated Apache mod_php scenario, a malicious HTTP request can trigger memory corruption before PHP begins executing application code. PHP identifies mod_php as the highest-risk deployment, while also warning that PHP-FPM, php-cgi, FrankenPHP, and LiteSpeed are in scope. This does not mean, however, that an exploit script for one given server configuration will be able to exploit the same vulnerabilities in other servers, the exploit needs porting to account for different configurations.

Active exploitation attempts, working public exploit tooling, and indicators of campaigns targeting php2shell have all now been documented, but it is important to note that success rates remain low and the scope of post-compromise activity is extremely limited.

The complexity of exploiting these memory-corruption vulnerabilities remains a constraint on scaled and automated exploitation. The exploit must be re-configured between targets to account for different memory layouts.

Why These Vulnerabilities Are Especially Dangerous

Strand has been monitoring this case as it unfolds, reviewing details as they become available and assessing the threat.

There are two factors which make these vulnerabilities particularly concerning:

As mentioned at the beginning of this blog, PHP applications are extremely populous across the entire internet, in the form of user-facing web portals as well as back-end processing infrastructure.

A Censys query run on 21 October 2026 provides a historical snapshot of visible PHP deployments:

Censys results captured on 21 October 2026. Header matches do not establish exploitability.

Censys returned 10,093,696 web properties exposing the X-Powered-By header with a value matching PHP 7.X. This is a count of matching web properties, not a verified count of vulnerable servers.

This query does not measure the full PHP footprint, for two reasons:

  • The X-Powered-By header can be entirely disabled or reconfigured, meaning there are many more webservers running PHP which are not included in this result set.

  • The query searches only for PHP version 7 and therefore excludes other PHP versions, including affected releases of PHP 8.

These are not Application-Level Vulnerabilities

The vulnerabilities exist within PHP itself - exploitation may take place during the processing of seemingly ordinary HTTP requests, particularly those containing multipart form data. Application security measures designed to prevent SQL injection, command injection, or malicious file uploads will not necessarily prevent exploitation.

This creates concern for defenders, since they may not be able to rely on tooling that was in place at the time of an attack.

Additionally, CVE-2026-109619 introduces a cross-request element, where the request responsible for creating the vulnerable memory state may be different from the request that ultimately triggers exploitation. This complicates forensic reconstruction, as investigators cannot necessarily identify the entire attack by examining a single suspicious HTTP transaction.

Successful exploitation achieving RCE will provide an attacker with code execution capability within the security context of the affected PHP or web-server worker. From there, they may access application secrets, database credentials, and sensitive files, or deploy additional malware, depending on the privileges and configuration of the compromised service.

Although this creates such problems for defenders and incident responders, it also hinders the efforts of threat actors looking to exploit these vulnerabilities at scale. Public tooling is now available for threat actors to make use of, which will allow them to attempt exploitation at scale, but it does not completely remove the barrier for them, and it leaves behind recognisable IoCs unless modified (more detail on IoCs later in this blog post). For this reason, it is paramount for anyone still using vulnerable installations of PHP to apply the recent patch, and conduct a forensic investigation to ensure they have not already been compromised.

Analysis of the Vulnerabilities

CVE-2026-109618: Unsafe recovery from OOM conditions

The first vulnerability concerns PHP's handling of Out-Of-Memory (OOM) conditions.

Like other programming languages, PHP imposes configurable limits on the amount of memory a script can consume. When a request exceeds its permitted allocation, PHP normally interrupts execution rather than allowing the process to continue allocating memory indefinitely.

Internally, however, PHP has historically handled certain memory allocation failures using a C library mechanism called longjmp().

Unlike a conventional function return, longjmp() transfers execution back to an earlier point in the program, bypassing the normal sequence of function returns. This becomes dangerous when PHP encounters an allocation failure while internal data structures are only partially initialised.

Under these conditions, PHP can abandon an operation without completing the initialisation or cleanup necessary to leave its internal memory in a consistent state.

When request shutdown subsequently runs, PHP may attempt to interpret this invalid memory as legitimate internal data. Attackers able to influence the layout and contents of the process memory can potentially turn this corruption into arbitrary code execution.

How attackers can trigger the vulnerability

Attackers may deliberately exhaust PHP's memory using malicious HTTP requests. Of particular concern here is the handling of requests containing multipart/form-data, normally used when submitting forms and uploading files.

PHP automatically parses this data, and several characteristics of its multipart parser can cause significantly more memory to be allocated than the size of the original HTTP request might suggest.

For example:

  • Requests without a usable declared content length can bypass the initial post_max_size check while continuing to supply request-body data

  • Multipart sections can contain large numbers of headers, whose internal representation consumes substantially more memory than their original encoded form

  • Empty file-upload controls can escape the normal max_file_uploads counter while still causing PHP to allocate metadata arrays

  • Deeply nested form-field names can multiply the memory and processing required to construct PHP's internal arrays

In Apache deployments using mod_php, the situation is particularly serious. PHP's request shutdown procedure runs even when request initialisation fails, allowing the interpreter to encounter corrupted internal state created during the failed startup process.

This makes CVE-2026-109618 exploitable independently of application-level functionality in the demonstrated Apache scenario.

PHP-FPM behaves differently, terminating its worker when request startup fails. Although this prevents the same startup-stage exploit sequence, the advisory does identify other potential paths to exploitation involving memory exhaustion after initialisation has completed - though the advisory itself does not confirm any successful exploit attempt for this CVE against PHP-FPM.

CVE-2026-109619: UAF caused by stale internal state surviving between requests

The second vulnerability, CVE-2026-109619, is a Use-After-Free (UAF) issue involving PHP's internal global state.

Web servers commonly reuse the same PHP worker process to handle multiple HTTP requests. Although memory belonging to an individual request is released when that request finishes, certain internal variables and references remain associated with the longer-lived worker.

PHP must therefore ensure that references to request-specific memory are cleared before that memory is released.

This vulnerability arises when this cleanup does not occur correctly.

An operation can leave a reference to request-owned memory in a global variable, even after the request ends and its memory is freed. When a subsequent request reaches an operation that accesses this reference, PHP may treat the already-freed memory as though it still contains valid data.

How an attacker exploits stale state

The advisory describes exploitation as involving two distinct operations: a producer and a consumer.

The producer is an operation that leaves request-specific state accessible after its memory has been released. This can occur when an unexpected fatal error interrupts an operation before its cleanup finishes, or when a warning or other diagnostic repopulates a state that has already been cleared.

The consumer is an operation in a later request that accesses the stale reference before PHP has completed its normal request initialisation.

An attack therefore follows a general sequence:

  1. An attacker triggers a PHP operation that stores request-owned information in internal global state

  2. A fatal error, memory exhaustion, or another abnormal execution path prevents the state from being cleared correctly

  3. The request ends, and PHP frees its associated memory while the worker retains a dangling reference

  4. The attacker sends another request that reaches the same PHP worker

  5. An early initialisation or session-handling operation accesses the stale reference, potentially enabling controlled memory corruption and RCE

Successful exploitation requires the attacker to influence the relevant memory layout and ensure the producing and consuming operations occur within the same persistent worker process.

Session upload progress creates an exploitation opportunity

One particularly important attack surface identified here is PHP's session upload progress functionality.

This feature allows PHP to track file uploads and report progress through session information. Some of its internal operations occur during request-body processing, before normal module and request initialisation has completed. This creates an opportunity for an attacker to trigger session-related operations while stale information from a previous request remains accessible.

The advisory confirms that session upload progress can function as both a producer and consumer of a vulnerable state.

Notably, the feature is enabled by default, and exploitation does not necessarily require the application to explicitly call session_start().

For PHP-FPM, there is a valid path to exploitation involving state produced during application execution, followed by a fatal error and a subsequent request that consumes the stale state through session upload progress.

An additional attack surface in PHP 8.5

An exploitation case involving PHP 8.5's fatal_error_backtraces feature is also mentioned in the advisory. When enabled, this functionality can preserve information about a fatal error in request-owned memory without properly clearing the corresponding global reference during shutdown.

A subsequent request that generates an early configuration diagnostic can access that stale reference before normal initialisation resets it. This has been identified by the PHP maintainers as the basis for confirmed RCE exploitation against Apache mod_php.

The diagnostic does not need to appear in an error log or be displayed to the client. Simply suppressing PHP warnings or disabling their output does not eliminate the vulnerability. These producer/consumer paths and their configuration dependencies are documented in the PHP stale-global-state advisory.

Detection and DFIR: What Should Defenders Look For?

Detecting exploitation of these vulnerabilities presents a challenge because the initial attack can occur entirely within PHP's internal request-processing machinery.

Rather than relying on obvious malicious parameters or suspicious PHP scripts, defenders should look for combinations of unusual HTTP activity, session-store changes, PHP execution failures, and unexpected behaviour originating from web-server processes. A sigma rule which helps to identify common processes spawned by attackers after successful exploitation is included in Appendix 1. Additionally, Appendix 2 contains published campaign indicators which have emerged since the disclosures.

Be aware that these indicators are not guaranteed to be present. Standard web-server access logs rarely capture the multipart structures needed to identify malicious requests, while some vulnerable execution paths may generate no visible PHP errors. Successful exploitation could also occur entirely within the PHP worker process, without spawning a shell or writing a malicious file to disk. Retrospective hunting should begin from at least 17 October 2026 as this is the earliest attempt reported by AWS.

Strand’s autonomous investigation system is designed to help organisations and DFIR firms responding to related incidents. Strand works in a reactive manner, without relying on tooling that was in place at the time of the compromise, and can identify attacker activity without relying on known Indicators of Compromise. Contact us at support@strandintelligence.com for more information. This blog will be updated as we develop a deeper understanding of how defenders can investigate and respond to incidents originating from these vulnerabilities.

A Reflection on the AI Threat Actor Landscape

Some reporting and speculation framed these disclosures as a doomsday event for a significant portion of the internet built on PHP. These are critical vulnerabilities, but the practical risk depends on the PHP build, configuration, and application paths available to an attacker.

The disclosures also offer a useful insight into the capabilities and constraints of AI-driven threat actors.

Threat actors who have adopted AI into their workflows can automate exploitation of straightforward vulnerabilities, especially where a reliable public proof of concept is available, and begin scanning for vulnerable targets rapidly after disclosure. It is common to observe this methodology being used by financially motivated threat actors who prioritise operational efficiency.

What these disclosures highlight is the constraints of this workflow. The vulnerabilities discussed in this article are memory-corruption vulnerabilities. Weaponising these can be much more difficult, requiring comprehensive knowledge of the internals of the target platform in order to exploit, with the success rate varying considerably between target instances using different configurations, and some being completely unexploitable.

As we originally assessed, due to the complexity and lack of portability between targets, this is not being widely exploited at-scale under the same kind of methodology. Instead, shared exploit tooling is contributing more towards wide-spread php2shell attempts, with contributors building support for an increasingly wider variety of server configurations as they conduct more research. At present, only the more adept operators are having reasonable success with this, utilising it for their higher priority targets which warrant the cost of targeted exploit development. That is not a reason to delay patching, and it does not rule out targeted attacks or increasing automation as exploit techniques develop.

What Have We Observed So Far?

We have been following the threat posed by 'php2shell' since the initial leaks. Here is a summary covering the observed events in the order they unfolded:

  • Pre-disclosure attempts: Amazon Threat Intelligence reported observed attempts against its MadPot network on 17 October, this is before details of the vulnerabilities were leaked onto public forums and social media on the 20th October 2026. Amazon did not state whether the attempts were successful.

  • Pre-disclosure scanning: Following the leaks, F5 Labs reported scanning activity identifying vulnerable servers from 08:36 UTC on 21 October.

  • Co-ordinated disclosure: Calif co-ordinated the release of their research with the release of PHP’s advisory and patch, both going public at 14:00 UTC on 21 October.

  • Public PoCs appear on GitHub: We analysed public tooling which began appearing on GitHub around the time of the disclosures. We did not find them to be reliable in our lab environment.

  • Operational exploit development: SOCRadar recovered a lab-tested chain and target-screening scripts from an exposed attacker server. Around 20 public sites were screened, but they stated in their post that "as of October 22, 2026, we have seen no evidence of shell access on any screened site".

  • Attempted malware deployment: Sophos initially reported successful exploitation on 22 October, but then withdrew that assessment at 21:21 UTC the same day. Its revised finding was scanning and failed attempts and states that the Potassium/Mirai payload was blocked. Associated malware and traffic indicators remain useful hunting leads and are included in Appendix 2.

  • Following successful attempts: Although initial public PoCs did not function reliably out-of-the-box, successful compromises have been observed in the days following. Success rates remain hard to quantify, but we should be prepared for them to increase as more groups successfully weaponise this.

As of the current landscape surrounding this, active attempts and usable tooling are established, and successful compromise is confirmed, yet our initial assessment remains to be true: automating the end-to-end workflow for this exploit remains a constraint. The exploit is not easily portable since calculating offsets and configuring heap grooming payloads must be done against a representative server configuration for each target.

Patching and the Additional Session Upload Progress Advisory

For the original two CVEs, the fixed upstream releases are PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12, or subsequent releases containing those fixes. Vendor packages may carry backported fixes under older version numbers; verify the vendor advisory and the runtime serving web requests, rather than relying only on an HTTP header or the CLI binary. Restart the relevant PHP/web-server workers after deployment. PHP 8.1 and older are outside upstream support; seek a verified vendor fix or migrate. PHP release guidance.

On 23 October, PHP separately announced CVE-2026-115560. This concerns an unusual application configuration: the session serializer is configured as php_binary or php_serialize, then changed at runtime to php before session_start(), while session upload progress remains enabled. The 21 October releases address the original pair; this additional issue is scheduled for the next regular bugfix release.

PHP recommends session.upload_progress.enabled=0 pending that release. Apply it before request parsing through php.ini, an FPM pool, or server configuration, and restart workers; do not rely on application-level ini_set() or FPM.user.ini. This also blocks the confirmed session paths for CVE-2026-109619, but does not fix CVE-2026-109618 or every stale-state variant. Server owners and maintainers should review any application dependency on session-based upload progress.

Patching and retrospective investigation should proceed together: a fixed runtime does not show whether an attacker previously gained access.

Reference Material

  1. PHP Security Advisory — 21 October 2026

  2. CVE-2026-109618 — RCE via OOM Corruption

  3. CVE-2026-109619 — RCE via Stale Global State

  4. PHP Official Downloads and Security Releases

  5. PHP Session Upload Progress Advisory — 23 October 2026

  6. Amazon Threat Intelligence: Pre-disclosure Attempts

  7. Sophos: Research, Corrections, and Indicators

  8. MyCERT: Exploit Tooling and Follow-up Advisory — 24 October 2026

  9. Community PHP2Shell Compromise Checker

  10. VulnCheck: PHP2Shell Observations and Network Indicators

  11. cowrAI: GODOFTHUNDER Campaign and Malware Infrastructure

  12. SOCRadar: PHP2Shell Exploit Tooling on an Exposed Attacker Server

  13. ELLIO: PHP2Shell Sensor Observations and Payload Analysis

Appendix 1 - Sigma Rule & Behavioural Analysis Advice

A sigma rule is provided to help check for exploitation. This rule can be triggered by false positives: it is not intended to provide a consolidated answer as to whether the instance has been compromised by these attacks, but rather to narrow down your search to suspicious processes which could be evidence of attacker activity. It highlights processes often utilised by attackers once they gain initial RCE.

YAML
title: Suspicious Child Process Spawned by PHP Web Server
id: 39874b3c-c4d9-4f73-a4ab-741819c647e0
status: experimental
description: >
    Detects suspicious command execution utilities spawned by
    PHP and web server processes. Such activity may indicate
    successful exploitation of a remote code execution (RCE)
    vulnerability, including CVE-2026-109618 and CVE-2026-109619.
references:
    - https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w
    - https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
author: Jordan Newman [jnewman@strandintelligence.com]
date: 2026-10-21
tags:
    - attack.execution
    - attack.t1059
    - attack.t1059.004
logsource:
    category: process_creation
    product: linux
detection:
    selection_parent:
        ParentImage|endswith:
            - '/php-fpm'
            - '/php-fpm8.2'
            - '/php-fpm8.3'
            - '/php-fpm8.4'
            - '/php-fpm8.5'
            - '/apache2'
            - '/httpd'
    selection_child:
        Image|endswith:
            - '/sh'
            - '/bash'
            - '/dash'
            - '/zsh'
            - '/curl'
            - '/wget'
            - '/python'
            - '/python3'
            - '/perl'
    condition: all of selection_*
falsepositives:
    - Legitimate PHP applications that execute shell commands or external utilities.
    - Administrative scripts invoked through PHP or web server processes.
level: high

At a high-level, these are the areas which defenders should prioritise, especially if running a threat hunt, using the sigma rule or otherwise, turns up artefacts matching any of these categories:

  • Errors and requests: correlate repeated multipart POSTs, 5xx responses, worker exits, allocator/heap-corruption messages, and memory exhaustion. in Unknown on line 0 indicates missing script/line context - potentially hinting at a crash caused by memory corruption.

  • Session stores: examine unexpected PHP code, serialized objects in upload-progress entries, and unusual session identifiers in context.

  • Files and configuration: inspect web shells, unexpected executable content in uploads, obfuscated code appearing where it shouldn't, and changes to.htaccess,.user.ini, or auto_prepend_file. Modification times alone can miss altered files.

  • Live state: investigate unexpected web-user processes, shell/download children, suspicious outbound connections, executables in temporary directories, deleted executables, and memfd payloads.

  • Persistence and integrity: review scheduled jobs, service definitions, SSH access, and unexpected package-file changes. Bear in mind that attacks using this exploit are heavily targeted.

Benign applications can produce individual matches. Missing logs, cleaned artefacts, and execution entirely within a worker can also leave these checks without a finding.

Enumerate these artefacts alongside the campaign indicators and any deployment-specific analysis.

Appendix 2 - Campaign Indicators

The following indicators are available for campaigns which have been observed attempting to exploit php2shell.

Indicator

Source

Context

Date observed

103.216.220.92

AWS

Malicious IP

17 October

31.223.184.166

AWS

Malicious IP

21 October

37.19.200.5

AWS

Malicious IP

21 October

134.209.159.64

AWS

Malicious IP

21 October

103.114.163.188

AWS

Malicious IP

21 October

95.217.98.37

AWS

Malicious IP

21 October

45[.]198[.]224[.]169

Sophos

Exploit-attempt source

N/A

92[.]118[.]112[.]100/nfs

Sophos

Payload-host address/path

N/A

134[.]199[.]154[.]64

Sophos

Potassium C2 server

N/A

117[.]55[.]202[.]115

Sophos

Potassium C2 server

N/A

thunder[.]godofthunder[.]st

Sophos

Domain contacted during malware sandbox analysis

N/A

0c5486f06620e26e316f4b33f318b0d646d5e1133789331aa2fed012360d1486

Sophos

Malware SHA-256

N/A

/tmp/nfs, ./nfs php

Sophos

Payload path and command

N/A

php2shell-scan/109618

Sophos

User-Agent

N/A

B7kQpoc618

Sophos

Observed Multipart boundary

N/A

85[.]11[.]167[.]243

VulnCheck

Exploit probes

21 October 2026

109[.]71[.]252[.]97

VulnCheck

Probes and reconnaissance

21 October 2026

221[.]14[.]159[.]134

VulnCheck

Malicious IP

21 October 2026

91[.]90[.]123[.]25

VulnCheck

Malicious IP

21 October 2026

206[.]188[.]197[.]105.
working directory on port 9999.
proxy pool on 8899.
listener on 8888

SOCRadar

Exploit-development/staging server

Published 22 October 2026

176[.]65[.]132[.]128

ELLIO

Malicious IP

21 October 2026

146[.]70[.]202[.]189

ELLIO

Uploaded a Linux DDoS bot and an ASP.NET web shell to a sensor

22 October 2026

hackattackkaboom[.]botlesscucks[.]st

cowrAI

Backup C2 domain recovered from malware configuration

22 October 2026

hik[.]gettingheadfromduckysmom[.]st

cowrAI

Backup C2 domain recovered from malware configuration

22 October 2026

AWS addresses belong to shared anonymisation infrastructure. Treat matches as investigation leads and correlate them with request and host evidence; an address match alone does not establish compromise.

Sophos have stated that the observed exploitation attempt failed and the payload was blocked. The leads are associated with the specific observed malware campaign abusing this exploit, not universal php2shell signatures.

Written by

Jordan Newman

The Strand team specialises in digital forensics, incident response, and cybersecurity threat analysis.