Article Banner

php2shell: Hunting Critical PHP Remote Code Execution

php2shell is a pair of newly disclosed weaknesses in PHP, the software that runs a large share of the world's websites. Security teams began tracking it on October 21, 2026, after fixes were released and early attacks were already underway. The weaknesses let an attacker take control of a web server without a password and without tricking any employee first.

Think of it like a hotel where any guest can slip a note under the front desk and walk away holding the master key. The attacker sends an ordinary-looking web request, and the server mistakenly hands back pieces of its own memory and then runs whatever commands the attacker chooses. Because the weakness sits in the website engine itself, even well-built and fully updated applications are exposed.

A single successful request can expose the passwords, login sessions, and secret keys of other visitors, then give the attacker a foothold to install hidden back doors. For businesses, that leads to stolen customer data, hijacked online stores, fraud, and costly cleanup. With more than a million internet-facing servers at risk and working attack code already circulating, organizations that run their own websites should treat this as an urgent priority and confirm their systems are patched.

Hunting Controls & Observations

php2shell chains two PHP core flaws, CVE-2026-109618 and CVE-2026-109619, into a single unauthenticated attack that both leaks server memory and runs attacker-chosen code. PHP rates both flaws CVSS v4.0 9.2. The exploit triggers through a file-upload-style web request and depends on the worker running out of memory, so freed memory is handed back to the client or reused by a later request on the same worker. Every web-facing PHP deployment is in scope, and PHP identifies the classic Apache module configuration as the highest risk because the attack runs before any application code. No static indicators of compromise have been published, so the durable detection strategy is behavioral. The following telemetry carries the strongest signal:

  • Endpoint Controls: Process-creation and file-write telemetry on web servers, from Microsoft Defender for Endpoint, Sysmon, or auditd mapped to the Splunk Common Information Model, covering both Linux and Windows hosts.
  • Network Controls: Web access logs and proxy or firewall egress records, for upload-style requests to pages that never accept uploads and for outbound connections that originate from the web tier.
  • Application & Host Controls: PHP and web-server error logs for out-of-memory fatal errors and rapid worker restarts, and server responses for abnormally large or malformed session cookies.

Behavioral Indicators of Attack

Analysts should hunt for the following behaviors across web-serving infrastructure:

  • Web requests that carry file-upload-style form data sent to pages that do not normally accept uploads, especially from unauthenticated sources.
  • Abnormally large or malformed session cookies returned in server responses, a sign the server leaks its own memory back to the client.
  • Bursts of out-of-memory errors and rapid restarts of PHP worker processes, the condition the exploit depends on.
  • Web-server or PHP worker processes launching a command shell or scripting interpreter, which legitimate web traffic never triggers.
  • New or modified script files appearing in website folders shortly after suspicious requests, consistent with a planted back door.
  • Web-server processes reaching out to the internet to download additional tools or payloads.

MITRE Enterprise ATT&CK Tactics and Techniques

php2shell activity maps across the kill chain as follows:

  • Initial Access (T1190): The attacker exploits the public-facing PHP application through a crafted upload-style request, requiring no credentials.
  • Execution (T1059.004): Successful exploitation runs commands through a Unix shell spawned by the web-server or PHP worker process.
  • Credential Access (T1212): The memory-disclosure flaw returns leaked worker memory to the client, exposing passwords, session tokens, API keys, and private keys from other requests.
  • Persistence (T1505.003): The attacker writes a web shell into a web-accessible directory to retain access after the initial request.
  • Command and Control (T1105): The foothold pulls second-stage tooling onto the host using built-in transfer utilities.

Controls' Observables

Endpoint Controls

  • Process lineage where a web-server or PHP worker process is the parent of a command shell or interpreter (T1059.004).
  • Creation or modification of PHP script files inside web roots and upload directories (T1505.003).
  • Transfer utilities such as curl, wget, or netcat launched by the web-server stack (T1105).

Network Controls

  • Upload-style requests delivered to endpoints that do not implement file upload, especially unauthenticated (T1190).
  • Outbound connections initiated by web-server processes to new or rarely seen destinations (T1105).

Application & Host Controls

  • Spikes in out-of-memory fatal errors and rapid PHP worker respawns in server logs, the precondition for exploitation.
  • Oversized or malformed session cookies in server responses, indicating memory disclosure to the client (T1212).

Insights and Recommendation

Organizations compromised through php2shell face immediate and compounding damage. The memory-disclosure flaw exposes the secrets of other users on the same server, including session tokens that allow account takeover, API keys that unlock connected services, and private keys that undermine encrypted traffic. The code-execution flaw turns that exposure into full server control, which attackers use to plant web shells, steal customer and payment data, hijack online storefronts, and stage follow-on intrusions. Because exploitation happens before application code runs, secure and fully patched applications provide no protection on their own.

Security teams should patch PHP to a fixed release (8.5.12, 8.4.27, 8.3.36, or 8.2.35) or apply a vendor backport as the priority action. Where patching cannot happen immediately, apply the PHP project's interim settings and then restart all workers: set memory_limit so applications cannot override it, disable session.upload_progress, and on PHP 8.5 set fatal_error_backtraces to off. These settings reduce exposure but do not replace the fix. Inventory every PHP runtime, including copies bundled inside appliances, management interfaces, and container images, since those often lag behind. Isolate internet-facing applications from internal networks until they are patched and verified. Treat any secret that lived in server memory, session tokens, API keys, and TLS private keys, as potentially exposed and rotate it. Then hunt the environment with the behavioral queries below, because a server can be exploited and backdoored before a patch is applied.

Source and Credits

This guide is based primarily on the Netherlands National Cyber Security Centre (NCSC-NL) operational-information repository "php2shell vulnerabilities (CVE-2026-109618, CVE-2026-109619)", published October 21, 2026, along with the associated PHP security advisory and CERT-EU advisory 2026-018.

Technical detail on the exploit chain and affected applications was corroborated against Sansec's php2shell research, the Tenable php2shell FAQ, and SecurityWeek's exploitation reporting. These corroborating sources sit outside the Focused Hunts approved-vendor list and are cited here for technical confirmation. Discovery of the flaws and the php2shell tool is credited by Sansec to researcher Calif (Ryan Austin), with additional analysis from Wiz Research. Early exploitation was reported by Cloudflare and watchTowr.

Threat Hunting IOCs & Queries

Known Indicators of Compromise

No static indicators of compromise, such as file hashes, domains, or IP addresses, have been published for php2shell as of October 21, 2026. Exploitation leaves behavioral traces rather than fixed artifacts, so the hunting anchors below are more durable than indicator matching:

  • Web-server process names: php-fpm, php, php-cgi, httpd, apache2, nginx, litespeed, frankenphp
  • Web shell file patterns: newly written .php, .phtml, .phar, or .inc files under web roots such as /var/www/, /public_html/, or /usr/share/nginx/
  • Second-stage tooling: transfer utilities such as curl, wget, nc, or tftp launched by the web tier

Web Server or PHP Worker Spawning a Command Shell

Priority: Medium. Observed outcome of in-the-wild exploitation; Tier 1 endpoint telemetry; rarely benign on a web host.
Behavior Targeted: A web-server or PHP worker process launching a shell or scripting interpreter, the clearest signal that remote code execution has succeeded.
MITRE ATT&CK: T1190 (Exploit Public-Facing Application), T1059.004 (Command and Scripting Interpreter: Unix Shell)
Expected Results: A web-server parent process (such as php-fpm or apache2) spawning sh, bash, or a language interpreter, typically with no interactive user attached.
False Positive Likelihood: MEDIUM
Telemetry Required: Process-creation events from Defender for Endpoint, Sysmon (Linux or Windows), or auditd mapped to the Splunk CIM Endpoint data model.
Tuning Guidance: Some applications legitimately shell out to helpers (image processing, mail, cron wrappers); baseline those parent-child pairs per host and allowlist them, then re-aggregate by command line to isolate unexpected spawns. Narrow the interpreter list to match the host's stack.
Detection Difficulty: MODERATE, because a small number of applications shell out during normal operation.

Splunk SPL Query

| tstats summariesonly=false count min(_time) AS first_seen max(_time) AS last_seen
    from datamodel=Endpoint.Processes
    where earliest=-7d
        Processes.parent_process_name IN ("php-fpm","php","php-cgi","httpd","apache2","nginx","litespeed","lshttpd","caddy","frankenphp")
        Processes.process_name IN ("sh","bash","dash","zsh","ksh","python","python3","perl","ruby")
    by Processes.dest Processes.user Processes.parent_process_name Processes.process_name Processes.process
| rename Processes.* AS *
| sort - count
| convert ctime(first_seen) ctime(last_seen)

Microsoft KQL Query (Defender/Sentinel)

DeviceProcessEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("php-fpm","php","php-cgi","httpd","apache2","nginx","litespeed","lshttpd","caddy","frankenphp")
| where FileName in~ ("sh","bash","dash","zsh","ksh","python","python3","perl","ruby")
| summarize Count = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp)
    by DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| order by Count desc

Web Shell Written into a Web-Accessible Directory

Priority: High. Persistence-stage impact; durable behavior pattern; Tier 1 endpoint telemetry.
Behavior Targeted: Creation or modification of a PHP script file inside a web root or upload directory, consistent with a planted back door that survives the initial exploit.
MITRE ATT&CK: T1505.003 (Server Software Component: Web Shell)
Expected Results: New or changed .php, .phtml, .phar, or .inc files in web-served paths, written by a web-server or PHP process rather than a deployment pipeline.
False Positive Likelihood: MEDIUM
Telemetry Required: File-creation events from Defender for Endpoint, Sysmon, or auditd mapped to the Splunk CIM Endpoint data model.
Tuning Guidance: Legitimate deployments, plugin or theme updates, and caching engines write PHP files too; exclude known deployment accounts, release windows, and cache directories, then focus on files written directly by web-server processes. Adjust the path list to the host's document roots.
Detection Difficulty: MODERATE, because content management systems write PHP during updates.

Splunk SPL Query

| tstats summariesonly=false count min(_time) AS first_seen max(_time) AS last_seen
    from datamodel=Endpoint.Filesystem
    where earliest=-7d
        (Filesystem.action="created" OR Filesystem.action="modified")
        (Filesystem.file_path="*/var/www/*" OR Filesystem.file_path="*/htdocs/*" OR Filesystem.file_path="*/public_html/*" OR Filesystem.file_path="*/usr/share/nginx/*" OR Filesystem.file_path="*/wp-content/*" OR Filesystem.file_path="*/inetpub/wwwroot/*")
        (Filesystem.file_name="*.php" OR Filesystem.file_name="*.phtml" OR Filesystem.file_name="*.phar" OR Filesystem.file_name="*.inc")
    by Filesystem.dest Filesystem.user Filesystem.file_path Filesystem.file_name Filesystem.action
| rename Filesystem.* AS *
| sort - last_seen
| convert ctime(first_seen) ctime(last_seen)

Microsoft KQL Query (Defender/Sentinel)

DeviceFileEvents
| where Timestamp > ago(7d)
| where ActionType in~ ("FileCreated","FileModified")
| where FolderPath has_any ("/var/www/","/htdocs/","/public_html/","/usr/share/nginx/","/wp-content/","\\inetpub\\wwwroot\\")
| where FileName endswith ".php" or FileName endswith ".phtml" or FileName endswith ".phar" or FileName endswith ".inc"
| where InitiatingProcessFileName in~ ("php-fpm","php","php-cgi","httpd","apache2","nginx","litespeed","lshttpd","caddy","frankenphp")
| project Timestamp, DeviceName, InitiatingProcessAccountName, InitiatingProcessFileName, FolderPath, FileName, ActionType
| order by Timestamp desc

Web Server Stack Downloading Second-Stage Tooling

Priority: High. Command-and-control-stage impact; durable behavior pattern; Tier 1 endpoint telemetry.
Behavior Targeted: A web-server process, or a shell it spawned, launching a file-transfer utility to pull additional tooling or payloads onto the host.
MITRE ATT&CK: T1105 (Ingress Tool Transfer)
Expected Results: curl, wget, netcat, or tftp invoked with a web-server or shell parent on a server that has no reason to fetch files interactively.
False Positive Likelihood: MEDIUM
Telemetry Required: Process-creation events from Defender for Endpoint, Sysmon, or auditd mapped to the Splunk CIM Endpoint data model.
Tuning Guidance: Package managers, update scripts, and health checks also call these utilities; exclude known maintenance accounts and scheduled jobs, and prioritize invocations whose parent is a web-server or interpreter process. Inspect the command line for remote URLs and output redirection to web roots.
Detection Difficulty: MODERATE, because transfer utilities have legitimate automation uses.

Splunk SPL Query

| tstats summariesonly=false count min(_time) AS first_seen max(_time) AS last_seen
    from datamodel=Endpoint.Processes
    where earliest=-7d
        Processes.parent_process_name IN ("php-fpm","php","php-cgi","httpd","apache2","nginx","litespeed","lshttpd","caddy","frankenphp","sh","bash","dash")
        Processes.process_name IN ("curl","wget","nc","ncat","tftp","ftp","socat")
    by Processes.dest Processes.user Processes.parent_process_name Processes.process_name Processes.process
| rename Processes.* AS *
| sort - count
| convert ctime(first_seen) ctime(last_seen)

Microsoft KQL Query (Defender/Sentinel)

DeviceProcessEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("php-fpm","php","php-cgi","httpd","apache2","nginx","litespeed","lshttpd","caddy","frankenphp","sh","bash","dash")
| where FileName in~ ("curl","wget","nc","ncat","tftp","ftp","socat")
| summarize Count = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp)
    by DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| order by Count desc

Note: These queries were generated with AI assistance and are a starting point for threat hunting and detection rule considerations.

Back to Hunting off the Red