2026-10-28 — Oracle PeopleSoft CVE-2026-35273 SSRF-to-RCE Chain: Sentinel Hunts

Threat Overview

TrendAI Zero Day Initiative’s October 27 technical report explains three vulnerabilities in the Oracle PeopleSoft chain currently tracked under CVE-2026-35273. PSIGW HttpListeningConnector forwards attacker-controlled requests to loopback; PSEMHUB trusts localhost by default. Attackers can then write a JSP webshell or place XML loaded by Java XMLDecoder at hub initialization. Mandiant documented ShinyHunters/UNC6240 exploitation beginning in May and renewed attacks in September, including encoded-path WAF bypass. The new disclosure provides actionable exploit-chain detail; the underlying vulnerability was patched in June.

References

TrendAI ZDI analysis — October 27, 2026

Oracle security alert — June 10, 2026

The Hacker News — October 28, 2026

Impacted Systems

Oracle PeopleSoft Enterprise PeopleTools 8.61 and 8.62 on self-managed PeopleSoft WebLogic application tiers; PSIGW exposed over HTTP(S) and internal PSEMHUB reachable through loopback SSRF. Oracle says older unsupported versions may be affected but were not tested. Oracle’s June 10 security alert supplies patch instructions; no universal fixed build is published in the public alert. Oracle Database alone is not asserted affected.

Why this matters

Confirmed unauthenticated exploitation against enterprise application tiers can yield a webshell, arbitrary code execution and credential exposure. URL-only WAF controls were bypassed with percent-encoded PSEMHUB paths in observed attacks.

Exploitation Status

Confirmed in-the-wild exploitation: Mandiant/Google. Confirmed technical chain: ZDI. An HTTP path match alone does not prove a successful exploit.

What this hunt looks for

PSIGW and encoded PSEMHUB HTTP requests; loopback forwarding; JSP and environment XML writes; Java child-shell execution; unusual Java egress; and Windows 4688 or Syslog fallbacks.

Required logs

CommonSecurityLog with HTTP URI fields, AzureDiagnostics WAF, Syslog with PeopleSoft application messages, DeviceProcessEvents, DeviceFileEvents, DeviceNetworkEvents, or SecurityEvent 4688 where ingested into Microsoft Sentinel. Not all tables are required for each hunt; each query uses the named table.

Hunt 01 — PSIGW and PSEMHUB requests in security gateways

CommonSecurityLog
| where TimeGenerated > ago(30d)
| extend Url = tolower(strcat(tostring(column_ifexists('RequestURL','')), ' ', tostring(column_ifexists('Message','')), ' ', tostring(column_ifexists('AdditionalExtensions',''))))
| where Url has_any ('psigw','psemhub','httplisteningconnector','%50semhub')
| where Url contains 'httplisteningconnector' or Url contains 'psemhub' or Url contains '%50semhub'
| project TimeGenerated, DeviceVendor, DeviceProduct, SourceIP, DestinationIP, RequestURL, DeviceAction, Message
| order by TimeGenerated desc

Hunt 02 — Azure WAF connector and encoded management paths

AzureDiagnostics
| where TimeGenerated > ago(30d)
| where Category has 'WebApplicationFirewall'
| extend Uri=tolower(strcat(tostring(column_ifexists('requestUri_s','')), ' ', tostring(column_ifexists('requestUri','')), ' ', tostring(column_ifexists('details_message_s',''))))
| where Uri contains 'psigw' or Uri contains 'psemhub' or Uri contains '%50semhub'
| project TimeGenerated, ResourceId, clientIP_s=column_ifexists('clientIP_s',''), action_s=column_ifexists('action_s',''), Uri, ruleName_s=column_ifexists('ruleName_s','')
| order by TimeGenerated desc

Hunt 03 — PSIGW SSRF and loopback in application Syslog

Syslog
| where TimeGenerated > ago(30d)
| extend M=tolower(SyslogMessage)
| where M contains 'psigw' or M contains 'psemhub' or M contains 'httplisteningconnector'
| where M contains '127.0.0.1' or M contains 'httptargetconnector' or M contains 'xml' or M contains 'exception'
| project TimeGenerated, Computer, ProcessName, SyslogMessage
| order by TimeGenerated desc

Hunt 04 — Java or WebLogic spawning shells

DeviceProcessEvents
| extend EventTime=coalesce(todatetime(column_ifexists('TimeGenerated',datetime(null))),todatetime(column_ifexists('Timestamp',datetime(null))))
| where EventTime > ago(30d)
| where InitiatingProcessFileName in~ ('java','java.exe','javaw.exe')
| where FileName in~ ('cmd.exe','powershell.exe','pwsh.exe','bash','sh','curl','wget','python','python3','certutil.exe')
| project EventTime, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by EventTime desc

Hunt 05 — PSEMHUB JSP and environment XML modifications

DeviceFileEvents
| extend EventTime=coalesce(todatetime(column_ifexists('TimeGenerated',datetime(null))),todatetime(column_ifexists('Timestamp',datetime(null))))
| where EventTime > ago(30d)
| extend P=tolower(FolderPath), F=tolower(FileName)
| where (P contains 'psemhub' and F endswith '.jsp') or (P contains 'envmetadata/data/environment' and F endswith '.xml')
| where ActionType in~ ('FileCreated','FileModified','FileRenamed')
| project EventTime, DeviceName, ActionType, FolderPath, FileName, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by EventTime desc

Hunt 06 — Windows 4688 Java-to-shell fallback

SecurityEvent
| where TimeGenerated > ago(30d) and EventID == 4688
| extend Child=tolower(tostring(column_ifexists('NewProcessName',''))), Parent=tolower(tostring(column_ifexists('ParentProcessName',''))), Cmd=tolower(tostring(column_ifexists('CommandLine','')))
| where Parent contains 'java' or Cmd contains 'psemhub' or Cmd contains 'psigw'
| where Child has_any ('cmd.exe','powershell.exe','pwsh.exe','certutil.exe') or Cmd has_any ('-enc','downloadstring','invoke-webrequest')
| project TimeGenerated, Computer, Account, Parent, Child, Cmd
| order by TimeGenerated desc

Hunt 07 — New Java external destinations

let baseline=DeviceNetworkEvents
| extend EventTime=coalesce(todatetime(column_ifexists('TimeGenerated',datetime(null))),todatetime(column_ifexists('Timestamp',datetime(null))))
| where EventTime between (ago(30d)..ago(2d))
| where InitiatingProcessFileName in~ ('java','java.exe','javaw.exe')
| summarize by DeviceName, RemoteIP;
DeviceNetworkEvents
| extend EventTime=coalesce(todatetime(column_ifexists('TimeGenerated',datetime(null))),todatetime(column_ifexists('Timestamp',datetime(null))))
| where EventTime > ago(2d)
| where InitiatingProcessFileName in~ ('java','java.exe','javaw.exe')
| where isnotempty(RemoteIP) and not(ipv4_is_private(RemoteIP))
| join kind=leftanti baseline on DeviceName, RemoteIP
| project EventTime, DeviceName, RemoteIP, RemotePort, RemoteUrl, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by EventTime desc

Hunt 08 — XMLDecoder and PSEMHUB initialization anomalies

Syslog
| where TimeGenerated > ago(30d)
| extend M=tolower(SyslogMessage)
| where M contains 'xmldecoder' or M contains 'hubmbeanpersistance' or M contains 'envmetadata/data/environment'
| project TimeGenerated, Computer, ProcessName, SyslogMessage
| order by TimeGenerated desc

Detection Notes

Highest-signal findings combine PSIGW/PSEMHUB request activity with JSP writes or Java child shells on a confirmed PeopleSoft server. WAF logs may omit bodies and normalize encoded URLs differently. The XMLDecoder path may leave no JSP. Windows 4688 cannot cover Linux servers; generic Java network activity is noisy. All conclusions are limited to ingested Sentinel telemetry and retention; no customer workspace was queried and no findings are asserted.

Leave a Reply