WordPress Core CVE-2026-119977 — exploited upgrade-window RCE

Threat Overview

An unauthenticated actor may race a full-package core update and request a predictable staged installer path. The exploit window is short, and request matches alone cannot prove code execution. This is relevant to MSSP customers because compromised externally exposed or trusted software components can enable privileged execution, credential theft or persistence. A matching behavioral signal is not by itself proof of this specific vulnerability.

References

– Vendor/research coverage (November 2026): https://thehackernews.com/2026/11/cisa-confirms-hackers-exploiting.html

Impacted Systems

WordPress Core 4.7.0–7.1.3, self-hosted sites performing full-package core updates where the temporary wp-content/upgrade staging area is web-accessible. Fixed: 7.1.4 or branch-specific security backports. WordPress 4.6 and earlier are outside supported backports. Cloud-hosted managed WordPress must be assessed by provider configuration.

Why this matters

Targeted intelligence indicates a credible enterprise exposure or confirmed malicious activity. The queries below are designed for the specific telemetry that may be ingested into Sentinel.

Exploitation Status

CISA KEV confirms exploitation (added November 3, reported November 4). No customer-specific exploitation is asserted.

What this hunt looks for

No customer workspace was queried. The hunt package defines searches for relevant available Microsoft Sentinel telemetry where the specified data source is ingested; it does not claim a completed review.

Required logs

Required data sources vary by query: Microsoft Sentinel CommonSecurityLog, Syslog, DeviceProcessEvents, DeviceFileEvents, and DeviceNetworkEvents where ingested. Query execution requires the corresponding tables and permissions.

W01 — HTTP requests targeting temporary upgrade PHP

CommonSecurityLog | where TimeGenerated >= ago(30d) | extend U=tostring(RequestURL) | where U contains "/wp-content/upgrade/" and U contains ".php" | project TimeGenerated, SourceIP, DestinationIP, RequestURL, DeviceAction, DeviceName | order by TimeGenerated desc

W02 — Repeated upgrade-path probing

CommonSecurityLog | where TimeGenerated >= ago(30d) | where tostring(RequestURL) contains "/wp-content/upgrade/" | summarize Requests=count(), URLs=make_set(RequestURL,10) by SourceIP, DestinationIP, bin(TimeGenerated,5m) | where Requests >= 5 | order by Requests desc

W03 — PHP or web server spawning command shells

DeviceProcessEvents | where TimeGenerated >= ago(30d) | where InitiatingProcessFileName in~ ("php","php-fpm","php-fpm8.2","apache2","httpd","nginx") | where FileName in~ ("sh","bash","dash","curl","wget","python3","perl","nc") | project TimeGenerated,DeviceName,FileName,ProcessCommandLine,InitiatingProcessFileName,InitiatingProcessCommandLine

W04 — PHP files created in WordPress upload or upgrade trees

DeviceFileEvents | where TimeGenerated >= ago(30d) | where FolderPath contains "/wp-content/" and (FolderPath contains "/upgrade/" or FolderPath contains "/uploads/") | where FileName endswith ".php" | project TimeGenerated,DeviceName,ActionType,FolderPath,FileName,InitiatingProcessFileName

W05 — Unexpected outbound connections from web-server processes

DeviceNetworkEvents | where TimeGenerated >= ago(30d) | where InitiatingProcessFileName in~ ("php","php-fpm","apache2","httpd","nginx") | where isnotempty(RemoteIP) and not(ipv4_is_private(RemoteIP)) | summarize Connections=count(),Ports=make_set(RemotePort,10) by DeviceName,InitiatingProcessFileName,RemoteIP | order by Connections desc

W06 — New external web destinations compared with baseline

let baseline=DeviceNetworkEvents | where TimeGenerated between (ago(30d)..ago(2d)) | where InitiatingProcessFileName in~ ("php","php-fpm","apache2","httpd","nginx") | summarize by DeviceId,RemoteIP; DeviceNetworkEvents | where TimeGenerated >= ago(2d) | where InitiatingProcessFileName in~ ("php","php-fpm","apache2","httpd","nginx") | where isnotempty(RemoteIP) and not(ipv4_is_private(RemoteIP)) | join kind=leftanti baseline on DeviceId,RemoteIP | project TimeGenerated,DeviceName,RemoteIP,RemotePort,InitiatingProcessFileName

W07 — Linux syslog web-server errors and execution anomalies

Syslog | where TimeGenerated >= ago(30d) | where ProcessName has_any ("apache","httpd","nginx","php") or SyslogMessage has_any ("wp-content/upgrade","setup-config.php") | where SyslogMessage has_any ("wp-content/upgrade","setup-config.php","permission denied","fatal error") | project TimeGenerated,Computer,ProcessName,SyslogMessage

Detection Notes

WordPress application or WAF access logs must be ingested to observe HTTP requests; Defender endpoint telemetry is needed for process/file follow-up. Generic network logs cannot prove exploit success. The first query is the initial triage priority; follow-up queries require analyst correlation with affected-product inventory and normal administrative activity. Broad process/network queries can produce benign results.

Leave a Reply