Back to Intelligence

CVE-2026-109618: PHP2Shell Unauthenticated RCE Actively Exploited — Detection, Hunting, and Remediation Guide

SA
Security Arsenal Team
October 28, 2026
12 min read

On Monday, the U.S. Cybersecurity and Infrastructure Security Agency (CISA) added two recently patched PHP vulnerabilities — collectively referred to as PHP2Shell — to its Known Exploited Vulnerabilities (KEV) catalog, confirming active, in-the-wild exploitation. Both flaws carry a CVSS score of 9.2 (Critical) and enable unauthenticated remote code execution on affected PHP deployments. One of the two flaws is tracked as CVE-2026-109618, described in the initial advisory as an out-of-memory condition that can be leveraged into code execution. The second CVE identifier was not disclosed in the initial reporting.

This is not a theoretical risk. KEV inclusion means adversaries are already weaponizing these flaws against internet-facing targets. If your organization runs PHP — on web servers, CMS platforms, internal tooling, or embedded appliances — you are in scope. Under Binding Operational Directive (BOD) 22-01, federal civilian agencies must remediate KEV-listed vulnerabilities within the mandated window; private sector organizations should treat that same clock as best practice.

What Is at Risk

PHP underpins an enormous share of the internet: WordPress, Drupal, Joomla, Laravel applications, custom line-of-business web apps, and countless vendor appliances with embedded PHP backends. An unauthenticated RCE in this stack is a worst-case scenario for defenders because:

  • No credentials are required. Any attacker who can reach the vulnerable endpoint can execute code.
  • The blast radius is web-tier wide. PHP-FPM and mod_php deployments typically execute with the privileges of the web server user (e.g., www-data, apache, nginx, or IIS APPPOOL identities) — enough to drop webshells, pivot to databases, and harvest application secrets from environment files.
  • Exploitation is already confirmed. KEV listing is reserved for vulnerabilities with reliable evidence of active exploitation, not scanner noise.

Historically, unauthenticated RCEs in the PHP ecosystem are adopted within hours by ransomware affiliates, cryptominers, and initial access brokers. Expect mass scanning and opportunistic exploitation to be underway.

Technical Analysis

Affected Component

The flaws affect PHP itself — the runtime that processes web requests through PHP-FPM, mod_php (Apache), or CGI-based handlers. Because the initial advisory was truncated in public reporting, defenders should assume broad exposure across supported PHP release lines until the PHP Group's official advisory and your distribution's security tracker confirm the exact affected version ranges. Treat all internet-facing PHP deployments as suspect until verified.

Vulnerability Profile

AttributeDetail
CVECVE-2026-109618 (second CVE pending public disclosure)
CVSS9.2 (Critical)
ImpactUnauthenticated remote code execution
Root cause (as reported)Out-of-memory condition leveraged to code execution
Exploitation statusConfirmed active exploitation — CISA KEV listed
Authentication requiredNone

How the Attack Works (Defender's View)

From the observable side, the exploitation chain for a PHP RCE of this class is consistent and highly detectable if you know where to look:

  1. Delivery: The attacker sends crafted HTTP requests to a PHP-handled endpoint. Web server access logs will show the request — often with abnormal payload sizes, encoding, or repeated requests to the same URI from a single source.
  2. Trigger: The vulnerable code path in the PHP runtime mishandles the input. In the case of CVE-2026-109618, the reported out-of-memory condition corrupts the execution state, allowing attacker-controlled data to influence execution.
  3. Execution: Successful exploitation causes the PHP worker process to spawn a child process — the single loudest indicator of compromise. On Linux, that means php-fpm spawning /bin/sh, bash, curl, wget, or python. On Windows, php-cgi.exe or php.exe spawning cmd.exe, powershell.exe, or rundll32.exe.
  4. Post-exploitation: Attackers typically establish persistence immediately — dropping a webshell into the webroot, writing a cron job, or pulling a second-stage payload from attacker infrastructure. Outbound connections from the web server process to non-standard destinations are a strong follow-on signal.

Because authentication is not required, the only mitigation before patching is removing network exposure to the vulnerable endpoint — which for most web applications is not viable. Patching is the remediation. Everything else is detection and containment.

Detection & Response

The detections below target the most reliable observable: the PHP runtime spawning shell interpreters, downloaders, or scripts. This behavior is almost never legitimate in production web workloads, which keeps false positives manageable.

Sigma Rules

YAML
---
title: PHP Worker Process Spawning Shell or Script Interpreter
description: Detects php-fpm, php-cgi, or php processes spawning shells or script interpreters, consistent with exploitation of PHP2Shell unauthenticated RCE flaws (CVE-2026-109618) enabling code execution under the web server context.
references:
  - https://thehackernews.com/2026/10/cisa-confirms-active-exploitation-of.html
  - https://www.cisa.gov/known-exploited-vulnerabilities-catalog
  - https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
status: experimental
date: 2026/10/20
tags:
  - attack.execution
  - attack.t1059
  - attack.t1190
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/php-fpm'
      - '/php-fpm7.4'
      - '/php-fpm8.0'
      - '/php-fpm8.1'
      - '/php-fpm8.2'
      - '/php-fpm8.3'
      - '/php-fpm8.4'
      - '/php'
  selection_child:
    Image|endswith:
      - '/sh'
      - '/bash'
      - '/dash'
      - '/zsh'
      - '/python'
      - '/python3'
      - '/perl'
      - '/curl'
      - '/wget'
      - '/nc'
      - '/ncat'
      - '/base64'
  condition: selection_parent and selection_child
falsepositives:
  - Rare legitimate PHP applications that shell out for media processing or system tasks; baseline per application before deployment
level: critical
---
title: PHP CGI or PHP Executable Spawning Windows Command Shell
description: Detects php.exe or php-cgi.exe spawning cmd.exe, powershell.exe, or other Windows script hosts, consistent with post-exploitation activity following PHP2Shell RCE exploitation on Windows-hosted PHP deployments.
references:
  - https://thehackernews.com/2026/10/cisa-confirms-active-exploitation-of.html
  - https://attack.mitre.org/techniques/T1059.001/
author: Security Arsenal
status: experimental
date: 2026/10/20
tags:
  - attack.execution
  - attack.t1059.001
  - attack.t1190
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\php.exe'
      - '\php-cgi.exe'
      - '\php-win.exe'
  selection_child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\rundll32.exe'
      - '\certutil.exe'
  condition: selection_parent and selection_child
falsepositives:
  - Custom PHP applications invoking system commands for administration; investigate parent-child lineage before whitelisting
level: critical
---
title: Webshell File Dropped in Webroot by Web Server Process
description: Detects creation of PHP script files in webroot directories by web server or PHP worker processes, a common persistence step following unauthenticated RCE exploitation such as the PHP2Shell flaws.
references:
  - https://thehackernews.com/2026/10/cisa-confirms-active-exploitation-of.html
  - https://attack.mitre.org/techniques/T1505.003/
author: Security Arsenal
status: experimental
date: 2026/10/20
tags:
  - attack.persistence
  - attack.t1505.003
logsource:
  category: file_event
  product: linux
detection:
  selection_path:
    TargetFilename|contains:
      - '/var/www/'
      - '/srv/www/'
      - '/usr/share/nginx/'
      - '/home/*/public_html/'
  selection_ext:
    TargetFilename|endswith:
      - '.php'
      - '.phtml'
      - '.phar'
      - '.php5'
      - '.php7'
  selection_actor:
    Image|endswith:
      - '/php-fpm'
      - '/php'
      - '/nginx'
      - '/apache2'
      - '/httpd'
  condition: selection_path and selection_ext and selection_actor
falsepositives:
  - Deployment pipelines writing application code via the web server context; suppress known CI/CD service accounts and paths
level: high

KQL — Microsoft Sentinel / Defender

Hunt for PHP worker processes spawning shells across Linux (Syslog/CEF-ingested) and Windows (MDE) estates. Run this over at least the past 14 days, then pivot on any hits to the source web server for full triage.

KQL — Microsoft Sentinel / Defender
// Hunt: PHP runtime spawning shells or script interpreters (PHP2Shell post-exploitation)
let phpParents = dynamic(["php-fpm", "php", "php-cgi", "php-cgi.exe", "php.exe", "php-win.exe"]);
let suspiciousChildren = dynamic(["sh", "bash", "dash", "zsh", "python", "python3", "perl", "curl", "wget", "nc", "ncat", "base64", "cmd.exe", "powershell.exe", "pwsh.exe", "certutil.exe", "rundll32.exe"]);
union isfuzzy=true
(DeviceProcessEvents
 | where InitiatingProcessFileName has_any (phpParents)
 | where FileName has_any (suspiciousChildren)
 | project TimeGenerated, DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, RemoteIP="n/a", Source="MDE"),
(Syslog
 | where Facility =~ "auth" or SyslogMessage has "php-fpm" or SyslogMessage has "php-cgi"
 | where SyslogMessage has_any (suspiciousChildren)
 | project TimeGenerated, DeviceName=Computer, AccountName="n/a", InitiatingProcessFileName="php", InitiatingProcessCommandLine=SyslogMessage, FileName=ProcessName, ProcessCommandLine=SyslogMessage, RemoteIP=HostIP, Source="Syslog"),
(CommonSecurityLog
 | where DeviceProcessName has_any (phpParents)
 | where AdditionalExtensions has_any (suspiciousChildren) or Message has_any (suspiciousChildren)
 | project TimeGenerated, DeviceName=DeviceName, AccountName=SourceUserName, InitiatingProcessFileName=DeviceProcessName, InitiatingProcessCommandLine=Message, FileName="n/a", ProcessCommandLine=Message, RemoteIP=SourceIP, Source="CEF"))
| sort by TimeGenerated desc

Velociraptor VQL

Deploy this hunt across your Linux and Windows web-tier fleet to sweep for PHP worker processes that have spawned shell interpreters — live evidence of successful exploitation.

VQL — Velociraptor
-- Hunt: PHP worker processes spawning shells or interpreters (PHP2Shell RCE indicator)
SELECT Pid,
       Ppid,
       Name AS ProcessName,
       Exe AS ProcessPath,
       CommandLine,
       Username,
       CreateTime
FROM pslist()
WHERE CommandLine =~ '(?i)(php-fpm|php-cgi|php\.exe)'
   OR Exe =~ '(?i)(/php-fpm|/php$|php-cgi|php\.exe$)'

-- Follow-up: enumerate child processes of any PHP worker and flag shell children
LET php_workers <= SELECT Pid, Name, Exe
FROM pslist()
WHERE Name =~ '(?i)php'

SELECT child.Pid AS ChildPid,
       child.Name AS ChildName,
       child.Exe AS ChildPath,
       child.CommandLine AS ChildCmdline,
       child.Username AS ChildUser,
       parent.Pid AS ParentPid,
       parent.Name AS ParentName
FROM pslist() AS child
JOIN php_workers AS parent ON child.Ppid = parent.Pid
WHERE child.Name =~ '(?i)(sh|bash|dash|zsh|python|perl|curl|wget|nc|ncat|cmd|powershell|certutil)'

Verification and Hardening Script

Run the following on Linux web servers to inventory your PHP version, identify running PHP services, check for vendor security updates, and detect suspicious recently-created PHP files in webroots (potential webshells).

Bash / Shell
#!/bin/bash
# PHP2Shell (CVE-2026-109618) exposure verification and hardening script
# Run as root on each PHP-enabled server

echo "=== [1] Installed PHP version(s) ==="
php -v 2>/dev/null || echo "php CLI not found"
php-fpm -v 2>/dev/null || php-fpm8.3 -v 2>/dev/null || echo "php-fpm binary not directly invocable"

echo ""
echo "=== [2] Running PHP services ==="
systemctl list-units --type=service --state=running 2>/dev/null | grep -iE 'php|fpm' || echo "No running PHP-FPM services detected"

echo ""
echo "=== [3] Pending security updates (Debian/Ubuntu) ==="
if command -v apt-get >/dev/null 2>&1; then
    apt-get update -qq 2>/dev/null
    apt-get -s upgrade 2>/dev/null | grep -iE 'php' | head -20
    echo ""
    echo "To apply PHP security updates: apt-get install --only-upgrade 'php*' -y && systemctl restart php*-fpm"
fi

echo ""
echo "=== [3b] Pending security updates (RHEL/Rocky/Alma) ==="
if command -v dnf >/dev/null 2>&1; then
    dnf check-update --security 2>/dev/null | grep -iE 'php' | head -20
    echo ""
    echo "To apply PHP security updates: dnf update --security 'php*' -y && systemctl restart php-fpm"
fi

echo ""
echo "=== [4] Recently created/modified PHP files in webroots (last 7 days) - possible webshells ==="
for webroot in /var/www /srv/www /usr/share/nginx/html /home/*/public_html; do
    if [ -d "$webroot" ]; then
        find "$webroot" -type f \( -name '*.php' -o -name '*.phtml' -o -name '*.phar' \) -mtime -7 -printf '%T@ %Tc %p\n' 2>/dev/null | sort -rn | head -25
    fi
done

echo ""
echo "=== [5] PHP-FPM workers with shell children (live compromise check) ==="
for pid in $(pgrep -f 'php-fpm' 2>/dev/null); do
    children=$(ps --ppid "$pid" -o pid=,comm= 2>/dev/null | grep -E '\b(sh|bash|dash|zsh|python|perl|curl|wget|nc|ncat)\b')
    if [ -n "$children" ]; then
        echo "ALERT: php-fpm PID $pid has shell children:"
        echo "$children"
    fi
done

echo ""
echo "=== [6] Outbound connections from web server users ==="
ss -tupn 2>/dev/null | grep -iE 'php|www-data|apache|nginx' | grep -v ':80\|:443' | head -20

echo ""
echo "=== Remediation checklist ==="
echo "1. Apply vendor PHP security updates immediately (see section 3 output)."
echo "2. Restart php-fpm / Apache after patching - in-memory processes keep the vulnerable code until restart."
echo "3. Review any files flagged in section 4 before deleting; preserve for forensics."
echo "4. Investigate any alerts from sections 5 and 6 as active compromise - isolate the host."

Remediation

1. Patch Immediately

CISA KEV listing means the clock is already running. Under BOD 22-01, federal civilian agencies must remediate within the KEV-mandated due date (typically ~3 weeks for new additions); all other organizations should adopt the same urgency. Because the exact fixed version numbers were not yet enumerated in the initial reporting:

  • Apply the latest PHP security release for your branch from php.net/downloads or your OS distribution's security channel (Debian Security Tracker, Ubuntu Security Notices, Red Hat Security Errata).
  • Verify against the PHP Group's official advisory and the CISA KEV catalog entry for the confirmed affected version ranges before declaring remediation complete.
  • Restart all PHP runtimes after patching (php-fpm, Apache with mod_php). The vulnerable interpreter code remains in memory until the process restarts — installing the package alone does not close the hole.
  • Do not forget container images, vendor appliances, and CMS-bundled PHP. Rebuild and redeploy containerized workloads with patched base images, and check appliance vendor advisories for embedded PHP runtimes.

2. Compensating Controls (While Patching Is Staged)

  • WAF rules: Deploy virtual-patching signatures for the PHP2Shell exploitation patterns as your WAF vendor publishes them. Treat this as a stopgap, not a fix.
  • Egress filtering: Restrict outbound connections from web server identities (www-data, apache, IIS app pools) to explicitly required destinations only. This blunts second-stage payload retrieval and C2 even if exploitation succeeds.
  • Disable dangerous PHP functions on production workloads where the application permits: exec, shell_exec, system, passthru, popen via disable_functions in php.ini. This converts many RCE exploits into non-events.
  • File system hardening: Mount webroot upload directories noexec where feasible and deny PHP execution in upload paths at the web server layer.

3. Assume Breach and Hunt

Because exploitation predates your patch, patching alone is insufficient. Before closing the ticket:

  • Run the detections above across at least 14–30 days of retrospective telemetry.
  • Review web server access logs for anomalous request patterns against PHP endpoints from external sources.
  • Audit webroots for unauthorized or recently modified PHP files, unexpected cron entries, and new local user accounts.
  • If any indicator of compromise is found, isolate the host, preserve forensic images, and initiate full incident response — the attacker may have moved laterally from the web tier to databases or internal services.

4. Operationalize Going Forward

  • Add PHP runtime version inventory to your vulnerability management program with KEV-priority SLAs (KEV-listed CVEs should trigger emergency change, not the standard 30-day cycle).
  • Ensure process lineage telemetry (Sysmon, auditd, or EDR) is collecting from web-tier hosts — the parent-child detections above are only as good as your telemetry.

Key Takeaways

  1. CVE-2026-109618 and a second undisclosed PHP2Shell CVE (both CVSS 9.2) are under active exploitation per CISA KEV — this is an emergency patch event, not a routine cycle.
  2. The highest-fidelity detection is behavioral: PHP worker processes spawning shells, downloaders, or script interpreters is almost never legitimate in production.
  3. Patch + restart + hunt — in that order, all three required. Restarting runtimes and retrospective hunting are the steps teams most often skip.
  4. Egress filtering and disable_functions hardening materially reduce the impact of this entire vulnerability class going forward.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.