Threat Overview
WordPress Core CVE-2026-87902 is a critical path-traversal/local-file-inclusion vulnerability in page-template resolution. An unauthenticated attacker can manipulate the pagename value so get_page_template() includes a readable local PHP file outside the active theme directories. Remote code execution requires additional server and theme preconditions. Patchstack observed probing within hours of disclosure, and September 24 reporting confirms activity progressed to attempts using pearcmd.php to write attacker-controlled PHP files to disk.
References
- The Hacker News, September 24, 2026 – https://thehackernews.com/2026/09/attackers-exploit-wordpress-cve-2026.html
- Patchstack, September 22, 2026 – https://patchstack.com/articles/cve-2026-87902-attackers-started-probing-wordpress-sites-hours-after-the-patch/
- WordPress 7.1.2 Release, September 22, 2026 – https://wordpress.org/news/2026/09/wordpress-7-1-2-release/
Impacted Systems
WordPress Core 4.7.0 through 7.1.1. Fixed releases include 7.1.2, 7.0.6, 6.9.9, 6.8.10 and security backports through 4.7.37. Exploitation requires an active theme with a top-level directory beginning with page- and a readable local PHP target. Current exploitation has used pearcmd.php where present.
Why this matters
The attack is unauthenticated and exploitation began within hours of disclosure. Observed activity has progressed from harmless inclusion probes to PHP file writes. Successful exploitation can provide code execution under the web-server account.
Exploitation Status
Confirmed active exploitation attempts. Patchstack first observed probing on September 22. September 24 reporting describes attempts using /usr/local/lib/php/pearcmd.php to write PHP content to /tmp and /var/tmp. Observed names include wp-pear-rce-flag.php, poc87902.php, luci_<random>.php and zeta_<random>.php.
What this hunt looks for
Double-encoded traversal in pagename, pagename plus page_id requests, reported exploitation source IPs, pearcmd.php references, PHP files written under temporary directories, web-server child processes, and unexpected outbound network activity.
Required logs
Azure WAF or other web/proxy telemetry in CommonSecurityLog, Defender XDR DeviceProcessEvents, DeviceFileEvents and DeviceNetworkEvents where the web server is onboarded, and Linux Syslog where available.
First Pass – Double-Encoded WordPress Traversal
CommonSecurityLog
| where TimeGenerated >= ago(7d)
| where RequestURL has_any ("%252e%252e","%252E%252E")
| where RequestURL has "pagename"
| project TimeGenerated,SourceIP,DestinationIP,RequestMethod,RequestURL,DeviceAction,Message
| order by TimeGenerated descKnown Exploitation Source IPs
CommonSecurityLog
| where TimeGenerated >= ago(7d)
| where SourceIP in ("104.194.9.227","43.250.53.42","180.251.159.243","195.178.110.247","107.189.14.87","45.61.184.170","92.246.130.76","169.58.48.193","169.58.48.195","2001:df1:e8c0::106b")
| project TimeGenerated,SourceIP,DestinationIP,DestinationPort,RequestMethod,RequestURL,DeviceAction,Message
| order by TimeGenerated descpagename and page_id Pairing
CommonSecurityLog
| where TimeGenerated >= ago(7d)
| where RequestURL has "pagename" and RequestURL has "page_id"
| project TimeGenerated,SourceIP,DestinationIP,RequestMethod,RequestURL,DeviceAction,Message
| order by TimeGenerated descpearcmd.php and Observed Payload Names
union isfuzzy=true CommonSecurityLog,Syslog
| where TimeGenerated >= ago(7d)
| where tostring(*) has_any ("pearcmd.php","wp-pear-rce-flag.php","poc87902.php","luci_","zeta_")
| project TimeGenerated,Type,Computer=tostring(column_ifexists("Computer","")),SourceIP=tostring(column_ifexists("SourceIP","")),Message=tostring(column_ifexists("Message","")),SyslogMessage=tostring(column_ifexists("SyslogMessage",""))
| order by TimeGenerated descPHP Files Created in Temporary Directories
DeviceFileEvents
| where Timestamp >= ago(7d)
| where FileName endswith ".php"
| where FolderPath startswith "/tmp/" or FolderPath startswith "/var/tmp/"
| project Timestamp,DeviceName,ActionType,FileName,FolderPath,SHA256,InitiatingProcessFileName,InitiatingProcessCommandLine
| order by Timestamp descWeb Server Spawning Shells or Downloaders
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where InitiatingProcessFileName in~ ("php","php-fpm","apache2","httpd","nginx")
| where FileName in~ ("sh","bash","dash","curl","wget","python","python3","perl")
| project Timestamp,DeviceName,AccountName,InitiatingProcessFileName,InitiatingProcessCommandLine,FileName,ProcessCommandLine,SHA256
| order by Timestamp descWeb Server Outbound Connections
DeviceNetworkEvents
| where Timestamp >= ago(7d)
| where InitiatingProcessFileName in~ ("php","php-fpm","apache2","httpd","nginx")
| project Timestamp,DeviceName,InitiatingProcessFileName,InitiatingProcessCommandLine,RemoteUrl,RemoteIP,RemotePort
| order by Timestamp descWordPress Syslog Fallback
Syslog
| where TimeGenerated >= ago(7d)
| where SyslogMessage has_any ("%252e%252e","pearcmd.php","wp-pear-rce-flag.php","poc87902.php","luci_","zeta_")
| project TimeGenerated,Computer,HostName,ProcessName,SeverityLevel,SyslogMessage
| order by TimeGenerated descDetection Notes
The highest-signal web indicator is pagename containing double-encoded traversal such as %252e%252e, especially with page_id. Reported source IPs are useful pivots but are not exhaustive. Endpoint telemetry is required to see PHP file writes or post-exploitation behavior. CommonSecurityLog fields depend on the WAF/proxy parser.