CyberXero: AI-Augmented Initial Access Broker

Russian-speaking, financially motivated AI-augmented initial access broker · Ukrainian energy and utilities plus global WordPress and e-commerce estates · Claude Code agent swarm and PentAGI wired to Cobalt Strike
Threat
CyberXero
Severity
HIGH active initial access broker
Type
IAB, Cobalt Strike C2, webshells, Redis abuse
Initial Access
Mass WordPress and e-commerce exploitation; exposed Redis; curated manual intrusion
Version
v0.1 · 2026-10-13
Author
HuntPack
Confidence
HIGH behaviour (primary vendor); MEDIUM IOCs (single originating report)
01

Executive Summary

Attacker objective: sell access. CyberXero is the forum alias of an initial access broker that SOCRadar's Threat Research Unit documented on 2026-10-06. It runs two pipelines from one workstation: a global automated campaign that mass-compromises WordPress and e-commerce sites for access and payment data, and a curated manual campaign against Ukrainian energy and utilities. Confirmed exfiltration covers four Ukrainian organisations and more than 628,000 records on individuals, including 564,073 subscriber records and 213,340 access-log entries from a Kharkiv district heating provider.

What is different: an AI orchestration layer on the actor's own infrastructure. SOCRadar reports up to 51 specialised Claude Code agent definitions on the primary workstation and a PentAGI deployment wired into a Cobalt Strike team server through an AI provider API for payload generation. One recorded run scanned 4,708 targets, reached 429 WordPress admin panels and deployed 32 shells in 61 seconds. The whole operation became visible because the actor exposed an open directory with its live working directory, AI session logs and plaintext tokens.

Scope of this pack: the actor, not the vulnerability. The WordPress REST API batch flaws (CVE-2026-63030, CVE-2026-60137) are only the delivery vector for the mass pipeline and are covered by a separate pack in this library; nothing here hunts the vulnerability itself, and no indicator is borrowed from another pack. This pack hunts what CyberXero does after and around that entry: Cobalt Strike PowerShell stagers, the UpdSvc service, remote WMI, Redis abuse with SSH key injection, webshell execution on sensored web servers, and the machine-speed tempo.

Honest coverage: the mass scanning and panel compromise happen against internet-facing web applications. Most of that is web-server-log and database territory, not endpoint telemetry. The strong endpoint surfaces are the PowerShell stager and beacon on sensored Windows hosts, UpdSvc service creation, remote WMI, shell-driven authorized_keys edits and Redis abuse on sensored Linux hosts, and webshell command execution on sensored web servers. Section 15 states the blind spots as gaps.

Defender priority: run Q1, Q3, Q6, Q12 and Q17 across 30 days first (near-zero false positives). Then Q15 and Q16 on every sensored web server, and Q14 to find Redis reachable from the internet. Run the section 7 native checks for the parts no sensor sees: rogue wp2_ administrators, wp2shell_ plugin directories, and authorized_keys on Redis hosts. Nothing in this pack ships at prevent: the whole indicator set originates from one report.

02

Source Review & Web Hunter Notes

TierSourceKey findingCarry forward
1SOCRadar: CyberXero, An AI-Augmented Initial Access Broker Targeting Ukrainian Critical Infrastructure (2026-10-06)Primary source. All infrastructure, hashes, behavioural indicators, TTP table, hunting guidance. Snapshot 01.Yes
2GBHackers: Russian-Speaking CyberXero Uses AI Agent Swarm (2026-10-07)Secondary. Restates five of the SOCRadar infrastructure IPs and the campaign narrative. Derivative of source 1. Snapshot 02.Yes (narrative, five IPs)
2Security Affairs: CyberXero Used 51 AI Agents to Steal 628,000 Ukrainian Records (2026-10-12)Secondary. Quotes SOCRadar; confirms scale, victim counts, operator and refusal findings. No indicators. Snapshot 03.Yes (narrative)
2The Hacker News: CyberXero Uses Claude Code in Campaign That Stole Over 628,000 Ukrainian Records (2026-10-12)Secondary. Confirms the two-pipeline structure, Redis breach of two Chinese entities, CVE delivery vector and hunting advice. Snapshot 04.Yes (narrative)
2eSecurityPlanet: CyberXero Uses Claude Code in Ukraine Data Theft (2026-10-12)Secondary. Repeats wp2_, wp2shell_ and authorized_keys hunting guidance. Snapshot 05.Yes (narrative)
1MITRE ATT&CK T1098.004, T1505.003, T1543.003, T1047, T1059.001Technique names and mitigation IDs used in sections 6 and 12. Snapshots 06 to 10.Yes
1Redis documentation: Redis securitybind, protected mode, requirepass, ACLs, rename-command CONFIG. Snapshot 11.Yes (hardening)
1WordPress Developer Resources: Hardening WordPressFile permissions, DISALLOW_FILE_EDIT, plugin hygiene. Snapshot 12.Yes (hardening)
1Microsoft Learn: about_Logging_WindowsScript block and module logging. Snapshot 13.Yes (hardening)

Web Hunter decisions and discrepancies

  • One originating report. Every indicator comes from SOCRadar. The four secondary outlets restate it. GBHackers repeats five IPs verbatim, but it credits SOCRadar throughout, so it is not independent corroboration. Result: every indicator ships as detect, nothing at prevent, and confidence is MEDIUM for indicators and HIGH for the behavioural description.
  • Record count correction. The task brief gave 628,073 heating-provider records. SOCRadar and the secondary coverage say 564,073 subscriber records plus 213,340 access-log entries at that provider, and more than 628,000 records across four organisations. This pack uses the SOCRadar figures.
  • Hash descriptions. SOCRadar lists 71e21094... as 1.bin and 59c535f4... as config.bin, both Chinese-cluster staging payloads. The stager hash is a cracked Cobalt Strike 4.9.1 build attributed by SOCRadar to Pwn3rs Team.
  • Scope held to the actor. The CVE list in the source (CVE-2026-63030, CVE-2026-60137, CVE-2026-4815, CVE-2015-1397) is mentioned only as delivery. No detection here targets the REST API flaw.
  • Behavioural patterns are not atomic IOCs. wp2_ plus eight hex, wp2shell_ plus eight hex and the 13-character stager path are shipped as patterns and queries, not as CSV rows.
  • Not in the endpoint's view. The Telegram bot notification, the AI session logs, the VLESS/Xray proxy layer and the CryptoPay gateway are actor-side. The pack lists them for context and builds nothing on them.
  • Untrusted source content. SOCRadar describes material recovered from the actor's own directory. The pack treats all of it as data: nothing quoted from that directory was executed or fetched, and no value from it reaches an action column.
03

Hunt Brief & Attack Chain

Hunt hypotheses (ordered by fidelity)

#HypothesisMITRETelemetryQueriesConfidence
H1A Windows host ran a PowerShell or cmd IEX stager against a CyberXero address or a bare-IP high-port URL.T1059.001, T1105Process creation with command line (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents)Q1, Q2HIGH
H2A service named UpdSvc, or any service whose binPath downloads and executes, was created and then run by services.exe.T1543.003Service creation (CrowdStrike: CreateService. SentinelOne and Defender: no listed event, use Windows event 7045 or the Services registry key) plus process creation with parentQ3, Q4, Q5HIGH
H3A sensored host talked to, or accepted a connection from, a published CyberXero address or the team server port set.T1071.001, T1595.002Outbound network connection with process (CrowdStrike: NetworkConnectIP4. SentinelOne: IP Connect. Defender: DeviceNetworkEvents); inbound accepted connection (CrowdStrike: NetworkReceiveAcceptIP4)Q6, Q7, Q8HIGH for IPs, MEDIUM for ports
H4WMI was used to execute commands remotely on or from a host.T1047Process creation with parent and command lineQ9, Q10MEDIUM
H5A Redis host was reached from the internet, abused through replication or config commands, and had an SSH key injected.T1190, T1098.004Inbound accepted connection; Linux process creation with command line and parentQ11, Q12, Q13, Q14MEDIUM (the Redis-side file write is invisible, see gaps)
H6A webshell on a sensored web server executed operator commands, at machine pace.T1505.003Process creation with parent (web worker as parent)Q15, Q16, Q17MEDIUM
H7One of the four published files was present on a sensored host.T1105, T1027File hash on process and file-write eventsQ18MEDIUM (low yield, see Q18 limit)

Attack chain

StepBehaviourTelemetryHunt angle
1. Reconmasscan, nuclei and wpscan (SOCRadar) against global ranges and a 95-subdomain Ukrainian energy list; 45.88.106.78 is the mass scanning serverWeb and firewall logs; inbound accepted connection on sensored hostsQ7, native N1
2. Entry (opportunistic)wp2shell Python package against WordPress; also Magento, PrestaShop, Support Board. CVE delivery only.Web server and database logs (outside endpoint telemetry)Native N2 to N4
3. Webshell and rogue adminwp2_ plus eight hex administrator; wp2shell_ plus eight hex plugin; WSO-Shell.php registered as an active pluginDatabase, file system; web worker child processes on sensored hostsQ15, Q16, Q17, N2, N3
4. Entry (directed / Redis)Exposed Redis abused by rogue replication (SLAVEOF technique) to inject SSH keys; 42.193.100.94 is the Redis exploitation nodeInbound accepted connection; Linux process creationQ11, Q12, Q13, Q14, N5
5. Stager and C2PowerShell IEX from 42.193.227.214:8033, Cobalt Strike beacon over 1002 (HTTPS) and 8044 (HTTP)Process creation; outbound connectionQ1, Q2, Q6, Q8
6. PersistenceUpdSvc service via svc.cna, binPath is the IEX downloadService creation; process creation with parent services.exeQ3, Q4, Q5
7. Lateral movementWMI remote execution; pass-the-hash via scan_pth.cnaProcess creation; authentication telemetryQ9, Q10; PTH is a gap
8. Collection and exfiltrationDatabase dumps (MySQL, MongoDB, Redis), hardcoded-credential extractors, Telegram bot notificationsDatabase and network logs (outside endpoint telemetry)Gap
04

Consolidated IOC Table

Twelve atomic indicators, all from the SOCRadar indicator tables and present in snapshot 01-socradar-cyberxero.txt. All are single-originated, so all ship as detect. Confidence is MEDIUM because the infrastructure is cloud-hosted and perishable. Behavioural patterns follow the atomic rows.

TypeValueConfidenceActionContextExpiry
SHA-25692a789444708fa1cb4cc5a89e0aa6cc7a279b62a7b8a4d2857255a18197d0090MEDIUMdetectstager32.bin Cobalt Strike x86 stager (Pwn3rs Team 4.9.1 build). SOCRadar only.2027-04-13
SHA-256a5ae0aab352871bc0b038b3aa43b03eb223425628c884af7b9fc592cd34eb86cMEDIUMdetectWSO-Shell.php WSO webshell obfuscated with R00t-Shell.com 2.0.15. SOCRadar only.2027-04-13
SHA-25671e21094c1ac1cf0275c91ed377965e248bca1c12711f6dd20e2682681fc1192MEDIUMdetect1.bin Chinese-cluster staging payload. SOCRadar only.2027-04-13
SHA-25659c535f47ab4d35f6d9fc8b8aec4a72438ea0b89e5a4dcea74b05d2d32cfa483MEDIUMdetectconfig.bin Chinese-cluster staging payload. SOCRadar only.2027-04-13
IPv446.21.250.135MEDIUMdetectPrimary workstation and open directory seed node. SOCRadar, restated by GBHackers (derivative, not independent).2027-04-13
IPv445.88.106.2MEDIUMdetectProvisioning server port 1500. SOCRadar, restated by GBHackers (derivative, not independent).2027-04-13
IPv445.88.106.78MEDIUMdetectMass scanning server. SOCRadar only.2027-04-13
IPv442.193.227.214MEDIUMdetectCobalt Strike team server (1002 HTTPS beacon / 8044 HTTP staging / 8033 PS stager / 9995). SOCRadar, restated by GBHackers (derivative, not independent).2027-04-13
IPv442.193.100.94MEDIUMdetectRedis exploitation node and PentAGI agents. SOCRadar only.2027-04-13
IPv449.234.12.182MEDIUMdetectStaging and payload delivery (Chinese cluster). SOCRadar only.2027-04-13
IPv4212.193.31.189MEDIUMdetectMulti-chain CryptoPay gateway. SOCRadar, restated by GBHackers (derivative, not independent).2027-04-13
IPv491.208.184.148MEDIUMdetectSecondary workstation. SOCRadar, restated by GBHackers (derivative, not independent).2027-04-13

Behavioural indicators (patterns, not atomic IOCs)

KindValueMeaningWhere used
Patternwp2_[0-9a-f]{8}Rogue WordPress administrator username created by wp2shellHunt (database, not endpoint)
Pattern/wp-content/plugins/wp2shell_[0-9a-f]{8}/wp2shell webshell plugin directoryHunt (web root file sweep, Q17)
NameWSO-Shell.phpWSO-family webshell registered as an active pluginHunt (file sweep, Q17)
NameUpdSvcWindows service created by the Cobalt Strike svc.cna aggressor script; binPath is a C2 IEX downloadDetect (Q3, Q4, Q5)
Patternhttp://42.193.227.214:8033/[a-z0-9]{13}PowerShell IEX stager download URLDetect (Q1, Q2)
Ports1002, 8044, 8033, 9995 on 42.193.227.214Beacon HTTPS, HTTP staging, stager delivery, team serverHunt by port set (Q8)
05

Affected Surface & Telemetry Matrix

SurfaceRequired telemetryPriorityGap risk
Sensored Windows servers and workstations reachable by the Cobalt Strike chainProcess creation with command line and parent (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents); service creation (CrowdStrike: CreateService); outbound connection (CrowdStrike: NetworkConnectIP4)CRITICALLOW for stager and service. Service creation is a cross-platform gap: outside endpoint telemetry on SentinelOne and Defender, use Windows event 7045.
Sensored Linux web servers running WordPress, Magento or PrestaShopProcess creation with parent (web worker as parent); inbound accepted connection (CrowdStrike: NetworkReceiveAcceptIP4)CRITICALMEDIUM: command execution is visible, the file write of the webshell and the SQL injection are outside endpoint telemetry.
Sensored Linux Redis hostsProcess creation with command line and parent; inbound accepted connectionHIGHHIGH: the Redis save that writes authorized_keys creates no process, and the replication handshake is on the wire.
WordPress application and database (wp_users, plugin directory)Database audit, file integrity, web server access logsCRITICALHIGH: outside endpoint telemetry. Native hunts N2 to N4 are the only coverage.
Perimeter and egress (firewall, proxy, DNS)Connection logs with destination IP and portHIGHMEDIUM: the strongest place to see the IP and port set for hosts with no sensor.
Identity (NTLM pass-the-hash across segments)Authentication events with logon typeMEDIUMHIGH: no query in this pack; scan_pth.cna is documented only as a script name.
Actor-side: Telegram notifications, AI session logs, VLESS/Xray, CryptoPayNone on a defender endpointINFONot observable by a defender sensor. Listed for context only.
06

ATT&CK Mapping

TacticTechniqueNameObserved behaviourQueryMitigations
ReconnaissanceT1595.002Active Scanning: Vulnerability Scanningmasscan, nuclei, wpscan from 45.88.106.78Q7Not mapped
Initial AccessT1190Exploit Public-Facing Applicationwp2shell against WordPress; Redis exposure; Magento and others. CVE is delivery only.Q14Native N2 to N5
ExecutionT1059.001PowerShellIEX stager from 42.193.227.214:8033Q1, Q2M1038, M1045, M1049, M1042, M1026
ExecutionT1047Windows Management InstrumentationWMI remote execution on compromised hostsQ9, Q10M1040, M1038, M1026, M1018
PersistenceT1543.003Create or Modify System Process: Windows ServiceUpdSvc via svc.cnaQ3, Q4, Q5M1047, M1040, M1045, M1028, M1018
PersistenceT1505.003Server Software Component: Web ShellWSO and wp2shell webshells as active WordPress pluginsQ15, Q16, Q17M1042, M1018
PersistenceT1098.004Account Manipulation: SSH Authorized KeysKey injected through rogue Redis replicationQ11, Q12, Q13M1042, M1022, M1018
PersistenceT1136.001Create Account: Local AccountRogue wp2_ plus eight hex WordPress administratorsQ17 (weak), N2Native only
Command and ControlT1071.001Application Layer Protocol: Web ProtocolsBeacon on 1002 (HTTPS) and 8044 (HTTP) to 42.193.227.214Q6, Q8Egress control (best practice)
Command and ControlT1102.002Web Service: Bidirectional CommunicationTelegram bot notification (actor side)NoneNot observable
Lateral MovementT1550.002Pass the Hashscan_pth.cna across internal segmentsNoneGap
Defense EvasionT1027Obfuscated Files or InformationWSO obfuscated with R00t-Shell.com 2.0.15Q18 (low yield)Not mapped

Technique IDs and the M-code lists for T1098.004, T1505.003, T1543.003, T1047 and T1059.001 were read from the saved MITRE snapshots (06 to 10). Other technique IDs follow the SOCRadar TTP table in snapshot 01. Rows marked best practice or native have no MITRE-listed preventive mitigation in the saved pages.

07

Native Audit-Log Hunts

The parts of the chain with no endpoint query. All checks are read-only. Run them on the web, database and Redis hosts, or through your RMM.

#CheckWhereWhat a hit means
N1Firewall, proxy and DNS logs for the eight published IPs and the port set 1002, 8033, 8044, 9995 to 42.193.227.214Perimeter / egressContact with CyberXero infrastructure from a host that may have no sensor
N2WordPress administrators matching ^wp2_[0-9a-f]{8}$ (wp-cli or SQL on wp_users, plus capability check)WordPress databaseRogue administrator created by wp2shell. Strongest single indicator in the SOCRadar report.
N3Plugin directories matching wp2shell_[0-9a-f]{8} and any file named WSO-Shell.php; active plugin list diff against your approved listWeb root file system, wp option active_pluginsDeployed webshell. Preserve the file before removal.
N4Web access logs: requests into /wp-content/plugins/wp2shell_*/, and bursts of POSTs to the REST batch route followed by a new plugin request within secondsWeb server logsWebshell use. Only the 61-second burst tempo is specific to this actor; the CVE route is covered by the separate pack.
N5Redis hosts: authorized_keys entries nobody can attribute, file modification time on ~/.ssh/authorized_keys, and INFO replication showing an unexpected masterLinux Redis serversRogue replication outcome. This is the only coverage of the Redis-side file write.
N6Windows: service named UpdSvc, event 7045 or 4697 with a PowerShell or cmd binPath, PowerShell script block events (4104) containing IEX against a bare IPWindows event logsStager and persistence on hosts with no sensor
N7Review exposed AI agent session logs and tokens if you run agents with terminal access (SOCRadar guidance)Your own agent hostsHygiene, not detection
08

Hunt Queries: CrowdStrike CQL, SentinelOne PowerQuery and Defender XDR KQL

Show all queries in
Pick your tenant's cloud first. Every "Open in Falcon" button below uses this selection.

18 queries. Windows service, process and network queries run on any sensored OS where noted; Q11 to Q13 are Linux specific, Q15 and Q16 cover both. Windows paths use FileName regexes so no path separators appear in a pattern. Event names were taken from the crowdstrike-logscale-v3 references and the linter's known-event list.

Q1 · Process command line references CyberXero infrastructure
CONF HIGHFP LOWCOST LOW

Looks for: Any process whose command line names a CyberXero IP (team server, Redis node, staging node, provisioning, scanner or workstation). The stager URL and the UpdSvc binPath both carry the team server address, so this single filter catches the stager, the service persistence and a hand-typed beacon launch. FP: None expected. The only benign hit is an analyst pasting a published IOC into a test command.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: An address written in hex, as a decimal integer or defanged is not matched.
  • PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
  • KQL – Defender XDR: An address written in hex, as a decimal integer or defanged is not matched.
  • KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: Process command line references CyberXero infrastructure (CyberXero)
// MITRE: T1059.001, T1105, T1071.001
// CONF: high  FP: low  COST: low
// REQUIRES: Process creation with command line (ProcessRollup2)
// FALSE POSITIVES: None expected: published attacker-owned addresses.
// LOOKBACK: 30d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| CommandLine=/(42\.193\.227\.214|42\.193\.100\.94|49\.234\.12\.182|46\.21\.250\.135|45\.88\.106\.2\b|45\.88\.106\.78|212\.193\.31\.189|91\.208\.184\.148)/
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
| sort(@timestamp, order=desc)
Q2 · PowerShell or cmd IEX download from a bare-IP URL with a high port
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: The stager shape, independent of the exact IP: a scripting host running IEX or DownloadString against a URL whose host is a raw IPv4 address on a non-default port. SOCRadar documents http://42.193.227.214:8033/ plus 13 lowercase alphanumerics; infrastructure rotates, the shape does not. The second regex pins the documented path shape. FP: Internal admin scripts that pull from an artifact server by IP and port. Exclude your own internal ranges and known build hosts (see the TUNING line in the query).

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A download whose URL is assembled at run time is not matched.
  • PowerQuery assumes: endpoint.os carries the value windows for Windows agents.
  • PowerQuery assumes: The URL is matched as plain text in the command line, so a URL built at run time from variables is not seen.
  • KQL – Defender XDR: A download whose URL is assembled at run time is not matched.
  • KQL – Defender XDR assumes: Windows sensors report the image name with the .exe suffix, so no separate platform predicate is needed.
  • KQL – Defender XDR assumes: The URL is matched as plain text in the command line.
// HUNT: PowerShell or cmd IEX download from a bare-IP URL with a high port (CyberXero)
// MITRE: T1059.001, T1105
// CONF: medium  FP: medium  COST: low
// REQUIRES: Process creation with command line (ProcessRollup2)
// FALSE POSITIVES: Internal artifact servers addressed by IP and port. TUNING below.
// TUNING: drop internal destinations with the commented CommandLine!=/.../ line once your artifact-server list is known; do not exclude by FileName alone
// LOOKBACK: 14d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Win
| FileName=/^(powershell|pwsh|cmd)(\.exe)?$/i
| CommandLine=/(\biex\b|invoke-expression|downloadstring|net\.webclient|invoke-webrequest|\biwr\b)/i
| CommandLine=/https?:\/\/[0-9]{1,3}(\.[0-9]{1,3}){3}:[0-9]{2,5}\b/i
// | CommandLine!=/https?:\/\/(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.)/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
Q3 · UpdSvc service created (Cobalt Strike svc.cna persistence)
CONF HIGHFP LOWCOST LOW

Looks for: The named persistence from the SOCRadar indicator table: a Windows service called UpdSvc whose binPath is a C2 IEX download. Also matches any new service whose image path contains the team server address. FP: UpdSvc is a plausible name for a vendor updater. Confirm by the ServiceImagePath: a PowerShell or cmd binPath with a URL is hostile, a vendor binary under Program Files is not.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: approximate-analyticProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A service created through an API path that writes no observed registry value is not seen.
  • PowerQuery: The CQL service-created event is not available in this schema.
  • PowerQuery assumes: registry.keyPath ends in the service name or in the service name plus the value name, and registry.value holds the data written.
  • PowerQuery assumes: Registry Value Modified events under the Services key are collected on the tenant.
  • KQL – Defender XDR: A service created through an API path that writes no observed registry value is not seen.
  • KQL – Defender XDR: The CQL service-created event has no direct Defender equivalent.
  • KQL – Defender XDR assumes: RegistryKey holds the full key path, so a service key ends in the service name.
  • KQL – Defender XDR assumes: RegistryValueSet is the ActionType recorded when a service value is written.
// HUNT: UpdSvc service created (Cobalt Strike svc.cna persistence) (CyberXero)
// MITRE: T1543.003, T1059.001
// CONF: high  FP: low  COST: low
// REQUIRES: Service creation (CreateService)
// FALSE POSITIVES: A vendor updater legitimately named UpdSvc (check ServiceImagePath).
// LOOKBACK: 30d
#event_simpleName=CreateService
| ServiceName=/^UpdSvc$/i or ServiceDisplayName=/^UpdSvc$/i or ServiceImagePath=/42\.193\.227\.214/
| table([@timestamp, aid, ComputerName, UserName, ServiceName, ServiceDisplayName, ServiceImagePath])
| sort(@timestamp, order=desc)
Q4 · Service created with a scripting-host binPath that downloads or decodes
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: The behavioral form of UpdSvc: any new service whose image path launches PowerShell, cmd, mshta or rundll32 AND carries an IEX, download, encoded-command or URL token. Survives a rename of the service. FP: Some backup, RMM and deployment tools wrap a PowerShell one-liner in a service. Exclude by the known vendor ServiceName.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: approximate-analyticProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A service created through an API path that writes no observed registry value is not seen.
  • PowerQuery: The CQL service-created event is not available in this schema.
  • PowerQuery assumes: registry.keyPath holds the key path and registry.value holds the data written.
  • PowerQuery assumes: The value is not restricted to ImagePath because the keyPath and valueName split is not verified on a tenant; the scripting-host and download predicates narrow it to the same rows in practice.
  • KQL – Defender XDR: A service created through an API path that writes no observed registry value is not seen.
  • KQL – Defender XDR: The CQL service-created event has no direct Defender equivalent.
  • KQL – Defender XDR assumes: RegistryValueSet is the ActionType recorded when a service value is written.
  • KQL – Defender XDR assumes: The value is not restricted to ImagePath; the scripting-host and download predicates narrow it to the same rows in practice.
// HUNT: Service created with a scripting-host binPath that downloads or decodes (CyberXero)
// MITRE: T1543.003, T1059.001
// CONF: medium  FP: medium  COST: low
// REQUIRES: Service creation (CreateService)
// FALSE POSITIVES: Vendor tools that wrap a PowerShell command in a service.
// TUNING: allowlist the vendor ServiceName values you find in your first run with the commented ServiceName!=/.../ line
// LOOKBACK: 30d
#event_simpleName=CreateService
| ServiceImagePath=/(powershell|pwsh|mshta|rundll32|cmd(\.exe)?\s+.c\s)/i
| ServiceImagePath=/(\biex\b|invoke-expression|downloadstring|frombase64string|-e(nc|ncodedcommand)?\s|https?:)/i
// | ServiceName!=/^(ExampleVendorAgent|ExampleBackupSvc)$/i
| table([@timestamp, aid, ComputerName, UserName, ServiceName, ServiceDisplayName, ServiceImagePath])
Q5 · Script host spawned by services.exe with a download or decode token
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: Execution side of the service persistence: services.exe is the parent, the child is a scripting host, and the command line carries an IEX, download or URL token. Pairs with Q3 and Q4, which see the creation. FP: Service wrappers from RMM and management agents. Exclude by the exact command line your vendor uses.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A service wrapper that launches the script host through an intermediate process is not matched.
  • PowerQuery assumes: endpoint.os carries the value windows for Windows agents.
  • KQL – Defender XDR: A service wrapper that launches the script host through an intermediate process is not matched.
  • KQL – Defender XDR assumes: Windows sensors report the image name with the .exe suffix, so no separate platform predicate is needed.
// HUNT: Script host spawned by services.exe with a download or decode token (CyberXero)
// MITRE: T1543.003, T1059.001
// CONF: medium  FP: medium  COST: low
// REQUIRES: Process creation with parent (ProcessRollup2)
// FALSE POSITIVES: Management-agent service wrappers.
// TUNING: exclude the exact CommandLine of approved agents; keep the URL token requirement so only downloaders remain
// LOOKBACK: 14d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Win
| ParentBaseFileName=/^services\.exe$/i
| FileName=/^(powershell|pwsh|cmd|mshta|rundll32)(\.exe)?$/i
| CommandLine=/(\biex\b|invoke-expression|downloadstring|frombase64string|https?:)/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
Q6 · Outbound connection to a published CyberXero address
CONF HIGHFP LOWCOST LOW

Looks for: Retrospective sweep of all eight CyberXero addresses on every sensored OS. Role map: 42.193.227.214 team server (1002 HTTPS beacon, 8044 HTTP staging, 8033 PowerShell stager, 9995 team server); 42.193.100.94 Redis exploitation; 49.234.12.182 staging; 46.21.250.135 workstation and open directory; 45.88.106.2 provisioning; 45.88.106.78 scanner; 212.193.31.189 payment gateway; 91.208.184.148 secondary workstation. Perishable: rotate the list as infrastructure is retired. FP: None expected.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: Traffic that never reaches the endpoint sensor, such as a connection from a device with no agent, is not seen.
  • PowerQuery assumes: dst.ip.address is the remote address of an outbound IP Connect event.
  • KQL – Defender XDR: Traffic that never reaches the endpoint sensor, such as a connection from a device with no agent, is not seen.
  • KQL – Defender XDR assumes: ConnectionSuccess, ConnectionFailed and ConnectionRequest are the outbound action types recorded on the tenant.
// HUNT: Outbound connection to a published CyberXero address (CyberXero)
// MITRE: T1071.001, T1105, T1090
// CONF: high  FP: low  COST: low
// REQUIRES: Outbound network connection with process (NetworkConnectIP4)
// FALSE POSITIVES: None expected: published attacker-owned addresses.
// LOOKBACK: 30d
#event_simpleName=NetworkConnectIP4
| in(field=RemoteAddressIP4, values=["46.21.250.135","45.88.106.2","45.88.106.78","42.193.227.214","42.193.100.94","49.234.12.182","212.193.31.189","91.208.184.148"])
| table([@timestamp, aid, ComputerName, event_platform, ContextBaseFileName, RemoteAddressIP4, RemotePort, LocalAddressIP4])
| sort(@timestamp, order=desc)
Q7 · Inbound connection accepted from a published CyberXero address
CONF MEDIUMFP LOWCOST LOW

Looks for: A sensored internet-facing host accepted a connection from the scanner (45.88.106.78), the workstation, or the Redis and staging nodes. This is where a sensored web server or Redis host shows evidence of CyberXero touching it. Scan hits alone are not compromise: follow with Q15, Q16 and Q13 on the same aid. FP: Low. A scan hit on an exposed host is expected for an internet-facing system and is context, not proof of compromise.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: approximate-analytic, equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: If the tenant does not populate the direction field the query returns nothing, which reads as a clean estate.
  • PowerQuery assumes: event.network.direction is populated and holds INCOMING for accepted inbound connections.
  • PowerQuery assumes: src.ip.address is the remote peer and dst.ip.address and dst.port.number are the local listener on an incoming event.
  • KQL – Defender XDR: If the tenant does not record InboundConnectionAccepted the query returns nothing, which reads as a clean estate.
  • KQL – Defender XDR assumes: InboundConnectionAccepted is recorded on the tenant; it is attested in Microsoft-owned hunting repositories but not listed on the table's Learn page.
// HUNT: Inbound connection accepted from a published CyberXero address (CyberXero)
// MITRE: T1595.002, T1190, T1021.004
// CONF: medium  FP: low  COST: low
// REQUIRES: Inbound accepted connection (NetworkReceiveAcceptIP4)
// FALSE POSITIVES: Scan hits against internet-facing hosts are context only.
// LOOKBACK: 30d
#event_simpleName=NetworkReceiveAcceptIP4
| in(field=RemoteAddressIP4, values=["46.21.250.135","45.88.106.2","45.88.106.78","42.193.227.214","42.193.100.94","49.234.12.182","212.193.31.189","91.208.184.148"])
| table([@timestamp, aid, ComputerName, event_platform, ContextBaseFileName, RemoteAddressIP4, LocalPort, LocalAddressIP4])
| sort(@timestamp, order=desc)
Q8 · External connection on the team server port set
CONF MEDIUMFP MEDIUMCOST MEDIUM

Looks for: Survives IP rotation if the operator keeps the same port plan: 1002 (HTTPS beacon), 8033 (stager delivery), 8044 (HTTP staging) and 9995 (team server) to a non-private address. Grouped per host, process and destination so one beacon is one row. FP: Ports 8044 and 9995 are used by legitimate products. Exclude known vendor destinations and review by process name: a browser is noise, powershell, rundll32 or an unknown binary is not.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: The link-local and carrier-grade NAT ranges are treated as external here, as they are in the CQL.
  • PowerQuery assumes: dst.port.number is numeric and holds the remote port of an outbound IP Connect event.
  • KQL – Defender XDR: RemoteIPType Public excludes link-local and carrier-grade NAT addresses, which the CQL treats as external.
  • KQL – Defender XDR assumes: RemoteIPType is Public for routable addresses and is populated on the tenant.
  • KQL – Defender XDR assumes: ConnectionSuccess, ConnectionFailed and ConnectionRequest are the outbound action types recorded on the tenant.
// HUNT: External connection on the team server port set (CyberXero)
// MITRE: T1071.001, T1571
// CONF: medium  FP: medium  COST: medium
// REQUIRES: Outbound network connection with process (NetworkConnectIP4)
// FALSE POSITIVES: Legitimate software on 8044 or 9995.
// TUNING: exclude vendor destination IPs after your first run, and rank rows whose ContextBaseFileName is a scripting host or an unsigned binary first
// LOOKBACK: 7d
#event_simpleName=NetworkConnectIP4
| in(field=RemotePort, values=["1002","8033","8044","9995"])
| !cidr(RemoteAddressIP4, subnet="10.0.0.0/8")
| !cidr(RemoteAddressIP4, subnet="172.16.0.0/12")
| !cidr(RemoteAddressIP4, subnet="192.168.0.0/16")
| !cidr(RemoteAddressIP4, subnet="127.0.0.0/8")
| groupBy([aid, ComputerName, ContextBaseFileName, RemoteAddressIP4, RemotePort], function=[count(as=conns), min(@timestamp, as=first_seen), max(@timestamp, as=last_seen)])
| sort(conns, order=desc)
Q9 · Command shell or script host spawned by WmiPrvSE.exe
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: Remote WMI execution lands as a child of WmiPrvSE.exe on the target. SOCRadar documents WMI remote execution against hosts in the Chinese Redis cluster using a blank-password account. FP: Endpoint management, inventory and monitoring agents execute through WMI. Exclude the service accounts and command lines of those tools.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A payload that runs inside the WMI provider host without creating a child process is not seen.
  • PowerQuery assumes: endpoint.os carries the value windows for Windows agents.
  • PowerQuery assumes: Windows agents report the image name with the .exe suffix.
  • KQL – Defender XDR: A payload that runs inside the WMI provider host without creating a child process is not seen.
  • KQL – Defender XDR assumes: Windows sensors report the image name with the .exe suffix, so no separate platform predicate is needed.
// HUNT: Command shell or script host spawned by WmiPrvSE.exe (CyberXero)
// MITRE: T1047
// CONF: medium  FP: medium  COST: low
// REQUIRES: Process creation with parent (ProcessRollup2)
// FALSE POSITIVES: Management and monitoring agents that run through WMI.
// TUNING: exclude your management-tool UserName values and exact CommandLine strings; treat any hit with an IEX, download or encoded token as high priority
// LOOKBACK: 14d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Win
| ParentBaseFileName=/^wmiprvse\.exe$/i
| FileName=/^(cmd|powershell|pwsh|rundll32|mshta|regsvr32|wscript|cscript|certutil|bitsadmin)(\.exe)?$/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
Q10 · WMI remote-execution initiators on the source host
CONF MEDIUMFP MEDIUMCOST MEDIUM

Looks for: Source side of the same activity: wmic with a node argument or process call create, and PowerShell WMI or CIM method calls with a remote computer name. FP: Administrators and inventory scripts use these. Exclude admin jump hosts and the service accounts that run scheduled inventory.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: Remote WMI started from a tool other than wmic or PowerShell is not matched.
  • PowerQuery assumes: endpoint.os carries the value windows for Windows agents.
  • KQL – Defender XDR: Remote WMI started from a tool other than wmic or PowerShell is not matched.
  • KQL – Defender XDR assumes: Windows sensors report the image name with the .exe suffix, so no separate platform predicate is needed.
// HUNT: WMI remote-execution initiators on the source host (CyberXero)
// MITRE: T1047
// CONF: medium  FP: medium  COST: medium
// REQUIRES: Process creation with command line (ProcessRollup2)
// FALSE POSITIVES: Admin and inventory scripts.
// TUNING: exclude the jump hosts and service accounts in your estate that legitimately run remote WMI; keep wmic process call create unexcluded
// LOOKBACK: 14d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Win
| FileName=/^(wmic|powershell|pwsh)(\.exe)?$/i
| CommandLine=/(\s.node:|process\s+call\s+create|invoke-wmimethod|invoke-cimmethod|win32_process.*(computername|cimsession))/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
Q11 · redis-cli replication or config abuse on a Linux host
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: Local redis-cli use that matches the rogue-replication family: SLAVEOF or REPLICAOF toward another node, CONFIG SET dir or dbfilename (the lever that points a Redis save at an SSH directory), and MODULE LOAD. Honest limit: the attacker's replication handshake arrives over the network and is not a process on the victim, so this sees only the local shell side. FP: Redis administrators legitimately configure replication. Exclude replica build jobs and named admin accounts.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: Commands piped to redis-cli on standard input, or sent by a client other than redis-cli, are not matched.
  • PowerQuery assumes: endpoint.os carries the value linux for Linux agents.
  • PowerQuery assumes: A command passed to redis-cli over standard input rather than the command line is not visible.
  • KQL – Defender XDR: Commands piped to redis-cli on standard input, or sent by a client other than redis-cli, are not matched.
  • KQL – Defender XDR assumes: The Linux sensor reports the image name without a suffix and fills ProcessCommandLine.
// HUNT: redis-cli replication or config abuse on a Linux host (CyberXero)
// MITRE: T1190, T1098.004, T1059.004
// CONF: medium  FP: medium  COST: low
// REQUIRES: Linux process creation with command line (ProcessRollup2)
// FALSE POSITIVES: Redis administrators building replicas.
// TUNING: exclude the admin UserName and the replication targets that are your own replicas; CONFIG SET dir pointing at a .ssh path is never legitimate
// LOOKBACK: 30d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Lin
| FileName=/^redis-cli$/
| CommandLine=/(slaveof|replicaof|config\s+set\s+(dir|dbfilename)|module\s+load)/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
Q12 · redis-server spawning a shell or downloader
CONF HIGHFP LOWCOST LOW

Looks for: A Redis server process should never start a shell, downloader or interpreter. Hits indicate module-load or similar code execution in the Redis process. Redis's own persistence children are not in the filename list. FP: Low. Custom Redis scripts that shell out are rare and should be known to the owning team.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A child started through a double fork, so that redis-server is no longer its creator, is not matched.
  • PowerQuery assumes: endpoint.os carries the value linux for Linux agents.
  • KQL – Defender XDR: A child started through a double fork, so that redis-server is no longer its creator, is not matched.
  • KQL – Defender XDR assumes: The Linux sensor reports image names without a suffix.
// HUNT: redis-server spawning a shell or downloader (CyberXero)
// MITRE: T1190, T1059.004, T1105
// CONF: high  FP: low  COST: low
// REQUIRES: Linux process creation with parent (ProcessRollup2)
// FALSE POSITIVES: Rare custom Redis integrations.
// LOOKBACK: 30d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Lin
| ParentBaseFileName=/^redis-server$/
| FileName=/^(sh|bash|dash|zsh|curl|wget|nc|ncat|python3?|perl|busybox|chmod|crontab)$/
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
Q13 · authorized_keys written or edited by a shell or file tool
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: Shell and file-tool commands that touch authorized_keys: echo or cat redirection, tee, cp, mv, sed, chattr and downloaders. Honest limit: when the write is done by redis-server itself through a Redis save, no process is created, so this query cannot see that path. Use the section 7 file sweep for it. FP: Configuration management, cloud-init and administrators add keys through these tools. Exclude by parent process and by the accounts that manage access.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: An editor such as vi or nano that writes the file is not in the tool list, as in the CQL, and a write by a process that does not name the file on its command line is not seen.
  • PowerQuery assumes: endpoint.os carries the value linux for Linux agents.
  • KQL – Defender XDR: An editor such as vi or nano that writes the file is not in the tool list, as in the CQL, and a write by a process that does not name the file on its command line is not seen.
  • KQL – Defender XDR assumes: The Linux sensor reports image names without a suffix and fills ProcessCommandLine.
// HUNT: authorized_keys written or edited by a shell or file tool (CyberXero)
// MITRE: T1098.004
// CONF: medium  FP: medium  COST: low
// REQUIRES: Linux process creation with command line (ProcessRollup2)
// FALSE POSITIVES: Configuration management and cloud-init.
// TUNING: exclude your configuration-management parents with the commented line; escalate when the writer's parent is a web server, redis-server or an interactive shell on a server that has no admin logon
// LOOKBACK: 14d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| event_platform=Lin
| CommandLine=/authorized_keys/
| FileName=/^(sh|bash|dash|zsh|tee|cp|mv|cat|echo|sed|printf|chattr|chmod|curl|wget|python3?|perl)$/
// | ParentBaseFileName!=/^(ansible.*|puppet|chef-client|salt-minion|cloud-init.*)$/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
Q14 · Inbound connection to Redis port 6379 from a public address
CONF MEDIUMFP MEDIUMCOST MEDIUM

Looks for: Redis is being reached from outside private space, which is the precondition for the rogue-replication path. Grouped per host and source so exposure is visible as a short list. FP: Intentional public Redis or a managed-service peer. The right outcome is usually a firewall change, not an alert.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: approximate-analytic, equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: If the tenant does not populate the direction field, or puts the local port on the source side, the query returns nothing, which reads as a clean estate.
  • PowerQuery assumes: event.network.direction is populated and holds INCOMING for accepted inbound connections.
  • PowerQuery assumes: dst.port.number is the local listening port on an incoming event and src.ip.address is the remote peer.
  • KQL – Defender XDR: If the tenant does not record InboundConnectionAccepted the query returns nothing, which reads as a clean estate.
  • KQL – Defender XDR: RemoteIPType Public excludes link-local and carrier-grade NAT addresses, which the CQL treats as external.
  • KQL – Defender XDR assumes: InboundConnectionAccepted is recorded on the tenant; it is attested in Microsoft-owned hunting repositories but not listed on the table's Learn page.
  • KQL – Defender XDR assumes: RemoteIPType is Public for routable addresses and is populated on the tenant.
// HUNT: Inbound connection to Redis port 6379 from a public address (CyberXero)
// MITRE: T1190, T1595.002
// CONF: medium  FP: medium  COST: medium
// REQUIRES: Inbound accepted connection (NetworkReceiveAcceptIP4)
// FALSE POSITIVES: Intentionally exposed Redis and known peers.
// TUNING: exclude the public peer addresses you expect and treat every remaining source as an exposure finding
// LOOKBACK: 7d
#event_simpleName=NetworkReceiveAcceptIP4
| LocalPort=6379
| !cidr(RemoteAddressIP4, subnet="10.0.0.0/8")
| !cidr(RemoteAddressIP4, subnet="172.16.0.0/12")
| !cidr(RemoteAddressIP4, subnet="192.168.0.0/16")
| !cidr(RemoteAddressIP4, subnet="127.0.0.0/8")
| groupBy([aid, ComputerName, RemoteAddressIP4], function=[count(as=accepts), min(@timestamp, as=first_seen), max(@timestamp, as=last_seen)])
| sort(accepts, order=desc)
Q15 · Web server worker spawning a shell or recon utility
CONF MEDIUMFP MEDIUMCOST LOW

Looks for: Webshell execution as seen from the host: Apache, nginx, PHP-FPM, PHP-CGI, LiteSpeed PHP or IIS w3wp starting a shell or a recon tool. WSO-family shells run operator commands through PHP, so the parent is the PHP or web worker. This is the strongest endpoint signal for the webshell stage on a sensored web server. FP: Some PHP applications shell out to utilities and some IIS apps call cmd. Exclude the exact application command lines you know.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A worker with a name outside the list, such as a Tomcat or Node.js server, is not covered, as in the CQL.
  • PowerQuery assumes: The creator name is reported as the bare image name, for example php-fpm8.2 or w3wp.exe.
  • KQL – Defender XDR: A worker with a name outside the list, such as a Tomcat or Node.js server, is not covered, as in the CQL.
  • KQL – Defender XDR assumes: The creator name is reported as the bare image name, for example php-fpm8.2 or w3wp.exe.
// HUNT: Web server worker spawning a shell or recon utility (CyberXero)
// MITRE: T1505.003, T1059.004, T1059.003
// CONF: medium  FP: medium  COST: low
// REQUIRES: Process creation with parent (ProcessRollup2)
// FALSE POSITIVES: PHP or IIS applications that legitimately shell out.
// TUNING: allowlist the exact CommandLine of known application helpers; keep whoami, id, uname, hostname and net/nltest recon unexcluded
// LOOKBACK: 14d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| ParentBaseFileName=/^(apache2|httpd|nginx|php-fpm[0-9.]*|php-cgi|lsphp[0-9]*|w3wp)(\.exe)?$/i
| FileName=/^(sh|bash|dash|zsh|cmd|powershell|pwsh|whoami|id|uname|hostname|curl|wget|nc|ncat|certutil|net|net1|nltest)(\.exe)?$/i
| table([@timestamp, aid, ComputerName, event_platform, UserName, ParentBaseFileName, FileName, CommandLine])
| sort(@timestamp, order=desc)
Q16 · Web worker child-process burst (machine-speed tempo)
CONF MEDIUMFP MEDIUMCOST MEDIUM

Looks for: Tempo detector for the AI-orchestrated pipeline: four or more distinct tools launched by web workers on one host inside a two-minute bucket. The reported run deployed 32 shells in 61 seconds, so human-paced shell use and agent-paced use differ sharply. Threshold is a starting point. FP: Deployment hooks and PHP applications that run several helper tools at once. Raise the threshold or exclude the deploy window.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A burst split across two windows can fall under the threshold in both.
  • PowerQuery assumes: estimate_distinct is exact at the small counts this threshold uses.
  • PowerQuery assumes: timebucket windows are aligned to the platform clock rather than to the first event, so a burst that straddles an edge can split into two windows.
  • KQL – Defender XDR: A burst split across two windows can fall under the threshold in both.
  • KQL – Defender XDR assumes: bin windows are aligned to the clock, so a burst that straddles an edge can split into two windows.
// HUNT: Web worker child-process burst (machine-speed tempo) (CyberXero)
// MITRE: T1505.003, T1059
// CONF: medium  FP: medium  COST: medium
// REQUIRES: Process creation with parent (ProcessRollup2)
// FALSE POSITIVES: Deployment hooks and chatty PHP applications.
// TUNING: raise the distinct_tools threshold on busy application hosts or exclude the nightly deploy window; investigate any host that also fired Q15
// LOOKBACK: 7d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| ParentBaseFileName=/^(apache2|httpd|nginx|php-fpm[0-9.]*|php-cgi|lsphp[0-9]*|w3wp)(\.exe)?$/i
| FileName=/^(sh|bash|dash|zsh|cmd|powershell|pwsh|whoami|id|uname|hostname|curl|wget|nc|ncat|certutil|net|net1|nltest|ls|cat|find|ps|ifconfig|ip)(\.exe)?$/i
| bucket(span=2m, field=[aid, ComputerName], function=[count(FileName, distinct=true, as=distinct_tools), count(as=children)])
| test(distinct_tools >= 4)
| sort(distinct_tools, order=desc)
Q17 · CyberXero artifact names in a command line
CONF HIGHFP LOWCOST LOW

Looks for: Command lines naming the campaign's own artifacts: a wp2shell_ plus eight hex plugin directory, a WSO-Shell.php file, or a wp2_ plus eight hex account. Hits come from responder activity, cleanup scripts, wp-cli, mysql clients or shell access to the plugin folder. Weak as a standalone detector because creation happens through the web application, not a process. It is a cheap retrospective sweep. FP: Low. Your own incident responders will match once they start cleanup.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: equivalent-with-schema-assumptionsProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: An artifact touched without appearing on any command line, for example by a web shell request, is not seen.
  • PowerQuery assumes: tgt.process.cmdline holds the full command line of the created process.
  • KQL – Defender XDR: An artifact touched without appearing on any command line, for example by a web shell request, is not seen.
  • KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: CyberXero artifact names in a command line (CyberXero)
// MITRE: T1505.003, T1136.001
// CONF: high  FP: low  COST: low
// REQUIRES: Process creation with command line (ProcessRollup2)
// FALSE POSITIVES: Responder cleanup commands.
// LOOKBACK: 30d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/
| CommandLine=/(wp2shell_[0-9a-f]{8}|WSO-Shell\.php|\bwp2_[0-9a-f]{8}\b)/i
| table([@timestamp, aid, ComputerName, UserName, FileName, CommandLine, ParentBaseFileName])
Q18 · Hash sweep of the four published CyberXero files
CONF MEDIUMFP LOWCOST LOW

Looks for: Retrospective hash sweep: stager32.bin, the obfuscated WSO-Shell.php, and the two Chinese-cluster staging payloads 1.bin and config.bin. Honest limit: .php and .bin files are not executables, so the sensor hashes them only if they run or are written as an executable type. Expect few or no hits even on an affected host, and treat a miss as no evidence. FP: None expected.

Validation: schema-aligned, static-reviewedAutomated: static-passedEquivalence: approximate-analyticProfiles: microsoft-defender-xdr, sentinelone-endpoint-ocsf
Known limitations and deployment notes
  • PowerQuery: A file that the agent hashes with SHA-1 only, or does not hash at all, is not matched.
  • PowerQuery: There is no per-format write event, so a native executable written without a create or modify event is not seen.
  • PowerQuery assumes: tgt.process.image.sha256 and tgt.file.sha256 are populated for the events of interest on the tenant.
  • KQL – Defender XDR: The process-start half of the CQL is not covered: SHA256 is often unpopulated on DeviceProcessEvents, so a file that was already on disk and then ran is missed.
  • KQL – Defender XDR: Advanced Hunting keeps 30 days; the CQL tab covers 90 days.
  • KQL – Defender XDR assumes: SHA256 is populated on DeviceFileEvents rows on the tenant.
// HUNT: Hash sweep of the four published CyberXero files (CyberXero)
// MITRE: T1105, T1505.003, T1027
// CONF: medium  FP: low  COST: low
// REQUIRES: Process, PE and ELF file telemetry with SHA-256
// FALSE POSITIVES: None expected: published attacker file hashes.
// LOOKBACK: 90d
#event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2|PeFileWritten|NewExecutableWritten|ELFFileWritten)$/
| in(field=SHA256HashData, values=["92a789444708fa1cb4cc5a89e0aa6cc7a279b62a7b8a4d2857255a18197d0090","a5ae0aab352871bc0b038b3aa43b03eb223425628c884af7b9fc592cd34eb86c","71e21094c1ac1cf0275c91ed377965e248bca1c12711f6dd20e2682681fc1192","59c535f47ab4d35f6d9fc8b8aec4a72438ea0b89e5a4dcea74b05d2d32cfa483"])
| table([@timestamp, aid, ComputerName, event_platform, FileName, SHA256HashData])
09

Detection Rules by Platform

Three queries are clean enough to promote from hunt to Custom IOA. All are detect only. The pack recommends no prevention action: every indicator traces to one originating report, and the behaviours sit on stock binaries (powershell.exe, wmic.exe, redis-cli, sshd) that must never be prevented on the strength of a name.

CrowdStrike: Custom IOA

IOA nameFromRule typePatternExclusionsAction
CyberXero, service created as UpdSvc or with team server in image pathPromote Q3Service creation (Windows)Service name ^UpdSvc$ or image path containing 42.193.227.214Vendor updater whose image path is a signed binary under Program FilesDetect: High
CyberXero, redis-server spawning a shell or downloaderPromote Q12Process Creation (Linux)Parent filename ^redis-server$ and image filename ^(sh|bash|dash|zsh|curl|wget|nc|ncat|python3?|perl|busybox|chmod|crontab)$None expectedDetect: High
CyberXero, PowerShell IEX against a CyberXero addressPromote Q1Process Creation (Windows)Command line containing 42.193.227.214 (any image)None expectedDetect: High

Pattern syntax follows the Custom IOA regular-expression fields. Confirm the exact escaping in your console, then create each rule in Monitor on a pilot policy for one business week. Not recommended as IOAs: Q2, Q4, Q5, Q8, Q9, Q10, Q13, Q14, Q15, Q16 (administrative or application noise), Q6, Q7, Q17, Q18 (indicator sweeps that belong in IOC Management and scheduled hunts).

SentinelOne: custom detection rules

RuleSource queryRun asNotes
CyberXero, service created as UpdSvc or with team server in image pathQ3, PowerQuery tabHunt only until the gap is closedQ3 is only an approximation here. SentinelOne has no service-creation event in the attested field model. The service exists as a value written under the Services registry key, so the hunt reads Registry Value Modified: a key named UpdSvc, a value equal to UpdSvc (display name), or a value naming 42.193.227.214 (image path). The CQL.... This pack's own text mentions a baseline or pilot; follow it as written
CyberXero, redis-server spawning a shell or downloaderQ12, PowerQuery tabScheduled custom detection ruleBind entities so the alert names the host instead of "Unknown Device". This pack's own text mentions a baseline or pilot; follow it as written
CyberXero, PowerShell IEX against a CyberXero addressQ1, PowerQuery tabScheduled custom detection ruleBind entities so the alert names the host instead of "Unknown Device". This pack's own text mentions a baseline or pilot; follow it as written

Create the rule with POST /web/api/v2.1/cloud-detection/rules, queryType: "scheduled" and queryLang: "2.0", with the query in data.scheduledParams.query. Use 2.0 operator spellings: a rule written with the 1.0 token ContainsCIS was accepted and never fired on a tenant. The API does not warn, so lint the body before deploying.

Microsoft Defender: custom detection rules

RuleSource queryRun asNotes
CyberXero, service created as UpdSvc or with team server in image pathQ3, KQL – Defender XDR tabHunt only until the gap is closedQ3 is only an approximation here. ServiceInstalled is recorded only when the Audit Security System Extension policy is deployed, so the hunt reads the registry write that creates the service instead: a key named UpdSvc, a value equal to UpdSvc (display name), or a value naming 42.193.227.214 (image path).. This pack's own text mentions a baseline or pilot; follow it as written
CyberXero, redis-server spawning a shell or downloaderQ12, KQL – Defender XDR tabCustom detection rule, alert only, every hourThe query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself. This pack's own text mentions a baseline or pilot; follow it as written
CyberXero, PowerShell IEX against a CyberXero addressQ1, KQL – Defender XDR tabCustom detection rule, alert only, every hourThe query returns Timestamp, ReportId and DeviceId, which Microsoft recommends for Defender for Endpoint tables so alerts carry the device group scope and the process tree. Remove the Timestamp filter and the final sort and take before saving the rule: the service applies the rule's lookback itself. This pack's own text mentions a baseline or pilot; follow it as written

Q2, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q13, Q14, Q15, Q16, Q17 and Q18 stay a hunt in this pack, not a rule. A rule can generate only 150 alerts per run. Continuous (NRT) frequency needs a single table and no comment lines, so delete the generated comment header from the query first.

10

Machine-Readable IOC Appendix

Blocks tuned to this campaign. The CSV is the only block that feeds the provenance gate: all twelve rows are atomic indicators that appear in saved snapshot 01-socradar-cyberxero.txt (the five IPs also appear in snapshot 02). The wp2_ account, wp2shell_ plugin and stager path shapes are patterns, not atomic IOCs, so they live in the behavioural block.

Falcon IOC Management CSVbulk import, detect only
type,value,action,severity,expiration,description,tags
sha256,92a789444708fa1cb4cc5a89e0aa6cc7a279b62a7b8a4d2857255a18197d0090,detect,high,2027-04-13,stager32.bin Cobalt Strike x86 stager (Pwn3rs Team 4.9.1 build),campaign:CyberXero;actor:CyberXero
sha256,a5ae0aab352871bc0b038b3aa43b03eb223425628c884af7b9fc592cd34eb86c,detect,high,2027-04-13,WSO-Shell.php WSO webshell obfuscated with R00t-Shell.com 2.0.15,campaign:CyberXero;actor:CyberXero
sha256,71e21094c1ac1cf0275c91ed377965e248bca1c12711f6dd20e2682681fc1192,detect,high,2027-04-13,1.bin Chinese-cluster staging payload,campaign:CyberXero;actor:CyberXero
sha256,59c535f47ab4d35f6d9fc8b8aec4a72438ea0b89e5a4dcea74b05d2d32cfa483,detect,high,2027-04-13,config.bin Chinese-cluster staging payload,campaign:CyberXero;actor:CyberXero
ipv4,46.21.250.135,detect,high,2027-04-13,Primary workstation and open directory seed node,campaign:CyberXero;actor:CyberXero
ipv4,45.88.106.2,detect,high,2027-04-13,Provisioning server port 1500,campaign:CyberXero;actor:CyberXero
ipv4,45.88.106.78,detect,high,2027-04-13,Mass scanning server,campaign:CyberXero;actor:CyberXero
ipv4,42.193.227.214,detect,high,2027-04-13,Cobalt Strike team server (1002 HTTPS beacon / 8044 HTTP staging / 8033 PS stager / 9995),campaign:CyberXero;actor:CyberXero
ipv4,42.193.100.94,detect,high,2027-04-13,Redis exploitation node and PentAGI agents,campaign:CyberXero;actor:CyberXero
ipv4,49.234.12.182,detect,high,2027-04-13,Staging and payload delivery (Chinese cluster),campaign:CyberXero;actor:CyberXero
ipv4,212.193.31.189,detect,high,2027-04-13,Multi-chain CryptoPay gateway,campaign:CyberXero;actor:CyberXero
ipv4,91.208.184.148,detect,high,2027-04-13,Secondary workstation,campaign:CyberXero;actor:CyberXero
Microsoft Defender indicators CSVSettings, Endpoints, Indicators, Import: audit only
indicatorType,indicatorValue,action,title,description,expirationTime,severity,recommendedActions,rbacGroups,category,mitretechniques,GenerateAlert
FileSha256,92a789444708fa1cb4cc5a89e0aa6cc7a279b62a7b8a4d2857255a18197d0090,Audit,stager32.bin Cobalt Strike x86 stager,stager32.bin Cobalt Strike x86 stager (Pwn3rs Team 4.9.1 build),2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,a5ae0aab352871bc0b038b3aa43b03eb223425628c884af7b9fc592cd34eb86c,Audit,WSO-Shell.php WSO webshell obfuscated with R00t-Shell.com 2.,WSO-Shell.php WSO webshell obfuscated with R00t-Shell.com 2.0.15,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,71e21094c1ac1cf0275c91ed377965e248bca1c12711f6dd20e2682681fc1192,Audit,1.bin Chinese-cluster staging payload,1.bin Chinese-cluster staging payload,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
FileSha256,59c535f47ab4d35f6d9fc8b8aec4a72438ea0b89e5a4dcea74b05d2d32cfa483,Audit,config.bin Chinese-cluster staging payload,config.bin Chinese-cluster staging payload,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,46.21.250.135,Audit,Primary workstation and open directory seed node,Primary workstation and open directory seed node,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,45.88.106.2,Audit,Provisioning server port 1500,Provisioning server port 1500,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,45.88.106.78,Audit,Mass scanning server,Mass scanning server,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,42.193.227.214,Audit,Cobalt Strike team server,Cobalt Strike team server (1002 HTTPS beacon / 8044 HTTP staging / 8033 PS stager / 9995),2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,42.193.100.94,Audit,Redis exploitation node and PentAGI agents,Redis exploitation node and PentAGI agents,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,49.234.12.182,Audit,Staging and payload delivery,Staging and payload delivery (Chinese cluster),2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,212.193.31.189,Audit,Multi-chain CryptoPay gateway,Multi-chain CryptoPay gateway,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True
IpAddress,91.208.184.148,Audit,Secondary workstation,Secondary workstation,2027-04-13T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True

Column names and allowed values are from Microsoft's documented parameter table. Check each expirationTime before importing: an indicator whose date has passed is already expired. Download the sample CSV from the Import page to confirm the column order before a bulk import. Each file takes at most 500 indicators. Learn describes the import per entity type, so if a mixed file is rejected, split it by indicatorType. An imported indicator does nothing unless the matching Advanced features are on (for example Custom network indicators and Allow or block file).

SentinelOne IOC importnot included

This pack does not ship a SentinelOne import block: the import format could not be verified against SentinelOne's own documentation. Export a sample from your console and the block can be added with confidence.

Behavioral Signaturesdurable, outlives the IOCs
CyberXero - behavioural signatures (survive IP and hash rotation)

B1  WordPress administrator whose login matches ^wp2_[0-9a-f]{8}$
B2  Plugin directory matching wp2shell_[0-9a-f]{8} under wp-content/plugins
B3  WSO-Shell.php registered as an active plugin
B4  Windows service UpdSvc, or any service whose binPath runs powershell/cmd with IEX or a URL
B5  PowerShell IEX download from http://<bare IPv4>:<port>/<13 lowercase alphanumerics>
B6  services.exe parenting a scripting host with a download token
B7  WmiPrvSE.exe parenting cmd/powershell, or wmic /node: from a non-admin host
B8  redis-cli SLAVEOF/REPLICAOF/CONFIG SET dir|dbfilename on a Redis host, or redis-server parenting a shell
B9  New or changed ~/.ssh/authorized_keys on a Redis host with no change ticket
B10 Web worker (apache2/httpd/nginx/php-fpm/w3wp) parenting several distinct tools within two minutes
B11 Redis 6379 reachable from non-private addresses
Named Malware / Toolingas named by the source
Named malware and tooling (names exactly as SOCRadar uses them)

wp2shell         actor's own Python package: REST batch desync, SQL injection, rogue admin, WSO webshell as plugin
WSO-Shell.php    WSO-family webshell, obfuscated with R00t-Shell.com 2.0.15
Cobalt Strike    4.9.1, unauthorized Pwn3rs Team build; svc.cna (UpdSvc) and scan_pth.cna aggressor scripts
PentAGI          open-source AI pentest framework wired to the team server through an AI provider API
Claude Code      up to 51 specialised agent definitions on the primary workstation
Telegram bot     compromise notifications (actor side)
VLESS/Xray       node layer anonymising attack traffic (actor side)

Role map: 42.193.227.214 team server (1002 HTTPS beacon, 8044 HTTP staging, 8033 PowerShell stager, 9995 team server)
          42.193.100.94 Redis exploitation node; 49.234.12.182 staging; 46.21.250.135 workstation + open directory
          45.88.106.2 provisioning (port 1500); 45.88.106.78 mass scanner; 212.193.31.189 CryptoPay; 91.208.184.148 secondary workstation
Audit Helpersread-only
# Read-only audit helpers. Run through RTR, your RMM or a local shell.

# A. Windows: UpdSvc and scripting-host services
Get-Service -Name UpdSvc -ErrorAction SilentlyContinue
Get-CimInstance Win32_Service | Where-Object { $_.PathName -match '(powershell|pwsh|mshta|rundll32)' -and $_.PathName -match '(iex|invoke-expression|downloadstring|http)' } |
  Select-Object Name, DisplayName, StartMode, PathName

# B. Linux: authorized_keys inventory (all users)
for h in /root /home/*; do f="$h/.ssh/authorized_keys"; [ -f "$f" ] && { echo "== $f"; stat -c '%y %U' "$f"; cut -c1-80 "$f"; }; done

# C. Linux: Redis exposure and replication
ss -ltnp | grep ':6379'
redis-cli INFO replication   # unexpected master_host = investigate

# D. WordPress (wp-cli): rogue administrators and plugin directories
wp user list --role=administrator --fields=ID,user_login,user_registered | grep -E 'wp2_[0-9a-f]{8}'
find wp-content/plugins -maxdepth 1 -name 'wp2shell_*' ; find . -name 'WSO-Shell.php'

Action policy: nothing in the CSV is set to prevent. The whole set originates from one report (two-source rule), the hashes belong to non-executable files in three of four cases, and the IPs are cloud-hosted and will be retired. Expiry is six months. Promote an IP to prevent only after an independent vendor lists it.

11

Detection Validation Gates

Work these in order. A query that has not cleared gate 2 has no business being an alert.

GateWhat to proveHowPass criteria
G1 · Telemetry readyThe events each query depends on arrive in your tenantRun each filter alone over 24h with count(): process creation with parent and command line (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents), service creation (CrowdStrike: CreateService; outside endpoint telemetry on SentinelOne and Defender, use event 7045), outbound connection with process, inbound accepted connection. Confirm Linux sensors are on the web and Redis hosts.Non-zero counts on Windows and Linux hosts; every missing source recorded as a gap
G2 · Benign baselineNoise level before alertingRun Q2, Q4, Q5, Q8, Q9, Q10, Q13, Q14, Q15 and Q16 over 14 days and tabulate hits by process, parent and accountMedium-FP queries explained by a short, named exclusion list; low-FP queries return zero or are explained one by one
G3 · Positive testDetections fire on safe stand-insIn a lab, create a service named UpdSvc with a harmless binPath; run a PowerShell command line containing a documentation-range bare IP and port with an IEX token; run redis-cli CONFIG SET dir on a throwaway Redis; start a shell from a test PHP script. No real attacker infrastructure is contacted.Q3, Q2, Q11 and Q15 each return the lab event
G4 · Negative testKnown-good activity stays quietRun an approved RMM install, an Ansible key push, and a normal PHP page that calls a helperQ4, Q13 and Q15 either stay quiet or are covered by a documented exclusion
G5 · PromotionMove to Custom IOA in Monitor modePromote Q1, Q3 and Q12 on a pilot policy for one weekNo unexplained detections; owner assigned
G6 · Response readinessSomeone can act on a hitWalk section 14 with the owning web, database and Windows teamsIsolation path and credential-rotation owner agreed
12

Hardening: Tiered

Each control is mapped to the technique, then to a MITRE mitigation (the why, read from the saved pages) and a vendor or best-practice authority (the what and where). Where no formal benchmark exists the control says so. Verification for each is given in the playbook (section 13).

Immediate (this week, low compatibility risk)
  • I1 · Take Redis off the internet. Bind to loopback or a private interface, keep protected mode on, require authentication or ACLs, and firewall 6379. T1098.004 and T1190. M1042 and M1018 (MITRE T1098.004). Authority: Redis security documentation (snapshot 11). Playbook P1.
  • I2 · Neutralise the Redis lever. Rename or disable CONFIG and the replication commands through rename-command or ACLs, and run Redis as an unprivileged user that cannot write any user's .ssh directory. M1042, M1022. Authority: Redis security documentation. Playbook P1.
  • I3 · Lock down authorized_keys. Point sshd at a root-owned key directory so a service account cannot plant a key, set restrictive modes, and audit writes. M1022, M1018 (T1098.004). ⚠ best-practice, no formal benchmark saved in this pack. Playbook P2.
  • I4 · WordPress write-surface reduction. DISALLOW_FILE_EDIT, strict file permissions, no write for the web user on plugin directories where operations allow, delete unused plugins. M1042, M1018 (T1505.003). Authority: WordPress Hardening handbook (snapshot 12). DISALLOW_FILE_MODS is a documented core constant but is not in the saved page (⚠ verify against the handbook). Playbook P3.
  • I5 · Run the rogue-admin and plugin audits now. Section 7 N2, N3 and N5. Playbook P6.
Near term (1 to 4 weeks, pilot first)
  • N1 · PowerShell visibility and constraint. Enable script block and module logging, move servers toward Constrained Language Mode with WDAC/AppLocker where a baseline exists. T1059.001. M1038, M1045, M1049, M1042, M1026 (MITRE T1059.001). Authority: Microsoft Learn about_Logging_Windows (snapshot 13). Playbook P4.
  • N2 · Service creation auditing. Alert on event 7045 and 4697 with scripting-host binPaths. T1543.003. M1047 Audit, M1018, M1028 (MITRE T1543.003). Playbook P5.
  • N3 · Remote WMI restriction. Limit inbound WMI and DCOM to management hosts; pilot the ASR rule that blocks process creation from PSExec and WMI commands in audit mode. T1047. M1040, M1038, M1026, M1018 (MITRE T1047). The ASR rule GUID is from Microsoft documentation not saved in this pack (⚠ verify the GUID before deploying). Playbook P4.
  • N4 · Server egress control. Default-deny outbound from web and Redis servers with an allow list; block the team server port set to non-approved destinations. T1071.001. ⚠ best-practice, no formal benchmark saved in this pack.
  • N5 · Apply the vendor fix for the WordPress core and plugin flaws used as delivery, and for Support Board, Magento and PrestaShop where present. Follow the separate CVE pack's guidance rather than duplicating it here.
Strategic (1 to 3 months)
  • S1 · Segment the web tier. Web servers must not reach internal Windows hosts or the Redis tier except on named ports. Limits the Cobalt Strike pivot and WMI lateral movement. ⚠ best-practice, no formal benchmark saved in this pack.
  • S2 · Application allow-listing on servers (WDAC or AppLocker) so a scripting host launched by services.exe or a web worker cannot run arbitrary content. M1038 (T1059.001, T1047).
  • S3 · External attack-surface monitoring. Continuously find internet-reachable Redis and unpatched WordPress and e-commerce estates, the same way the actor's scanner does.
  • S4 · Treat AI agent session logs as credential-grade data. SOCRadar's guidance: retain, encrypt and restrict them like credential logs or keystores. Relevant only if you run agents with terminal or network access.
13

Deployable Playbooks

Test every playbook on a pilot host first. P5 and P6 are read-only. Each playbook lists its prerequisites, reboot requirement and rollback. Example paths and the REPLACE_WITH_ secret are placeholders for you to set.

P1 · Redis hardening (I1, I2)

# P1 · Redis: private bind, authentication, no CONFIG, unprivileged (I1, I2)
# Prerequisites: root on the Redis host; a client inventory so you do not break legitimate callers; Redis 6 or later for ACL.
# Reboot required: no (restart the redis service)
# Rollback: restore the saved copy: cp /etc/redis/redis.conf.pre-hardening /etc/redis/redis.conf ; systemctl restart redis

cp /etc/redis/redis.conf /etc/redis/redis.conf.pre-hardening
# edit /etc/redis/redis.conf
bind 127.0.0.1 -::1            # or the private interface address only
protected-mode yes
requirepass REPLACE_WITH_LONG_RANDOM_SECRET
rename-command CONFIG ""
rename-command SLAVEOF ""
rename-command REPLICAOF ""
rename-command MODULE ""
# if replicas are required, use ACLs for the replication user instead of leaving REPLICAOF open
systemctl restart redis
# verify
ss -ltn | grep 6379                     # must not show 0.0.0.0:6379 or [::]:6379
redis-cli -a "$REDIS_PASSWORD" CONFIG GET dir   # expected: unknown command
# network: allow tcp/6379 only from named client addresses, drop everything else

P2 · sshd root-owned keys and auditing (I3)

# P2 · sshd: root-owned authorized keys and write auditing (I3)
# Prerequisites: root; every account that needs key login has a key file staged in the new directory first.
# Reboot required: no (reload sshd). Test a second session before closing the first.
# Rollback: remove the AuthorizedKeysFile line (default ~/.ssh/authorized_keys returns); systemctl reload sshd; remove the audit rule file

install -d -m 755 -o root -g root /etc/ssh/authorized_keys
# for each user: install -m 644 -o root -g root <key file> /etc/ssh/authorized_keys/<user>
# in /etc/ssh/sshd_config:
AuthorizedKeysFile /etc/ssh/authorized_keys/%u
systemctl reload sshd

# audit writes to any user key file (auditd)
cat > /etc/audit/rules.d/authkeys.rules <<'EOF'
-w /etc/ssh/authorized_keys -p wa -k authkeys
-w /root/.ssh/authorized_keys -p wa -k authkeys
EOF
augenrules --load
# verify
sshd -T | grep -i authorizedkeysfile
auditctl -l | grep authkeys

P3 · WordPress write-surface reduction (I4)

# P3 · WordPress: reduce the write surface (I4)
# Prerequisites: shell on the web host; a staging copy; know which plugin updates are done by hand or by CI.
# Reboot required: no
# Rollback: remove the added define() lines from wp-config.php; restore modes from the saved listing: setfacl --restore=/root/wp-perms.acl -R (or re-apply the previous chmod/chown)

getfacl -R /var/www/html > /root/wp-perms.acl 2>/dev/null     # save current state (path is an example)
# wp-config.php
define( 'DISALLOW_FILE_EDIT', true );
# optional, blocks plugin and theme install and update from the dashboard; updates then run from CI or wp-cli:
define( 'DISALLOW_FILE_MODS', true );

# permissions per the WordPress handbook (example path; adjust to your layout)
find /var/www/html -type d -exec chmod 755 {} \;
find /var/www/html -type f -exec chmod 644 {} \;
chmod 640 /var/www/html/wp-config.php
# remove inactive plugins, then verify
wp plugin list --status=inactive
wp plugin delete <inactive-plugin-slug>
wp user list --role=administrator --fields=user_login,user_registered

P4 · PowerShell logging and ASR audit (N1, N3)

# P4 · Windows: PowerShell logging, and ASR rule for PSExec/WMI process creation in audit mode (N1, N3)
# Prerequisites: Windows PowerShell 5.1 or 7 on test hosts; local admin; Defender Antivirus active for the ASR step; SIEM able to receive 4104.
# Reboot required: no
# Rollback: delete the policy keys (Remove-Item) and run Remove-MpPreference -AttackSurfaceReductionRules_Ids d1e49aac-8f56-4280-b9ba-993a6d77406c

New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Force | Out-Null
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Name EnableScriptBlockLogging -Value 1 -Type DWord
New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging' -Force | Out-Null
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging' -Name EnableModuleLogging -Value 1 -Type DWord

# ASR: block process creations from PSExec and WMI commands, AUDIT first (verify the GUID against Microsoft Learn)
Add-MpPreference -AttackSurfaceReductionRules_Ids d1e49aac-8f56-4280-b9ba-993a6d77406c -AttackSurfaceReductionRules_Actions AuditMode
# verify
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104} -MaxEvents 3
(Get-MpPreference).AttackSurfaceReductionRules_Ids
# note: audit-mode results land in the Defender operational log; endpoint-management and SCCM use WMI, so review before moving to Block

P5 · Service-creation review (N2)

# P5 · Windows: alert on suspicious service creation (N2), read-only query plus a forwarding hint
# Prerequisites: System log retention; PowerShell 5.1+; optionally a WEF/SIEM subscription for event 7045.
# Reboot required: no
# Rollback: none required (read-only)

Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045; StartTime=(Get-Date).AddDays(-30)} |
  Where-Object { $_.Message -match '(UpdSvc|powershell|pwsh|mshta|rundll32)' } |
  Select-Object TimeCreated, @{n='Detail';e={$_.Message -replace '\s+',' '}}
# Security log 4697 (service installed) needs 'Audit Security System Extension' enabled:
auditpol /get /subcategory:"Security System Extension"

P6 · Rogue-admin and webshell audit (I5)

# P6 · Rogue-admin and webshell audit across WordPress hosts (I5), read-only
# Prerequisites: wp-cli and shell access on each WordPress host; run from the WordPress root.
# Reboot required: no
# Rollback: none required (read-only). Do not delete a hit until its files are preserved for forensics.

wp user list --role=administrator --field=user_login | grep -E '^wp2_[0-9a-f]{8}$'
wp plugin list --status=active --fields=name,version | grep -E '^wp2shell_[0-9a-f]{8}'
find wp-content/plugins -maxdepth 1 -type d -name 'wp2shell_*' -printf '%TY-%Tm-%Td %p\n'
find . -type f -name 'WSO-Shell.php' -printf '%TY-%Tm-%Td %p\n'
# Redis hosts
for h in /root /home/*; do f="$h/.ssh/authorized_keys"; [ -f "$f" ] && stat -c '%y %n' "$f"; done
14

Containment Runbook

Sequencing rule: CyberXero is a broker. Assume any access it obtained has been or will be sold, so removing the shell is not closure. Rotate every credential stored on or reachable from a compromised web or Redis host, and treat the database as exfiltrated.

PhaseActionsOwnerEvidence to capture
C0 · Triage
0 to 15 min
Identify which query fired, the host and the account. Check whether Q1, Q3, Q6, Q12 and Q15 also fired on the same aid. Confirm whether the host is internet-facing and what it can reach.SOC L1Falcon process tree; query output; host role
Isolate
15 to 60 min
Network-contain the host with the EDR isolation action. Block the eight published IPs and the port set at the egress firewall as a temporary measure (attacker-owned, cloud-hosted). Take the WordPress site offline or behind maintenance if a rogue admin or webshell is confirmed.SOC L2 / networkIsolation confirmation; firewall change record
Isolate: by platformCrowdStrike: network-contain the host. SentinelOne: network quarantine (Disconnect from Network; confirm the label in your console version). Microsoft Defender: Isolate device (full network isolation).SOC L2 / networkIsolation confirmation; firewall change record
PreserveImage the web root, the plugin directory, authorized_keys, shell history and web logs before cleanup. Capture memory on Windows hosts that ran the stager.IRHashes and copies; chain of custody
Eradicate (Windows)Stop and delete UpdSvc and any scripting-host service. Remove the beacon, scheduled tasks and WMI subscriptions found. Rebuild the host if a team server session was established.IR / endpointService export; registry hive copy
Eradicate (Linux and web)Remove rogue wp2_ administrators, wp2shell_ plugin directories and WSO-Shell.php. Remove unattributed authorized_keys entries and rotate host keys if the key was in place. Re-image the Redis host if the process spawned children. Patch and apply P1 to P3 before returning to service.Web / platformList of removed accounts, files and keys
RotateRotate WordPress salts, database credentials, application secrets, SSH keys, API tokens and any payment-gateway credentials on the host. Reset all WordPress administrator passwords and force re-authentication.Platform / IAMRotation log
RecoverReturn to service only after the full section 7 sweep is clean. Monitor Q1, Q3, Q6, Q12, Q15 and Q17 at a short interval for 30 days. Assess personal-data notification duties if customer data was reachable.Service owner / legalSign-off record
15

Detection Coverage Map

TechniqueBehaviorCQLIOAHardeningCrowdStrike coverageSentinelOneDefender XDR
T1059.001PowerShell IEX stager from the team serverQ1, Q2Promote Q1N1, S2GOOD Strong on sensored Windows hostsGood, with assumptionsGood, with assumptions
T1543.003UpdSvc and scripting-host servicesQ3, Q4, Q5Promote Q3N2GOOD Service creation is outside endpoint telemetry on some platformsPartial: Q3 approximate, Q4 approximatePartial: Q3 approximate, Q4 approximate
T1071.001Beacon and staging to published IPs and portsQ6, Q7, Q8NoN4PARTIAL Perishable IPs; port plan may change; no domain indicators publishedPartial: Q7 approximatePartial: same limit as CrowdStrike
T1047WMI remote executionQ9, Q10NoN3PARTIAL Only the process side; no WMI event-subscription telemetry in this packPartial: same limit as CrowdStrikePartial: same limit as CrowdStrike
T1098.004SSH key injection through RedisQ11, Q12, Q13Promote Q12I2, I3PARTIAL The Redis save that writes the key creates no process: native N5 onlyPartial: same limit as CrowdStrikePartial: same limit as CrowdStrike
T1190Exposed RedisQ14NoI1PARTIAL Intent unknowable; exposure finding, not proofPartial: Q14 approximatePartial: same limit as CrowdStrike
T1505.003Webshell command execution on sensored web serversQ15, Q16, Q17NoI4PARTIAL Webshell file write and request path are outside endpoint telemetryPartial: same limit as CrowdStrikePartial: same limit as CrowdStrike
T1136.001Rogue wp2_ administratorsQ17NoI5GAP Account creation is a database write through the web app; native N2 onlyGAP: same limit as CrowdStrikeGAP: same limit as CrowdStrike
T1190 / T1595.002Mass WordPress scanning and panel compromiseQ7NoN5GAP Web-server and database log territory; sensors see neither the HTTP request nor the SQLGAP: same limit as CrowdStrikeGAP: same limit as CrowdStrike
T1550.002Pass-the-hash via scan_pth.cnaNoneNoS1GAP Not covered; the source names the script onlyGAPGAP
T1102.002Telegram bot notificationNoneNoNoneGAP Actor-sideGAPGAP
T1105 / T1027Published file hashesQ18NoNonePARTIAL Most published files are not executables; expect few hitsPartial: Q18 approximatePartial: Q18 approximate

Validation gates (summary): telemetry ready (G1), benign baseline (G2), positive test (G3), negative test (G4), Monitor-mode promotion (G5), response readiness (G6). Full table in section 11.

Honest scope: this pack cannot see the mass WordPress compromise, the SQL injection, the rogue-administrator database write, the file write of the webshell, the Redis-side write to authorized_keys, pass-the-hash, or anything on the actor's side. It detects what the actor does on hosts you have sensors on: the stager, the service, WMI, shell and Redis process activity, webshell-spawned commands, and contact with published infrastructure. Hosts with no sensor depend on the section 7 native checks and on egress logs.

16

Hunt Summary Ticket

TITLE:      CyberXero: AI-augmented initial access broker (Cobalt Strike, Redis, WordPress webshells)
SEVERITY:   High. SOCRadar report 2026-10-06; active at publication; Ukrainian energy and utilities plus global WordPress and e-commerce
SCOPE:      Sensored Windows hosts (stager, UpdSvc, WMI), sensored Linux web and Redis servers, and egress logs for unsensored hosts.

HYPOTHESIS: A host ran a PowerShell IEX stager against a CyberXero team server, persisted as a UpdSvc service, moved by WMI; or a web or
            Redis server was breached, given a wp2shell_ plugin or an injected SSH key, and operated at machine pace.

QUERIES:
            Q1  Process command line references CyberXero infrastructure       CONF high   | FP low    | COST low
            Q2  PowerShell or cmd IEX download from a bare-IP URL with a high port CONF medium | FP medium | COST low
            Q3  UpdSvc service created (Cobalt Strike svc.cna persistence)     CONF high   | FP low    | COST low
            Q4  Service created with a scripting-host binPath that downloads or decodes CONF medium | FP medium | COST low
            Q5  Script host spawned by services.exe with a download or decode token CONF medium | FP medium | COST low
            Q6  Outbound connection to a published CyberXero address           CONF high   | FP low    | COST low
            Q7  Inbound connection accepted from a published CyberXero address CONF medium | FP low    | COST low
            Q8  External connection on the team server port set                CONF medium | FP medium | COST medium
            Q9  Command shell or script host spawned by WmiPrvSE.exe           CONF medium | FP medium | COST low
            Q10 WMI remote-execution initiators on the source host             CONF medium | FP medium | COST medium
            Q11 redis-cli replication or config abuse on a Linux host          CONF medium | FP medium | COST low
            Q12 redis-server spawning a shell or downloader                    CONF high   | FP low    | COST low
            Q13 authorized_keys written or edited by a shell or file tool      CONF medium | FP medium | COST low
            Q14 Inbound connection to Redis port 6379 from a public address    CONF medium | FP medium | COST medium
            Q15 Web server worker spawning a shell or recon utility            CONF medium | FP medium | COST low
            Q16 Web worker child-process burst (machine-speed tempo)           CONF medium | FP medium | COST medium
            Q17 CyberXero artifact names in a command line                     CONF high   | FP low    | COST low
            Q18 Hash sweep of the four published CyberXero files               CONF medium | FP low    | COST low

DO FIRST:   1. Q1, Q3, Q6, Q12, Q17 across 30 days (near-zero FP)
            2. Q15 and Q16 on every sensored web server; Q14 to find public Redis
            3. Section 7 native checks N2, N3, N5 (rogue admins, plugin dirs, authorized_keys)
            4. Apply I1 and I2 (Redis) and I4 (WordPress) hardening

FINDINGS:   [ ] Q1 hits: ______    [ ] Q3 hits: ______    [ ] Q6 hits: ______    [ ] Q12 hits: ______
            [ ] Q15/Q16 hits: ______    [ ] Rogue wp2_ admins: ______    [ ] Unattributed authorized_keys: ______
            [ ] Hosts with 2+ query hits in 24h (auto-escalate): ______

GAPS:       - Mass WordPress scanning, SQL injection, rogue-admin DB write: outside endpoint telemetry
            - Redis save that writes authorized_keys creates no process; only native N5 sees it
            - Pass-the-hash (scan_pth.cna) has no query
            - Telegram, VLESS/Xray, session logs: actor side
            - Service creation is a cross-platform gap outside the CrowdStrike sensor
            - All indicators single-originated at SOCRadar; nothing ships at prevent

ACTIONS:    [ ] Promote Q1, Q3, Q12 to Custom IOA (Monitor mode, pilot policy, 1 week)
            [ ] Import the section 10 CSV into IOC Management (detect, 6 month expiry)
            [ ] Deploy Immediate hardening I1 to I5
            [ ] Confirm Linux sensors on web and Redis hosts (gate G1)

OWNER:      ______________________
VERSION:    v0.1 - 2026-10-13
17

Changelog

v0.1 2026-10-13 Initial draft. Built from the SOCRadar CyberXero report (2026-10-06) with four secondary articles as narrative corroboration, and MITRE ATT&CK, Redis, WordPress and Microsoft Learn pages for mapping and hardening. 18 CQL hunt queries, 12 atomic indicators (all detect), 3 Custom IOA promotions. Record count taken from the source (564,073 heating-provider records) rather than the task brief figure. SentinelOne PowerQuery and Microsoft Defender KQL tabs added to Q1-Q18: SIEM Query Rosetta release 0.1.0 (public-beta; static-reviewed translations).
18

References