MythicRatatoskr: Yggdrasil-Hidden Backdoor and the Sandworm SDelete Wiping Stage
Executive Summary
ESET Research (published 2026-10-22) documents an intrusion at a Ukrainian grain logistics company in which UAC-0099 gained initial access on 2025-07-16 with a spearphishing attachment, then deployed a previously undocumented Go backdoor, MythicRatatoskr, on 2025-07-17. Access was later handed to Sandworm, which carried out a data-wiping attack on 2025-09-17 by deploying the Sysinternals SDelete utility through Active Directory Group Policy. ESET attributes the early stage to UAC-0099 and the wiping stage to Sandworm, both with high confidence, and says it could not determine which group operated the backdoor.
MythicRatatoskr is notable for hiding its command-and-control server inside the Yggdrasil mesh network. It is built on the yggstack and yggdrasil-go libraries, connects to three randomly chosen peers from 32 hardcoded public Yggdrasil peers, and talks to a C&C reachable only as a Yggdrasil IPv6 address over HTTPS on port 443. It runs as a Windows service named ieupdate, keeps an AES-encrypted configuration in a dot-prefixed file, and supports shell, file transfer, screenshots, port exposure and a reverse SOCKS5 proxy. A separate Go SOCKS5 server, bindProxy, listens on 127.0.0.1:33690.
What this pack hunts. Because the C&C address lives inside the mesh, ordinary C&C blocking does not work. ESET says blocking the public peers is a viable mitigation, so this pack hunts the visible underlay (peer connections, service and file artifacts, the loopback listener, shell children) and the destructive stage (SDelete, especially one command line fanning out across many hosts). MATCHBOIL and MATCHWOK appear only as the documented delivery chain of this intrusion. They are covered in depth by the separate UAC-0099 pack and are not rebuilt here.
Defender priority: run Query 1 (the ieupdate service), Query 4 (ESET SHA-1 hashes) and Query 9 (port 33690) across 30 days now, then Query 12 for any SDelete fan-out. Block the 32 public Yggdrasil peers at egress and DNS. A wiping stage that follows a quiet backdoor by two months means a MythicRatatoskr hit should be treated as a pre-destructive intrusion: protect offline backups and the accounts that can edit Group Policy before anything else.
Source Review & Web Hunter Notes
| Tier | Source | Key Finding | Carry Forward |
|---|---|---|---|
| 1 | ESET Research, "MythicRatatoskr: An Yggdrasil-enabled backdoor deployed in a UAC-0099-Sandworm collaboration" (2026-10-22) | Primary analysis: timeline, host artifacts, configuration, commands, network protocol, bindProxy, ATT&CK table, hashes, C&C address, 32-peer list, SDelete via Group Policy | Yes (snapshot 01) |
| 1 | ESET malware-ioc repository, mythicratatoskr folder (README) | Hash table and C&C address. Same vendor as the article, so it is NOT an independent second source. One SHA-1 differs from the article by a single character | Yes (snapshot 02) |
| 2 | The Record from Recorded Future News, "Russian hackers teamed up to wipe data at Ukrainian grain firm" (2026-10-21) | Independent reporting of the UAC-0099 to Sandworm handoff, the backdoor capabilities and ESET quotes. No hashes or hosts | Partial (snapshot 03) |
| 2 | The Next Web, "ESET says Russia-linked hackers hid malware traffic in Yggdrasil network" | Independent corroboration of dates (2025-07-16, 2025-09-17), SDelete wiping and the Yggdrasil abuse. Says SDelete was distributed "through the company's own network settings"; does not name Group Policy | Partial (snapshot 04) |
Web-hunter decisions
- Second sourcing. Independent coverage (The Record, The Next Web) confirms the story but publishes no atomic indicators. Every hash, the C&C address and both domains therefore rest on ESET alone, and all ship at
detect. No indicator ships atprevent. The Group Policy delivery of SDelete is likewise ESET-only; The Next Web only says "network settings". - SHA-1 discrepancy. The article lists the last ieupdate.exe hash ending
...996F1629D682...; the ESET GitHub file lists...996F1429D682.... One is almost certainly a typo. Both are shipped and searched, and the spelling is labelled in the CSV. Re-check against ESET before relying on either. - C&C address. The article body gives the full address with the 201: prefix; its IoC table and the GitHub file drop the prefix. The body form is shipped (it is a valid 200::/7 address and matches the configuration table).
- Not carried forward. Pages that tried to instruct this research: none observed. The GlobeNewswire press release returned Access Denied and is not cited. The lead hints about a Linux variant are kept as a labelled possibility only: ESET found indications, no sample.
- Scope control. The library already carries a UAC-0099 pack (LUNCHPOKE, MATCHBOIL, Notepad++). This pack imports only the two delivery-chain indicators ESET ties to this intrusion (uztickets.com, egyptanimals.com) and three host artifacts (pdfopentask, temporarydoc.txt, UpdateMonitor).
Hunt Brief & Attack Chain
| Step | What happens (source) | Telemetry (plain terms, then platforms) | Hunt angle |
|---|---|---|---|
| 1 Initial access | Spearphishing email with malicious attachment, 2025-07-16 (ESET) | Mail gateway logs (outside endpoint telemetry); process creation with parent (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | Q13 |
| 2 Execution | Scheduled task pdfopentask runs PowerShell from %temp%\temporarydoc.txt; MATCHBOIL deploys MATCHWOK (C&C uztickets[.]com, fetched from egyptanimals[.]com) | Scheduled task creation (CrowdStrike: ScheduledTaskRegistered. SentinelOne: Task Register, confirm on tenant. Defender: DeviceEvents ScheduledTaskCreated); DNS lookup (CrowdStrike: DnsRequest. SentinelOne: DNS Resolved. Defender: DeviceEvents, confirm the DNS action type) | Q13, Q14 |
| 3 Persistence (chain) | MATCHWOK persisted as HKCU Run value UpdateMonitor | Registry autostart write (CrowdStrike: AsepValueUpdate. SentinelOne: Registry Value Modified. Defender: DeviceRegistryEvents) | Q13 |
| 4 Backdoor deploy | A day later (2025-07-17) MythicRatatoskr is delivered; runs as a Windows service named ieupdate, some samples sleep 10 minutes first | Executable written (CrowdStrike: PeFileWritten, NewExecutableWritten. SentinelOne: File Creation. Defender: DeviceFileEvents); service creation (CrowdStrike: CreateService. Services are a cross-platform gap on SentinelOne; Defender needs registry route) | Q1, Q2, Q3, Q4 |
| 5 C&C | Joins Yggdrasil via 3 of 32 hardcoded public peers, then JSON HTTPS POSTs (checkin, tasking, result, getfile) to the mesh C&C on 443; beacon 5m | Outbound connection (CrowdStrike: NetworkConnectIP4, NetworkConnectIP6. SentinelOne: IP Connect. Defender: DeviceNetworkEvents); DNS lookup | Q5, Q6, Q7, Q8 |
| 6 Operator actions | shell via cmd.exe, ls/cd/pwd, upload/download, screenshot, expose, reverse SOCKS5 proxy to the C&C on 8080 | Process creation with parent and command line; screen capture and in-process file reads are not visible (outside endpoint telemetry) | Q10 (shell only); gap for the rest |
| 7 Proxy and lateral | bindProxy SOCKS5 on 127.0.0.1:33690; implants pushed to other hosts through an OpenSSH SFTP server | Listening socket (CrowdStrike: NetworkListenIP4); process creation | Q9, Q15 |
| 8 Handoff and wipe | Sandworm deploys SDelete through Active Directory Group Policy, 2025-09-17 | Process creation with parent and command line; Group Policy edits are domain-controller directory and SYSVOL events (outside endpoint telemetry) | Q11, Q12; native hunts 3 to 5 |
Hunt hypotheses (ordered by fidelity)
- H1 (high). A host runs a service named ieupdate, or a binary matching an ESET hash, from one of the observed install paths. Q1, Q2, Q3, Q4.
- H2 (high). A process listens on 33690 or a masquerade-named process opens external connections. Q8, Q9.
- H3 (high). A masquerade-named service binary spawns cmd.exe, or a command line touches .updatecache or .crond. Q10.
- H4 (high). One SDelete command line runs on five or more hosts in a short window (Group Policy distribution). Q12, with Q11 for single-host review.
- H5 (medium). Hosts connect to or resolve the hardcoded public Yggdrasil peers. Q5, Q6, Q7.
- H6 (medium). The delivery-chain artifacts for this intrusion are present, or an OpenSSH SFTP server appears on a host with no SSH role. Q13, Q14, Q15.
Consolidated IOC Table
| Type | Value | Confidence | Action | Context |
|---|---|---|---|---|
| SHA-1 | D5F9288DAEBF87AE4579945F8DC6CF235B093CFD | High | detect | MythicRatatoskr backdoor (Act64.exe) |
| SHA-1 | B69EF0E45B401440C0FDE22046775D0C57E87415 | High | detect | MythicRatatoskr backdoor (ie.exe) |
| SHA-1 | 4E3E6577866E4CE2ED73CA089700AE04230E768F | High | detect | MythicRatatoskr backdoor (ieupdate.exe) |
| SHA-1 | 69969EEB7E0A3D84C4E70193636FCF934C6AA388 | High | detect | MythicRatatoskr backdoor (ieupdate.exe) |
| SHA-1 | 01855153CA7A33AD5FF36451DE5612DFBA0DD2CA | High | detect | MythicRatatoskr backdoor (krbtman.exe) |
| SHA-1 | E29AF83A07FB32EB47C28733A9382E766D53F704 | High | detect | MythicRatatoskr backdoor (OneDriveLiveUpdater.exe) |
| SHA-1 | 028CA11F3F0D8396043AF7BF756231FC2F50F829 | High | detect | MythicRatatoskr backdoor (windowsdefendersvc.exe) |
| SHA-1 | 9085896989947C0919A660352F75F6B233FC645B | High | detect | MythicRatatoskr backdoor (windowsdefendersvc.exe) |
| SHA-1 | D7E6A5A46C6ED3510997E91B11E51BE0250FD2A2 | High | detect | MythicRatatoskr backdoor (updater.exe) |
| SHA-1 | 131A371A1E4EE78EC3B2863607C99290EC3B58A6 | High | detect | bindProxy SOCKS5 server (krbtman.exe) |
| SHA-1 | 09C816697C0C2AFF9B4FF58681558CA30D04C9CD | High | detect | bindProxy SOCKS5 server (nbtresolver.exe) |
| SHA-1 | 8CEB5F8BCDF4995B7164996F1629D682613BB17B | High | detect | MythicRatatoskr backdoor (ieupdate.exe). Article spelling |
| SHA-1 | 8CEB5F8BCDF4995B7164996F1429D682613BB17B | Medium | detect | ieupdate.exe as spelled in the ESET GitHub file (one character differs from the article) |
| IPv6 | 201:b479:2771:8df4:b5eb:d007:63b0:2838 | High | detect | MythicRatatoskr C&C inside Yggdrasil; HTTPS 443, reverse proxy 8080. First seen 2025-07-17 |
| Domain | uztickets[.]com | High | detect | MATCHWOK C&C in this intrusion (delivery chain) |
| Domain | egyptanimals[.]com | Medium | detect | MATCHWOK fetched from /animals/photoalbum; likely abused third-party site |
| IPv4 / host | 31 public Yggdrasil peers (10 IPs, 21 hostnames) listed in the appendix | Medium | hunt | Legitimate community nodes. Block at egress and review hits; not malware IOCs |
| Port | TCP 33690 on 127.0.0.1 | High | hunt | bindProxy SOCKS5 listener (Q9) |
| Port | TCP 443 and 8080 to the C&C | Medium | enrich | Mesh-internal; endpoint sees only the underlay |
| Service | ieupdate | High | hunt | MythicRatatoskr service name (Q1) |
No indicator reaches prevent. The ESET article and the ESET GitHub file are one vendor, and press coverage publishes no atomic values, so no atomic IOC has two independent sources. OneDriveLiveUpdater.exe, windowsdefendersvc.exe and krbtman.exe are masquerade names, and krbtman.exe is the backdoor on some hosts and the SOCKS5 server on others, so identify by hash and path, never by name alone. SDelete is a legitimate signed Sysinternals tool and is deliberately absent from the IOC list.
Affected Surface & Telemetry Matrix
| Surface | Telemetry (plain terms, then platforms) | Priority | Gap risk |
|---|---|---|---|
| Windows endpoints and servers (service, file, process) | Process creation with command line, path, parent and SHA-1 (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents); service creation (CrowdStrike: CreateService); executable written (CrowdStrike: PeFileWritten, NewExecutableWritten) | Critical | Service creation is a cross-platform gap on SentinelOne and needs the registry route on Defender |
| Network egress | Outbound connection with owning process (CrowdStrike: NetworkConnectIP4, NetworkConnectIP6. SentinelOne: IP Connect. Defender: DeviceNetworkEvents); listening socket (CrowdStrike: NetworkListenIP4); DNS lookup (CrowdStrike: DnsRequest) | High | Overlay C&C traffic is inside the user-space mesh stack; only the underlay peer connections are visible |
| Active Directory and Group Policy | Directory Service Changes events (5136) and SYSVOL file writes on domain controllers; process creation on endpoints for the GPO-launched SDelete | Critical | GPO edits are outside endpoint telemetry unless a sensor runs on the domain controller and logs the edit; use native hunts 3 to 5 |
| File system (hidden config) | .updatecache and .crond are plain files with no dedicated file-write event for arbitrary names | Medium | Outside endpoint telemetry for creation; hunt by file inventory (native hunt 6) and by command lines (Q10) |
| Screen capture and in-memory file reads | screenshot and download commands run inside the backdoor process | Medium | No telemetry; infer from the surrounding C&C and process behavior |
| Linux or Unix hosts | ESET found hints of a Linux variant (.crond, /tmp/.test_config); no sample | Low | Unsampled; no query is written for it |
ATT&CK Mapping
| Tactic | Technique | Observed behavior | Query or control |
|---|---|---|---|
| Initial Access | T1566.001 Spearphishing Attachment | Malicious attachment, 2025-07-16 (ESET table) | Q13; ASR M1049/M1040 |
| Execution | T1059.003 Windows Command Shell | shell command via cmd.exe (ESET table) | Q10 |
| Execution | T1053.005 Scheduled Task (analyst-mapped) | Task pdfopentask runs PowerShell from temporarydoc.txt | Q13 |
| Persistence | T1543.003 Windows Service | Service ieupdate; updater.exe and WindowsDefenderSvc.exe started as services (ESET table) | Q1, Q3 |
| Persistence | T1547.001 Registry Run Keys (analyst-mapped) | MATCHWOK persisted as HKCU Run value UpdateMonitor | Q13 |
| Defense Evasion | T1036.005 Match Legitimate Name or Location (analyst-mapped) | Defender, OneDrive and Internet Explorer lookalike filenames | Q2, Q3, Q8 |
| Defense Evasion | T1027.013 Encrypted/Encoded File | AES-256-CFB configuration file (ESET table) | Q10 (command lines) |
| Defense Evasion | T1678 Delay Execution | 10-minute start delay in some samples (ESET table) | Behavioral note; widen windows |
| Collection | T1113 Screen Capture | screenshot command (ESET table) | Gap |
| Collection | T1005 Data from Local System | ls and download (ESET table) | Gap |
| Command and Control | T1090.001 Internal Proxy | bindProxy SOCKS5 on 127.0.0.1:33690 (ESET table) | Q9 |
| Command and Control | T1090.003 Multi-hop Proxy | C&C inside the Yggdrasil mesh (ESET table) | Q5, Q6, Q7, Q8 |
| Command and Control | T1573 Encrypted Channel | End-to-end protected Yggdrasil traffic (ESET table) | Q5, Q7 |
| Command and Control | T1105 Ingress Tool Transfer | SOCKS5 server probably delivered via the backdoor (ESET table) | Q2, Q15 |
| Command and Control | T1071.001 Web Protocols | HTTPS to the C&C (ESET table) | Q8 |
| Command and Control | T1132.001 Standard Encoding | Base64-encoded results (ESET table) | Gap |
| Lateral Movement | T1021.004 SSH / T1570 Lateral Tool Transfer (analyst-mapped) | OpenSSH SFTP server used to push samples | Q15 |
| Exfiltration | T1041 Exfiltration Over C2 Channel | File and screenshot exfiltration over the C&C (ESET table) | Gap (mesh-internal) |
| Privilege / Defense Evasion | T1484.001 Group Policy Modification (analyst-mapped) | SDelete deployed through Active Directory Group Policy | Q11, Q12; native hunts 3 to 5 |
| Impact | T1485 Data Destruction | SDelete data-wiping on 2025-09-17 (ESET table) | Q11, Q12 |
Rows marked "ESET table" come from the ATT&CK table in the primary report (ATT&CK v19). Rows marked "analyst-mapped" are this pack's mapping of behavior ESET describes in prose and are not in ESET's table.
Native Audit-Log Hunts
| # | Check | Where | What to look for |
|---|---|---|---|
| 1 | Service installs | Windows System log 7045; Security 4697 (needs Audit Security System Extension) | Service name ieupdate; images windowsdefendersvc.exe, updater.exe in System32, krbtman.exe, OneDriveLiveUpdater.exe |
| 2 | Scheduled task creation | Security 4698; Microsoft-Windows-TaskScheduler/Operational 106 | Task pdfopentask; PowerShell reading temporarydoc.txt |
| 3 | Group Policy object changes | Domain controller Security 5136 (groupPolicyContainer, gPCFileSysPath, versionNumber) and 5137 | Edits outside change windows; new immediate scheduled task or startup script that references sdelete |
| 4 | SYSVOL content | File listing of SYSVOL\<domain>\Policies for ScheduledTasks.xml, scripts and Registry.pol modified near the wipe time | Newly written ScheduledTasks.xml, .bat or .ps1 files that launch sdelete.exe or sdelete64.exe |
| 5 | Group Policy client log | Microsoft-Windows-GroupPolicy/Operational on a sample of endpoints | Which GPO was applied just before SDelete ran |
| 6 | Hidden config file inventory | PowerShell: Get-ChildItem C:\Windows\Temp,C:\Windows\System32,$env:LOCALAPPDATA\Temp -Force -Filter .* -ErrorAction SilentlyContinue | Where-Object { $_.Name -in ".updatecache",".crond" } | Presence of .updatecache or .crond (encrypted JSON config, first 16 bytes are the IV) |
| 7 | Sysmon (if deployed) | EID 1 process create, EID 3 network connect, EID 11 file create, EID 12/13 registry | Same artifacts as Q1 to Q10; EID 11 fills the config-file creation gap that Falcon lacks |
| 8 | Firewall, proxy and NetFlow | Egress logs | Long-lived TLS to the 31 hardcoded peers on odd ports (for example 61995, 54232, 39575, 65534) from servers or service accounts |
| 9 | OpenSSH on Windows | Microsoft-Windows-OpenSSH/Operational; sshd service state | Inbound SFTP sessions to hosts with no sanctioned SSH role, followed by new executables |
Hunt Queries: CrowdStrike CQL, SentinelOne PowerQuery and Defender XDR KQL
Use your tenant's own address. SentinelOne does not document a link that pre-fills a query, so each "Copy & open SentinelOne" button copies the query and opens this console: paste it into PowerQuery.
Pick your portal. Microsoft documents a Share link in advanced hunting but not its URL format, so each "Copy & open Defender" button copies the query and opens Advanced hunting: paste it into the editor.
Looks for: A Windows service named ieupdate, or a service whose image is ieupdate.exe, windowsdefendersvc.exe, krbtman.exe, OneDriveLiveUpdater.exe, nbtresolver.exe, or updater.exe in System32. ESET reports MythicRatatoskr starts as a Windows service named ieupdate, and updater.exe and WindowsDefenderSvc.exe were started as services.
Known limitations and deployment notes
- PowerQuery: A service created through a path that does not write ImagePath to the registry on the monitored host is not seen. The CQL's service display name and service name fields have no separate column here.
- PowerQuery assumes: A new service shows up as a write of its ImagePath value, and registry.keyPath ends at the service key or at the value name.
- PowerQuery assumes: registry.value holds the service image path as written.
- KQL – Defender XDR: A service created without a recorded ImagePath registry write is not seen. The CQL's service display name has no separate column here.
- KQL – Defender XDR assumes: RegistryKey ends at the service key name for an ImagePath write.
- KQL – Defender XDR assumes: RegistryValueData holds the service image path as written.
// HUNT: MythicRatatoskr service persistence (ieupdate) // MITRE: T1543.003, T1036.005 // CONF: high FP: low COST: low | REQUIRES: service creation telemetry (CreateService) // LOOKBACK: 30d (set with the time picker) #event_simpleName=CreateService | ServiceName=/^ieupdate$/i or ServiceImagePath=/\\(ieupdate|windowsdefendersvc|krbtman|onedriveliveupdater|nbtresolver)\.exe/i or ServiceImagePath=/\\windows\\system32\\updater\.exe/i | table([@timestamp, aid, ComputerName, UserName, ServiceName, ServiceDisplayName, ServiceImagePath]) | sort(@timestamp, order=desc)
5 required fields · View requirements
Required telemetry
- Registry Value Modified
Required fields
event.time: Event timeevent.type: Event typeregistry.keyPath: Registry key pathregistry.valueName: Registry value nameregistry.value: Registry value data
Recommended fields
endpoint.name: Hostsrc.process.name: Writing process
Readiness test
event.type = 'Registry Value Modified' registry.keyPath = * | limit 5 | columns event.time, event.type, registry.keyPath, registry.valueName, registry.value
// HUNT: MythicRatatoskr service persistence (ieupdate) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1543.003, T1036.005 // CONF: high | FP: low // EQUIVALENCE: approximate-analytic - SentinelOne lists no service-creation event type, so the hunt reads the registry write that creates the service: the ImagePath value under the Services key. It tests the same two things as the CQL, a service named ieupdate and a service image with a masquerade name. // REQUIRES: SentinelOne endpoint registry telemetry (Registry Value Modified events) // TUNING: Baseline legitimate vendor updaters that register a service named updater under System32 before alerting. // LOOKBACK: 30d; set with the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A service created through a path that does not write ImagePath to the registry on the monitored host is not seen. The CQL's service display name and service name fields have no separate column here. // VALIDATION LEVEL: static-reviewed event.type = 'Registry Value Modified' registry.valueName = 'ImagePath' registry.keyPath contains 'Services' (registry.keyPath matches '\\\\Services\\\\ieupdate(\\\\|$)' or registry.value matches '\\\\(ieupdate|windowsdefendersvc|krbtman|onedriveliveupdater|nbtresolver)\\.exe' or registry.value matches '\\\\windows\\\\system32\\\\updater\\.exe') | columns event.time, endpoint.name, src.process.user, registry.keyPath, registry.value, src.process.name | sort -event.time | limit 200
Automated validation: static-passed
5 required fields · View requirements
Required telemetry
- DeviceRegistryEvents
Required fields
Timestamp: Event timeActionType: ActionRegistryKey: Registry keyRegistryValueName: Registry value nameRegistryValueData: Registry value data
Recommended fields
InitiatingProcessFileName: Writing process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceRegistryEvents | where Timestamp > ago(1d) | project Timestamp, ActionType, RegistryKey, RegistryValueName, RegistryValueData | take 5
// HUNT: MythicRatatoskr service persistence (ieupdate) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1543.003, T1036.005 // CONF: high | FP: low // EQUIVALENCE: approximate-analytic - Defender records a service creation as a registry write, so the hunt reads the ImagePath value under the Services key rather than a service-creation event. It tests the same two things as the CQL, a service named ieupdate and a service image with a masquerade name. // REQUIRES: Defender for Endpoint registry telemetry (DeviceRegistryEvents) // TUNING: Baseline legitimate vendor updaters that register a service named updater under System32 before alerting. // LOOKBACK: 30d // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A service created without a recorded ImagePath registry write is not seen. The CQL's service display name has no separate column here. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceRegistryEvents | where Timestamp >= ago(30d) | where ActionType == "RegistryValueSet" | where RegistryValueName =~ "ImagePath" | where RegistryKey matches regex @"(?i)\\Services\\ieupdate$" or RegistryValueData matches regex @"(?i)\\(ieupdate|windowsdefendersvc|krbtman|onedriveliveupdater|nbtresolver)\.exe" or RegistryValueData matches regex @"(?i)\\windows\\system32\\updater\.exe" | project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessAccountName, RegistryKey, RegistryValueData, InitiatingProcessFileName | sort by Timestamp desc | take 200
Looks for: Executable writes whose full path matches an install location ESET observed: System32 updater.exe, krbtman.exe or windowsdefendersvc.exe, the OneDrive folder OneDriveLiveUpdater.exe, the ADOMD.NET folder applicationasphost.exe, C:\OFFICE2010\Utilities\Act64.exe, Downloads and Internet Explorer ieupdate.exe, and the SMBCache nbtresolver.exe. FP: Path-bound, so a legitimate updater.exe elsewhere does not match. The noisiest branches are ie.exe and updater.exe in user-writable folders. Baseline 14 days and drop a branch only after proving it benign.
Known limitations and deployment notes
- PowerQuery: The CQL fires only on executable (PE) writes; this query matches on the path alone, so a non-PE file of the same name also matches.
- PowerQuery assumes: tgt.file.path holds the full path of the written file.
- PowerQuery assumes: The regex is case-insensitive by default, which reproduces the CQL /i intent.
- PowerQuery assumes: File Modification is included so a binary overwritten in place is seen; the CQL's sensor events cover executable writes only.
- KQL – Defender XDR: The CQL fires only on executable (PE) writes; this query matches on the path alone, so a non-PE file of the same name also matches.
- KQL – Defender XDR assumes: FolderPath contains the install directory, with or without the file name appended.
- KQL – Defender XDR assumes: contains is case-insensitive, which reproduces the CQL /i intent.
- KQL – Defender XDR assumes: The directory test is a substring, so a deeper subfolder of the same name also matches.
// HUNT: MythicRatatoskr and bindProxy binaries written to observed install paths // MITRE: T1036.005, T1105 // CONF: high FP: medium COST: low | REQUIRES: executable write telemetry (PeFileWritten, NewExecutableWritten) // TUNING: baseline 14 days. If a software-distribution tool legitimately stages an updater.exe, exclude that writer with a ContextBaseFileName filter. Drop the Downloads ie.exe branch first if it is noisy. // LOOKBACK: 30d (set with the time picker) #event_simpleName=/^(PeFileWritten|NewExecutableWritten)$/ | TargetFileName=/(\\windows\\system32\\(updater|krbtman|windowsdefendersvc)\.exe|\\microsoft\\onedrive\\onedriveliveupdater\.exe|\\microsoft\.net\\adomd\.net\\110\\applicationasphost\.exe|\\office2010\\utilities\\act64\.exe|\\downloads\\(windowsdefendersvc|ieupdate|ie|krbtman)\.exe|\\internet explorer\\ieupdate\.exe|\\appdata\\local\\ieupdate\.exe|\\smbcache\\nbtresolver\.exe)$/i | table([@timestamp, aid, ComputerName, UserName, TargetFileName, ContextBaseFileName, SHA256HashData]) | sort(@timestamp, order=desc)
3 required fields · View requirements
Required telemetry
- File Creation
- File Modification
Required fields
event.time: Event timeevent.type: Event typetgt.file.path: Written file path
Recommended fields
endpoint.name: Hostsrc.process.name: Writing process
Optional fields
tgt.file.sha256: File hash. Population on file events varies by tenant.
Readiness test
event.type = 'File Creation' tgt.file.path = * | limit 5 | columns event.time, event.type, tgt.file.path
// HUNT: MythicRatatoskr and bindProxy binaries written to observed install paths
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1036.005, T1105
// CONF: high | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same file-write predicate: the full path must end in one of the observed masquerade binaries under its observed install directory. The writer is src.process.* because this is not a process-creation event. The CQL's PE-write sensor events become File Creation and File Modification.
// REQUIRES: SentinelOne endpoint file telemetry (File Creation and File Modification events)
// TUNING: Baseline 14 days. If a software-distribution tool legitimately stages an updater.exe, exclude that writer with a src.process.name filter. Drop the Downloads ie.exe branch first if it is noisy.
// LOOKBACK: 30d; set with the console time picker
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The CQL fires only on executable (PE) writes; this query matches on the path alone, so a non-PE file of the same name also matches.
// VALIDATION LEVEL: static-reviewed
event.type in ('File Creation', 'File Modification') tgt.file.path matches '(\\\\windows\\\\system32\\\\(updater|krbtman|windowsdefendersvc)\\.exe|\\\\microsoft\\\\onedrive\\\\onedriveliveupdater\\.exe|\\\\microsoft\\.net\\\\adomd\\.net\\\\110\\\\applicationasphost\\.exe|\\\\office2010\\\\utilities\\\\act64\\.exe|\\\\downloads\\\\(windowsdefendersvc|ieupdate|ie|krbtman)\\.exe|\\\\internet explorer\\\\ieupdate\\.exe|\\\\appdata\\\\local\\\\ieupdate\\.exe|\\\\smbcache\\\\nbtresolver\\.exe)$'
| columns event.time, endpoint.name, src.process.user, tgt.file.path, src.process.name, tgt.file.sha256
| sort -event.time
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceFileEvents
Required fields
Timestamp: Event timeActionType: ActionFolderPath: File folderFileName: File name
Recommended fields
InitiatingProcessFileName: Writing process
Optional fields
SHA256: Hash. SHA256 is often unpopulated; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceFileEvents | where Timestamp > ago(1d) | project Timestamp, ActionType, FolderPath, FileName | take 5
// HUNT: MythicRatatoskr and bindProxy binaries written to observed install paths
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1036.005, T1105
// CONF: high | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same file-write predicate: a masquerade file name under its observed install directory. The directory and the name are tested separately because FolderPath may or may not include the file name. The CQL's PE-write sensor events become FileCreated and FileModified.
// REQUIRES: Defender for Endpoint file telemetry (DeviceFileEvents)
// TUNING: Baseline 14 days. If a software-distribution tool legitimately stages an updater.exe, exclude that writer by InitiatingProcessFileName. Drop the Downloads ie.exe branch first if it is noisy.
// LOOKBACK: 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The CQL fires only on executable (PE) writes; this query matches on the path alone, so a non-PE file of the same name also matches.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceFileEvents
| where Timestamp >= ago(30d)
| where ActionType in ("FileCreated", "FileModified")
| where (FolderPath contains @"\windows\system32" and FileName in~ ("updater.exe", "krbtman.exe", "windowsdefendersvc.exe"))
or (FolderPath contains @"\microsoft\onedrive" and FileName =~ "onedriveliveupdater.exe")
or (FolderPath contains @"\microsoft.net\adomd.net\110" and FileName =~ "applicationasphost.exe")
or (FolderPath contains @"\office2010\utilities" and FileName =~ "act64.exe")
or (FolderPath contains @"\downloads" and FileName in~ ("windowsdefendersvc.exe", "ieupdate.exe", "ie.exe", "krbtman.exe"))
or (FolderPath contains @"\internet explorer" and FileName =~ "ieupdate.exe")
or (FolderPath contains @"\appdata\local" and FileName =~ "ieupdate.exe")
or (FolderPath contains @"\smbcache" and FileName =~ "nbtresolver.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessAccountName, FolderPath, FileName, InitiatingProcessFileName, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: Process creation whose image path is one of the install locations in Query 2. This is the execution-side twin of the file-write query and catches hosts where the write predates retention. FP: Same path-bound design as Query 2. A legitimate software update agent literally named updater.exe in System32 would match; none ships with Windows.
Known limitations and deployment notes
- PowerQuery: A process the sensor did not observe starting is not captured.
- PowerQuery assumes: tgt.process.image.path holds the full image path of the new process.
- PowerQuery assumes: The regex is case-insensitive by default, which reproduces the CQL /i intent.
- PowerQuery assumes: tgt.process.image.sha1 and tgt.process.image.sha256 are populated on this tenant's process events.
- KQL – Defender XDR: A process the sensor did not observe starting is not captured.
- KQL – Defender XDR assumes: FolderPath contains the install directory, with or without the file name appended.
- KQL – Defender XDR assumes: contains is case-insensitive, which reproduces the CQL /i intent.
- KQL – Defender XDR assumes: The directory test is a substring, so a deeper subfolder of the same name also matches.
// HUNT: MythicRatatoskr and bindProxy process execution from observed install paths // MITRE: T1036.005, T1543.003 // CONF: high FP: medium COST: low | REQUIRES: process creation with image path (ProcessRollup2) // TUNING: baseline 14 days. Exclude a sanctioned updater by SHA256HashData allowlist, not by name, because the attackers reuse common names. // LOOKBACK: 30d (set with the time picker) #event_simpleName=ProcessRollup2 | ImageFileName=/(\\windows\\system32\\(updater|krbtman|windowsdefendersvc)\.exe|\\microsoft\\onedrive\\onedriveliveupdater\.exe|\\microsoft\.net\\adomd\.net\\110\\applicationasphost\.exe|\\office2010\\utilities\\act64\.exe|\\downloads\\(windowsdefendersvc|ieupdate|ie|krbtman)\.exe|\\internet explorer\\ieupdate\.exe|\\appdata\\local\\ieupdate\.exe|\\smbcache\\nbtresolver\.exe)$/i | table([@timestamp, aid, ComputerName, UserName, ImageFileName, ParentBaseFileName, CommandLine, SHA1HashData, SHA256HashData]) | sort(@timestamp, order=desc)
3 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.image.path: Created process image path
Recommended fields
endpoint.name: Hostsrc.process.name: Creator processtgt.process.cmdline: Created command line
Optional fields
tgt.process.image.sha1: Created process SHA-1. Population on a given tenant is worth a readiness test.
Readiness test
event.type = 'Process Creation' tgt.process.image.path = * | limit 5 | columns event.time, event.type, tgt.process.image.path
// HUNT: MythicRatatoskr and bindProxy process execution from observed install paths // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1036.005, T1543.003 // CONF: high | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the new process image path must end in one of the observed masquerade binaries under its observed install directory. The image is tgt.process.* because this is a Process Creation event and src.process.* is the creator. // REQUIRES: SentinelOne endpoint process-creation telemetry (Process Creation events) // TUNING: Baseline 14 days. Exclude a sanctioned updater by tgt.process.image.sha1 allowlist, not by name, because the attackers reuse common names. // LOOKBACK: 30d; set with the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A process the sensor did not observe starting is not captured. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.image.path matches '(\\\\windows\\\\system32\\\\(updater|krbtman|windowsdefendersvc)\\.exe|\\\\microsoft\\\\onedrive\\\\onedriveliveupdater\\.exe|\\\\microsoft\\.net\\\\adomd\\.net\\\\110\\\\applicationasphost\\.exe|\\\\office2010\\\\utilities\\\\act64\\.exe|\\\\downloads\\\\(windowsdefendersvc|ieupdate|ie|krbtman)\\.exe|\\\\internet explorer\\\\ieupdate\\.exe|\\\\appdata\\\\local\\\\ieupdate\\.exe|\\\\smbcache\\\\nbtresolver\\.exe)$' | columns event.time, endpoint.name, src.process.user, tgt.process.image.path, src.process.name, tgt.process.cmdline, tgt.process.image.sha1, tgt.process.image.sha256 | sort -event.time | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFolderPath: Created process folderFileName: Created process name
Recommended fields
InitiatingProcessFileName: Initiating processProcessCommandLine: Created command line
Optional fields
SHA1: Hash. SHA256 is often unpopulated in DeviceProcessEvents; SHA1 is the safer pivot.
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FolderPath, FileName | take 5
// HUNT: MythicRatatoskr and bindProxy process execution from observed install paths
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1036.005, T1543.003
// CONF: high | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a masquerade image name under its observed install directory. The directory and the name are tested separately because FolderPath may or may not include the file name. The parent is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Baseline 14 days. Exclude a sanctioned updater by SHA1 allowlist, not by name, because the attackers reuse common names.
// LOOKBACK: 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A process the sensor did not observe starting is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where (FolderPath contains @"\windows\system32" and FileName in~ ("updater.exe", "krbtman.exe", "windowsdefendersvc.exe"))
or (FolderPath contains @"\microsoft\onedrive" and FileName =~ "onedriveliveupdater.exe")
or (FolderPath contains @"\microsoft.net\adomd.net\110" and FileName =~ "applicationasphost.exe")
or (FolderPath contains @"\office2010\utilities" and FileName =~ "act64.exe")
or (FolderPath contains @"\downloads" and FileName in~ ("windowsdefendersvc.exe", "ieupdate.exe", "ie.exe", "krbtman.exe"))
or (FolderPath contains @"\internet explorer" and FileName =~ "ieupdate.exe")
or (FolderPath contains @"\appdata\local" and FileName =~ "ieupdate.exe")
or (FolderPath contains @"\smbcache" and FileName =~ "nbtresolver.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FolderPath, FileName, InitiatingProcessFileName, ProcessCommandLine, SHA1, SHA256
| sort by Timestamp desc
| take 200Looks for: Any executed process whose SHA-1 equals one of the 11 hashes ESET publishes for MythicRatatoskr and the two SOCKS5 server samples, plus both spellings of the last ieupdate.exe hash (the ESET article and the ESET GitHub file differ by one character, so both are searched).
Known limitations and deployment notes
- PowerQuery: An empty result is only meaningful if the readiness test shows tgt.process.image.sha1 populated; an unpopulated hash field returns nothing.
- PowerQuery assumes: tgt.process.image.sha1 is populated on this tenant's process-creation events.
- KQL – Defender XDR: An empty result is only meaningful if the readiness test shows SHA1 populated.
- KQL – Defender XDR assumes: SHA1 is populated on DeviceProcessEvents rows for this tenant.
// HUNT: MythicRatatoskr and bindProxy SHA-1 match (ESET) // MITRE: T1543.003, T1090.001 // CONF: high FP: low COST: low | REQUIRES: process creation with SHA-1 (ProcessRollup2) // NOTE: krbtman.exe is MythicRatatoskr on some hosts and the SOCKS5 server on others. Read SHA1HashData to tell them apart. // LOOKBACK: 30d (set with the time picker) #event_simpleName=ProcessRollup2 | SHA1HashData=/^(D5F9288DAEBF87AE4579945F8DC6CF235B093CFD|B69EF0E45B401440C0FDE22046775D0C57E87415|4E3E6577866E4CE2ED73CA089700AE04230E768F|69969EEB7E0A3D84C4E70193636FCF934C6AA388|01855153CA7A33AD5FF36451DE5612DFBA0DD2CA|E29AF83A07FB32EB47C28733A9382E766D53F704|028CA11F3F0D8396043AF7BF756231FC2F50F829|9085896989947C0919A660352F75F6B233FC645B|D7E6A5A46C6ED3510997E91B11E51BE0250FD2A2|131A371A1E4EE78EC3B2863607C99290EC3B58A6|09C816697C0C2AFF9B4FF58681558CA30D04C9CD|8CEB5F8BCDF4995B7164996F1629D682613BB17B|8CEB5F8BCDF4995B7164996F1429D682613BB17B)$/i | table([@timestamp, aid, ComputerName, UserName, FileName, ImageFileName, SHA1HashData, ParentBaseFileName, CommandLine]) | sort(@timestamp, order=desc)
3 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.image.sha1: Created process SHA-1
Recommended fields
endpoint.name: Hosttgt.process.name: Created process namesrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.image.sha1 = * | limit 5 | columns event.time, event.type, tgt.process.image.sha1
// HUNT: MythicRatatoskr and bindProxy SHA-1 match (ESET)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1543.003, T1090.001
// CONF: high | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the SHA-1 of the new process image is one of the 13 ESET-published values. in:anycase reproduces the CQL /i match on the hex digits.
// REQUIRES: SentinelOne endpoint process-creation telemetry with the image SHA-1 populated
// TUNING: krbtman.exe is MythicRatatoskr on some hosts and the SOCKS5 server on others; read tgt.process.image.sha1 to tell them apart.
// LOOKBACK: 30d; set with the console time picker
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: An empty result is only meaningful if the readiness test shows tgt.process.image.sha1 populated; an unpopulated hash field returns nothing.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' tgt.process.image.sha1 in:anycase ('D5F9288DAEBF87AE4579945F8DC6CF235B093CFD', 'B69EF0E45B401440C0FDE22046775D0C57E87415', '4E3E6577866E4CE2ED73CA089700AE04230E768F', '69969EEB7E0A3D84C4E70193636FCF934C6AA388', '01855153CA7A33AD5FF36451DE5612DFBA0DD2CA', 'E29AF83A07FB32EB47C28733A9382E766D53F704', '028CA11F3F0D8396043AF7BF756231FC2F50F829', '9085896989947C0919A660352F75F6B233FC645B', 'D7E6A5A46C6ED3510997E91B11E51BE0250FD2A2', '131A371A1E4EE78EC3B2863607C99290EC3B58A6', '09C816697C0C2AFF9B4FF58681558CA30D04C9CD', '8CEB5F8BCDF4995B7164996F1629D682613BB17B', '8CEB5F8BCDF4995B7164996F1429D682613BB17B')
| columns event.time, endpoint.name, src.process.user, tgt.process.name, tgt.process.image.path, tgt.process.image.sha1, src.process.name, tgt.process.cmdline
| sort -event.time
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeSHA1: Created process SHA-1
Recommended fields
FileName: Created process nameInitiatingProcessFileName: Initiating process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, SHA1 | take 5
// HUNT: MythicRatatoskr and bindProxy SHA-1 match (ESET)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1543.003, T1090.001
// CONF: high | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the SHA-1 of the created process is one of the 13 ESET-published values. in~ reproduces the CQL /i match on the hex digits. SHA1 is used because SHA256 is often unpopulated.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) with SHA1 populated
// TUNING: krbtman.exe is MythicRatatoskr on some hosts and the SOCKS5 server on others; read SHA1 to tell them apart.
// LOOKBACK: 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: An empty result is only meaningful if the readiness test shows SHA1 populated.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where SHA1 in~ ("D5F9288DAEBF87AE4579945F8DC6CF235B093CFD", "B69EF0E45B401440C0FDE22046775D0C57E87415", "4E3E6577866E4CE2ED73CA089700AE04230E768F", "69969EEB7E0A3D84C4E70193636FCF934C6AA388", "01855153CA7A33AD5FF36451DE5612DFBA0DD2CA", "E29AF83A07FB32EB47C28733A9382E766D53F704", "028CA11F3F0D8396043AF7BF756231FC2F50F829", "9085896989947C0919A660352F75F6B233FC645B", "D7E6A5A46C6ED3510997E91B11E51BE0250FD2A2", "131A371A1E4EE78EC3B2863607C99290EC3B58A6", "09C816697C0C2AFF9B4FF58681558CA30D04C9CD", "8CEB5F8BCDF4995B7164996F1629D682613BB17B", "8CEB5F8BCDF4995B7164996F1429D682613BB17B")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FileName, FolderPath, SHA1, InitiatingProcessFileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: IPv4 connections to the ten raw-IP public peers in the list embedded in every ESET-analysed sample. ESET states blocking the public peers is a viable mitigation, because the C&C itself sits inside the mesh and is not reachable as an ordinary address. FP: These are public community Yggdrasil nodes. Any user or lab that legitimately runs Yggdrasil will match. Treat a hit as a lead and pivot to the connecting process (Query 8) before acting.
Known limitations and deployment notes
- PowerQuery: A peer reached only over the IPv6 overlay is not seen here; Query 7 covers that range.
- PowerQuery assumes: IP Connect events carry the remote address in dst.ip.address and the connecting process in src.process.name.
- PowerQuery assumes: Inbound and outbound connections are both counted; the CQL's event is outbound connections.
- KQL – Defender XDR: A peer reached only over the IPv6 overlay is not seen here; Query 7 covers that range.
- KQL – Defender XDR assumes: All ActionType values are counted, including failed connection attempts; the CQL's event is established outbound connections.
// HUNT: Connections to MythicRatatoskr hardcoded public Yggdrasil peers (IPv4) // MITRE: T1090.003, T1573 // CONF: medium FP: medium COST: low | REQUIRES: outbound network connection telemetry (NetworkConnectIP4) // TUNING: exclude hosts on an approved Yggdrasil or mesh-networking allowlist. A service-hosted binary in System32 or a user profile that connects here is the high-value case. // LOOKBACK: 14d (set with the time picker) #event_simpleName=NetworkConnectIP4 | in(RemoteAddressIP4, values=["37.205.14.171", "109.176.250.101", "65.21.57.122", "95.217.35.92", "51.255.223.60", "51.15.204.214", "62.210.85.80", "23.137.249.65", "78.27.153.163", "193.93.119.42"]) | groupBy([aid, ComputerName, ContextBaseFileName, RemoteAddressIP4, RemotePort], function=[count(as=conns), min(@timestamp, as=firstSeen), max(@timestamp, as=lastSeen)]) | sort(conns, order=desc)
6 required fields · View requirements
Required telemetry
- IP Connect
Required fields
event.time: Event timeevent.type: Event typedst.ip.address: Remote addressdst.port.number: Remote portendpoint.name: Hostsrc.process.name: Connecting process
Readiness test
event.type = 'IP Connect' dst.ip.address = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.name, dst.ip.address, dst.port.number
// HUNT: Connections to MythicRatatoskr hardcoded public Yggdrasil peers (IPv4)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1090.003, T1573
// CONF: medium | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same connection predicate: the remote address is one of the 10 hardcoded Yggdrasil peers, grouped by host, process and peer with a count and first and last seen. The connecting process is src.process.* because this is not a process-creation event.
// REQUIRES: SentinelOne endpoint network telemetry (IP Connect events)
// TUNING: Exclude hosts on an approved Yggdrasil or mesh-networking allowlist. A service-hosted binary in System32 or a user profile that connects here is the high-value case.
// LOOKBACK: 14d; set with the console time picker
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A peer reached only over the IPv6 overlay is not seen here; Query 7 covers that range.
// VALIDATION LEVEL: static-reviewed
event.type = 'IP Connect' dst.ip.address in ('37.205.14.171', '109.176.250.101', '65.21.57.122', '95.217.35.92', '51.255.223.60', '51.15.204.214', '62.210.85.80', '23.137.249.65', '78.27.153.163', '193.93.119.42')
| group conns = count(), first_seen = min(event.time), last_seen = max(event.time) by endpoint.name, src.process.name, dst.ip.address, dst.port.number
| sort -conns
| limit 200Automated validation: static-passed
5 required fields · View requirements
Required telemetry
- DeviceNetworkEvents
Required fields
Timestamp: Event timeRemoteIP: Remote addressRemotePort: Remote portDeviceName: HostInitiatingProcessFileName: Connecting process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceNetworkEvents | where Timestamp > ago(1d) | project Timestamp, DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort | take 5
// HUNT: Connections to MythicRatatoskr hardcoded public Yggdrasil peers (IPv4)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1090.003, T1573
// CONF: medium | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same connection predicate: the remote address is one of the 10 hardcoded Yggdrasil peers, grouped by host, process and peer with a count and first and last seen. The connecting process is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint network telemetry (DeviceNetworkEvents)
// TUNING: Exclude hosts on an approved Yggdrasil or mesh-networking allowlist. A service-hosted binary in System32 or a user profile that connects here is the high-value case.
// LOOKBACK: 14d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A peer reached only over the IPv6 overlay is not seen here; Query 7 covers that range.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceNetworkEvents
| where Timestamp >= ago(14d)
| where RemoteIP in ("37.205.14.171", "109.176.250.101", "65.21.57.122", "95.217.35.92", "51.255.223.60", "51.15.204.214", "62.210.85.80", "23.137.249.65", "78.27.153.163", "193.93.119.42")
| summarize Connections = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort
| sort by Connections desc
| take 200Looks for: Name resolution for the 21 hostname peers in the embedded list (for example the ygg.yt and yggdrasil.neilalexander.dev nodes). A host that resolves several of them is joining the public mesh. FP: Legitimate Yggdrasil users and researchers resolve these names. Several distinct peers resolved by one non-browser process is the stronger signal than a single lookup.
Known limitations and deployment notes
- PowerQuery: The CQL's collected list of queried names has no equivalent aggregate in this query; the pivot is the host and the distinct count.
- PowerQuery assumes: DNS Resolved events carry the queried name in event.dns.request; some schema versions use dns.request instead.
- PowerQuery assumes: estimate_distinct is approximate, so a distinct_peers of 2 may be off by one at scale.
- KQL – Defender XDR: If DnsQueryResponse is not populated for the tenant the query returns nothing; the readiness test shows which AdditionalFields key is present.
- KQL – Defender XDR assumes: The DnsQueryResponse action is recorded on this tenant and AdditionalFields holds the name under DnsQueryString or QueryName.
- KQL – Defender XDR assumes: dcount is an estimate, so a DistinctPeers of 2 may be off by one at scale.
// HUNT: DNS resolution of MythicRatatoskr hardcoded Yggdrasil peer hostnames // MITRE: T1090.003, T1071.001 // CONF: medium FP: medium COST: low | REQUIRES: DNS request telemetry (DnsRequest) // TUNING: exclude approved mesh-networking hosts. Prefer hosts where distinctPeers is 2 or more. // LOOKBACK: 14d (set with the time picker) #event_simpleName=DnsRequest | DomainName=/(^|\.)(s2\.i2pd\.xyz|vpn\.ltha\.de|mlupo\.duckdns\.org|ip6\.fvm\.mywire\.org|helium\.avevad\.com|yggdrasil\.neilalexander\.dev|bode\.theender\.net|g\.ygg\.yt|b\.ygg\.yt|n\.ygg\.yt|ygg1\.grin\.hu|srl\.newsdeef\.eu|ygg-nl\.incognet\.io|0\.ygg\.l1qu1d\.net|london\.sabretruth\.org|yggdrasil\.sunsung\.fun|sysop\.link|sto01\.yggdrasil\.hosted-by\.skhron\.eu|ygg\.ace\.ctrl-c\.liu\.se|spain\.magicum\.net|y\.zbin\.eu)$/i | groupBy([aid, ComputerName], function=[count(DomainName, distinct=true, as=distinctPeers), count(as=lookups), collect([DomainName])]) | sort(distinctPeers, order=desc)
4 required fields · View requirements
Required telemetry
- DNS Resolved
Required fields
event.time: Event timeevent.type: Event typeevent.dns.request: Queried nameendpoint.name: Host
Fallbacks
event.dns.request→dns.request: Same value under the older documented field name.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * | limit 5 | columns event.time, event.type, endpoint.name, event.dns.request
// HUNT: DNS resolution of MythicRatatoskr hardcoded Yggdrasil peer hostnames // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1090.003, T1071.001 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same DNS predicate: the queried name is, or is a subdomain of, one of the 21 hardcoded Yggdrasil peer hostnames, grouped per host with a distinct-name count. The distinct count is an estimate in SentinelOne where the CQL's is exact. // REQUIRES: SentinelOne endpoint DNS telemetry (DNS Resolved events) // TUNING: Exclude approved mesh-networking hosts. Prefer hosts where distinct_peers is 2 or more. // LOOKBACK: 14d; set with the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: The CQL's collected list of queried names has no equivalent aggregate in this query; the pivot is the host and the distinct count. // VALIDATION LEVEL: static-reviewed event.type = 'DNS Resolved' event.dns.request matches '(^|\\.)(s2\\.i2pd\\.xyz|vpn\\.ltha\\.de|mlupo\\.duckdns\\.org|ip6\\.fvm\\.mywire\\.org|helium\\.avevad\\.com|yggdrasil\\.neilalexander\\.dev|bode\\.theender\\.net|g\\.ygg\\.yt|b\\.ygg\\.yt|n\\.ygg\\.yt|ygg1\\.grin\\.hu|srl\\.newsdeef\\.eu|ygg-nl\\.incognet\\.io|0\\.ygg\\.l1qu1d\\.net|london\\.sabretruth\\.org|yggdrasil\\.sunsung\\.fun|sysop\\.link|sto01\\.yggdrasil\\.hosted-by\\.skhron\\.eu|ygg\\.ace\\.ctrl-c\\.liu\\.se|spain\\.magicum\\.net|y\\.zbin\\.eu)$' | group distinct_peers = estimate_distinct(event.dns.request), lookups = count(), first_seen = min(event.time), last_seen = max(event.time) by endpoint.name | sort -distinct_peers | limit 200
Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: ActionAdditionalFields: DNS detailsDeviceName: Host
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, DeviceName, ActionType, AdditionalFields | take 5
// HUNT: DNS resolution of MythicRatatoskr hardcoded Yggdrasil peer hostnames // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1090.003, T1071.001 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same DNS predicate: the queried name is, or is a subdomain of, one of the 21 hardcoded Yggdrasil peer hostnames, grouped per host with a distinct-name count. Defender has no endpoint DNS table, so the name is read from the DnsQueryResponse action's AdditionalFields. // REQUIRES: Defender for Endpoint DNS action telemetry (DeviceEvents, ActionType DnsQueryResponse) // TUNING: Exclude approved mesh-networking hosts. Prefer hosts where DistinctPeers is 2 or more. // LOOKBACK: 14d // CONFIGURATION: No lookup objects required. // KNOWN GAPS: If DnsQueryResponse is not populated for the tenant the query returns nothing; the readiness test shows which AdditionalFields key is present. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0 DeviceEvents | where Timestamp >= ago(14d) | where ActionType == "DnsQueryResponse" | extend QueryName = tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])) | where QueryName matches regex @"(?i)(^|\.)(s2\.i2pd\.xyz|vpn\.ltha\.de|mlupo\.duckdns\.org|ip6\.fvm\.mywire\.org|helium\.avevad\.com|yggdrasil\.neilalexander\.dev|bode\.theender\.net|g\.ygg\.yt|b\.ygg\.yt|n\.ygg\.yt|ygg1\.grin\.hu|srl\.newsdeef\.eu|ygg-nl\.incognet\.io|0\.ygg\.l1qu1d\.net|london\.sabretruth\.org|yggdrasil\.sunsung\.fun|sysop\.link|sto01\.yggdrasil\.hosted-by\.skhron\.eu|ygg\.ace\.ctrl-c\.liu\.se|spain\.magicum\.net|y\.zbin\.eu)$" | summarize DistinctPeers = dcount(QueryName), Lookups = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp), Domains = make_set(QueryName, 25) by DeviceName | sort by DistinctPeers desc | take 200
Looks for: Connections whose remote IPv6 address falls in 200::/7 (first group 2xx or 3xx, never 2001), which includes the C&C address ESET published. CONF is low on purpose: MythicRatatoskr is built on yggstack, which runs the mesh in user space, so overlay addresses normally never reach the operating system network stack. This query only fires for a variant or a host that uses a Yggdrasil tunnel interface.
Known limitations and deployment notes
- PowerQuery: Overlay traffic handled entirely in user space never reaches the endpoint network stack and is not seen.
- PowerQuery assumes: IPv6 destinations appear in dst.ip.address on IP Connect events, written with the leading zero group either present or omitted.
- PowerQuery assumes: The regex is case-insensitive by default.
- KQL – Defender XDR: Overlay traffic handled entirely in user space never reaches the endpoint network stack and is not seen.
- KQL – Defender XDR assumes: IPv6 destinations appear in RemoteIP, written with the leading zero group either present or omitted.
// HUNT: Outbound IPv6 into Yggdrasil 200::/7 (includes the ESET C&C address) // MITRE: T1090.003, T1573 // CONF: low FP: low COST: low | REQUIRES: outbound IPv6 connection telemetry (NetworkConnectIP6) // NOTE: yggstack keeps overlay traffic in user space, so absence of hits does not clear a host. Use Queries 5, 6 and 8 for the underlay. // LOOKBACK: 30d (set with the time picker) #event_simpleName=NetworkConnectIP6 | RemoteAddressIP6=/^0?[23][0-9a-f]{2}:/i | table([@timestamp, aid, ComputerName, ContextBaseFileName, RemoteAddressIP6, RemotePort]) | sort(@timestamp, order=desc)
3 required fields · View requirements
Required telemetry
- IP Connect
Required fields
event.time: Event timeevent.type: Event typedst.ip.address: Remote address
Recommended fields
endpoint.name: Hostsrc.process.name: Connecting processdst.port.number: Remote port
Readiness test
event.type = 'IP Connect' dst.ip.address matches ':' | limit 5 | columns event.time, event.type, dst.ip.address
// HUNT: Outbound IPv6 into Yggdrasil 200::/7 (includes the ESET C&C address)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1090.003, T1573
// CONF: low | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same address predicate: the remote address is in 200::/7, written as a leading 02xx or 03xx group. The connecting process is src.process.* because this is not a process-creation event.
// REQUIRES: SentinelOne endpoint network telemetry (IP Connect events) carrying IPv6 destinations
// TUNING: yggstack keeps overlay traffic in user space, so absence of hits does not clear a host. Use Queries 5, 6 and 8 for the underlay.
// LOOKBACK: 30d; set with the console time picker
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Overlay traffic handled entirely in user space never reaches the endpoint network stack and is not seen.
// VALIDATION LEVEL: static-reviewed
event.type = 'IP Connect' dst.ip.address matches '^0?[23][0-9a-f]{2}:'
| columns event.time, endpoint.name, src.process.name, dst.ip.address, dst.port.number
| sort -event.time
| limit 200Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceNetworkEvents
Required fields
Timestamp: Event timeRemoteIP: Remote address
Recommended fields
InitiatingProcessFileName: Connecting processRemotePort: Remote port
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceNetworkEvents | where Timestamp > ago(1d) | where RemoteIP contains ":" | project Timestamp, RemoteIP | take 5
// HUNT: Outbound IPv6 into Yggdrasil 200::/7 (includes the ESET C&C address)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1090.003, T1573
// CONF: low | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same address predicate: the remote address is in 200::/7, written as a leading 02xx or 03xx group. The connecting process is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint network telemetry (DeviceNetworkEvents) carrying IPv6 destinations
// TUNING: yggstack keeps overlay traffic in user space, so absence of hits does not clear a host. Use Queries 5, 6 and 8 for the underlay.
// LOOKBACK: 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Overlay traffic handled entirely in user space never reaches the endpoint network stack and is not seen.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceNetworkEvents
| where Timestamp >= ago(30d)
| where RemoteIP matches regex @"(?i)^0?[23][0-9a-f]{2}:"
| project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort
| sort by Timestamp desc
| take 200Looks for: Network connections to non-private addresses from a process named ieupdate.exe, windowsdefendersvc.exe, krbtman.exe, OneDriveLiveUpdater.exe, nbtresolver.exe or Act64.exe. This is the underlay view of the backdoor: TLS to a randomly chosen trio of public peers, and a beacon every 5 minutes by default.
Known limitations and deployment notes
- PowerQuery: A connection made by a renamed copy of the implant is not seen; Query 4 covers the known hashes.
- PowerQuery assumes: The process name is matched case-insensitively, which reproduces the CQL /i intent.
- PowerQuery assumes: IPv6 destinations are not excluded by the four IPv4 ranges; the CQL's event covers IPv4 connections only.
- KQL – Defender XDR: A connection made by a renamed copy of the implant is not seen; Query 4 covers the known hashes.
- KQL – Defender XDR assumes: ipv4_is_in_range returns null for an IPv6 RemoteIP, so IPv6 connections drop out, matching the CQL's IPv4-only event.
// HUNT: Masquerade-named MythicRatatoskr or bindProxy process with external connections // MITRE: T1071.001, T1090.003 // CONF: high FP: low COST: low | REQUIRES: outbound network connection telemetry (NetworkConnectIP4) // LOOKBACK: 14d (set with the time picker) #event_simpleName=NetworkConnectIP4 | ContextBaseFileName=/^(ieupdate|windowsdefendersvc|krbtman|onedriveliveupdater|nbtresolver|act64)\.exe$/i | !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=firstSeen), max(@timestamp, as=lastSeen)]) | sort(conns, order=desc)
6 required fields · View requirements
Required telemetry
- IP Connect
Required fields
event.time: Event timeevent.type: Event typesrc.process.name: Connecting processdst.ip.address: Remote addressdst.port.number: Remote portendpoint.name: Host
Readiness test
event.type = 'IP Connect' src.process.name = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.name, dst.ip.address, dst.port.number
// HUNT: Masquerade-named MythicRatatoskr or bindProxy process with external connections // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1071.001, T1090.003 // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same connection predicate: a masquerade-named process connecting to an address outside 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 and 127.0.0.0/8, grouped by host, process and destination. The connecting process is src.process.* because this is not a process-creation event. // REQUIRES: SentinelOne endpoint network telemetry (IP Connect events) // TUNING: The masquerade names are specific, so little tuning is expected. Review any legitimate Microsoft binary that shares one of these names by image path and signer. // LOOKBACK: 14d; set with the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A connection made by a renamed copy of the implant is not seen; Query 4 covers the known hashes. // VALIDATION LEVEL: static-reviewed event.type = 'IP Connect' src.process.name matches '^(ieupdate|windowsdefendersvc|krbtman|onedriveliveupdater|nbtresolver|act64)\\.exe$' | filter !(net_ipsubnet(dst.ip.address, '10.0.0.0/8')) and !(net_ipsubnet(dst.ip.address, '172.16.0.0/12')) and !(net_ipsubnet(dst.ip.address, '192.168.0.0/16')) and !(net_ipsubnet(dst.ip.address, '127.0.0.0/8')) | group conns = count(), first_seen = min(event.time), last_seen = max(event.time) by endpoint.name, src.process.name, dst.ip.address, dst.port.number | sort -conns | limit 200
Automated validation: static-passed
5 required fields · View requirements
Required telemetry
- DeviceNetworkEvents
Required fields
Timestamp: Event timeInitiatingProcessFileName: Connecting processRemoteIP: Remote addressRemotePort: Remote portDeviceName: Host
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceNetworkEvents | where Timestamp > ago(1d) | project Timestamp, DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort | take 5
// HUNT: Masquerade-named MythicRatatoskr or bindProxy process with external connections
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1071.001, T1090.003
// CONF: high | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same connection predicate: a masquerade-named process connecting to an address outside 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 and 127.0.0.0/8, grouped by host, process and destination. The connecting process is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint network telemetry (DeviceNetworkEvents)
// TUNING: The masquerade names are specific, so little tuning is expected. Review any legitimate Microsoft binary that shares one of these names by InitiatingProcessFolderPath and signer.
// LOOKBACK: 14d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A connection made by a renamed copy of the implant is not seen; Query 4 covers the known hashes.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceNetworkEvents
| where Timestamp >= ago(14d)
| where InitiatingProcessFileName in~ ("ieupdate.exe", "windowsdefendersvc.exe", "krbtman.exe", "onedriveliveupdater.exe", "nbtresolver.exe", "act64.exe")
| where not(ipv4_is_in_range(RemoteIP, "10.0.0.0/8")) and not(ipv4_is_in_range(RemoteIP, "172.16.0.0/12")) and not(ipv4_is_in_range(RemoteIP, "192.168.0.0/16")) and not(ipv4_is_in_range(RemoteIP, "127.0.0.0/8"))
| summarize Connections = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort
| sort by Connections desc
| take 200Looks for: A process listening on TCP 33690. ESET reports the standalone Go SOCKS5 server (internally named bindProxy) listens on 127.0.0.1 port 33690 and is probably exposed to the operators through the backdoor expose command.
Known limitations and deployment notes
- PowerQuery: If the tenant records no IP Listen events, only the loopback connection signal can fire.
- PowerQuery assumes: The IP Listen event type exists on this tenant and holds the local port in src.port.number; the field model marks it as unverified.
- PowerQuery assumes: A loopback connection to port 33690 is evidence of a listener even when the listen event is not recorded.
- KQL – Defender XDR: If the tenant records no ListeningConnectionCreated actions the query returns nothing.
- KQL – Defender XDR assumes: The ListeningConnectionCreated action is recorded on this tenant; it is attested in Microsoft hunting-query repositories rather than documented on the table page.
// HUNT: bindProxy SOCKS5 listener on port 33690 // MITRE: T1090.001 // CONF: high FP: low COST: low | REQUIRES: listening port telemetry (NetworkListenIP4) // LOOKBACK: 30d (set with the time picker) #event_simpleName=NetworkListenIP4 | LocalPort=33690 | table([@timestamp, aid, ComputerName, LocalAddressIP4, LocalPort, ContextBaseFileName]) | sort(@timestamp, order=desc)
5 required fields · View requirements
Required telemetry
- IP Listen
- IP Connect
Required fields
event.time: Event timeevent.type: Event typesrc.port.number: Local port on a listen eventdst.ip.address: Remote addressdst.port.number: Remote port
Recommended fields
endpoint.name: Hostsrc.process.name: Process
Readiness test
event.type = 'IP Listen' src.port.number = * | limit 5 | columns event.time, event.type, src.port.number, dst.ip.address, dst.port.number
// HUNT: bindProxy SOCKS5 listener on port 33690 // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1090.001 // CONF: high | FP: low // EQUIVALENCE: approximate-analytic - SentinelOne's listen event type is not attested in the field model, so the hunt tests two signals for the same SOCKS5 listener on port 33690: a listen event on that local port, and a loopback connection to it. Either one finds a running bindProxy. // REQUIRES: SentinelOne endpoint network telemetry (IP Listen and IP Connect events) // TUNING: Port 33690 is specific to bindProxy in the published reporting; confirm the process on any hit before closing it. // LOOKBACK: 30d; set with the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: If the tenant records no IP Listen events, only the loopback connection signal can fire. // VALIDATION LEVEL: static-reviewed (event.type = 'IP Listen' src.port.number = 33690) or (event.type = 'IP Connect' dst.ip.address = '127.0.0.1' dst.port.number = 33690) | columns event.time, endpoint.name, event.type, src.process.name, src.ip.address, src.port.number, dst.ip.address, dst.port.number | sort -event.time | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceNetworkEvents
Required fields
Timestamp: Event timeActionType: ActionLocalPort: Local port
Recommended fields
InitiatingProcessFileName: Listening processLocalIP: Local address
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceNetworkEvents | where Timestamp > ago(1d) | where ActionType == "ListeningConnectionCreated" | project Timestamp, ActionType, LocalPort | take 5
// HUNT: bindProxy SOCKS5 listener on port 33690 // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1090.001 // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same listener predicate: a listening-connection record whose local port is 33690. The listening process is InitiatingProcessFileName. // REQUIRES: Defender for Endpoint network telemetry (DeviceNetworkEvents, ActionType ListeningConnectionCreated) // TUNING: Port 33690 is specific to bindProxy in the published reporting; confirm the process on any hit before closing it. // LOOKBACK: 30d // CONFIGURATION: No lookup objects required. // KNOWN GAPS: If the tenant records no ListeningConnectionCreated actions the query returns nothing. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceNetworkEvents | where Timestamp >= ago(30d) | where ActionType == "ListeningConnectionCreated" and LocalPort == 33690 | project Timestamp, ReportId, DeviceId, DeviceName, LocalIP, LocalPort, InitiatingProcessFileName | sort by Timestamp desc | take 200
Looks for: The shell command runs cmd.exe, so a masquerade-named parent starting cmd.exe is the operator at the keyboard. The second branch catches command lines that read or delete the hidden encrypted configuration files .updatecache and .crond.
Known limitations and deployment notes
- PowerQuery: A shell spawned through a path that does not create a cmd.exe process is not captured.
- PowerQuery assumes: Names are matched case-insensitively, which reproduces the CQL /i intent.
- PowerQuery assumes: tgt.process.cmdline holds the full command line of the new process.
- KQL – Defender XDR: A shell spawned through a path that does not create a cmd.exe process is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: MythicRatatoskr shell command (cmd.exe child) and config file handling // MITRE: T1059.003, T1027.013 // CONF: high FP: low COST: low | REQUIRES: process creation with parent and command line (ProcessRollup2) // LOOKBACK: 30d (set with the time picker) #event_simpleName=ProcessRollup2 | (FileName=/^cmd\.exe$/i and ParentBaseFileName=/^(ieupdate|windowsdefendersvc|krbtman|onedriveliveupdater|nbtresolver|act64)\.exe$/i) or CommandLine=/[\\\/]\.(updatecache|crond)\b/i | table([@timestamp, aid, ComputerName, UserName, FileName, ParentBaseFileName, CommandLine]) | sort(@timestamp, order=desc)
5 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process namesrc.process.name: Creator process nametgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.user: Creator user
Readiness test
event.type = 'Process Creation' tgt.process.name = * | limit 5 | columns event.time, event.type, tgt.process.name, src.process.name, tgt.process.cmdline
// HUNT: MythicRatatoskr shell command (cmd.exe child) and config file handling // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1059.003, T1027.013 // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: cmd.exe whose creator is a masquerade binary, or any command line naming a hidden .updatecache or .crond file after a path separator. The new process is tgt.process.* and its creator is src.process.* because this is a Process Creation event. // REQUIRES: SentinelOne endpoint process-creation telemetry (Process Creation events) // TUNING: Both branches are specific to this implant, so little tuning is expected. The command-line branch can also match an analyst listing the hidden files. // LOOKBACK: 30d; set with the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A shell spawned through a path that does not create a cmd.exe process is not captured. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' ((tgt.process.name matches '^cmd\\.exe$' and src.process.name matches '^(ieupdate|windowsdefendersvc|krbtman|onedriveliveupdater|nbtresolver|act64)\\.exe$') or tgt.process.cmdline matches '[\\\\/]\\.(updatecache|crond)\\b') | columns event.time, endpoint.name, src.process.user, tgt.process.name, src.process.name, tgt.process.cmdline | sort -event.time | limit 200
Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameInitiatingProcessFileName: Initiating process nameProcessCommandLine: Created command line
Recommended fields
AccountName: Account
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName, InitiatingProcessFileName, ProcessCommandLine | take 5
// HUNT: MythicRatatoskr shell command (cmd.exe child) and config file handling
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1059.003, T1027.013
// CONF: high | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: cmd.exe whose initiating process is a masquerade binary, or any command line naming a hidden .updatecache or .crond file after a path separator. The parent is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Both branches are specific to this implant, so little tuning is expected. The command-line branch can also match an analyst listing the hidden files.
// LOOKBACK: 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A shell spawned through a path that does not create a cmd.exe process is not captured.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where (FileName =~ "cmd.exe" and InitiatingProcessFileName in~ ("ieupdate.exe", "windowsdefendersvc.exe", "krbtman.exe", "onedriveliveupdater.exe", "nbtresolver.exe", "act64.exe")) or ProcessCommandLine matches regex @"(?i)[\\/]\.(updatecache|crond)\b"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FileName, InitiatingProcessFileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: Any run of sdelete.exe, sdelete64.exe or sdelete64a.exe. ESET says Sandworm deployed SDelete through Active Directory Group Policy for the September 2025 wiping stage. The parent process shows how it was launched: gpscript.exe or a startup script for a GPO script, or a scheduler-hosted parent for a GPO scheduled task. FP: SDelete is a signed Sysinternals tool that administrators use legitimately. Do not block it by name or hash. Detect and review the parent, the command line and whether the host is an approved secure-erase workstation.
Known limitations and deployment notes
- PowerQuery: A renamed copy of the tool is not matched by name.
- PowerQuery assumes: The name is matched case-insensitively, which reproduces the CQL /i intent.
- KQL – Defender XDR: Advanced Hunting retains 30 days, so executions older than that are only on the CQL tab (90d). A renamed copy of the tool is not matched by name.
- KQL – Defender XDR assumes: The three file names are the complete set of SDelete spellings, matching the CQL pattern.
// HUNT: SDelete executed (Sandworm data-wiping stage) // MITRE: T1485, T1484.001 // CONF: medium FP: medium COST: low | REQUIRES: process creation with parent and command line (ProcessRollup2) // TUNING: exclude named secure-erase or decommissioning hosts by ComputerName. Never exclude by file hash, because attackers rename and the tool is the legitimate Sysinternals binary. // LOOKBACK: 90d (set with the time picker) #event_simpleName=ProcessRollup2 | FileName=/^sdelete(64|64a)?\.exe$/i | table([@timestamp, aid, ComputerName, UserName, FileName, ImageFileName, ParentBaseFileName, CommandLine]) | sort(@timestamp, order=desc)
3 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process name
Recommended fields
endpoint.name: Hostsrc.process.name: Creator processtgt.process.cmdline: Created command line
Readiness test
event.type = 'Process Creation' tgt.process.name = * | limit 5 | columns event.time, event.type, tgt.process.name
// HUNT: SDelete executed (Sandworm data-wiping stage) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1485, T1484.001 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the new process is sdelete.exe, sdelete64.exe or sdelete64a.exe. The new process is tgt.process.* and its creator is src.process.* because this is a Process Creation event. // REQUIRES: SentinelOne endpoint process-creation telemetry (Process Creation events) // TUNING: Exclude named secure-erase or decommissioning hosts by endpoint.name. Never exclude by file hash, because attackers rename and the tool is the legitimate Sysinternals binary. // LOOKBACK: 90d on the CQL tab; set the console picker to the tenant's retention // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed copy of the tool is not matched by name. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches '^sdelete(64|64a)?\\.exe$' | columns event.time, endpoint.name, src.process.user, tgt.process.name, tgt.process.image.path, src.process.name, tgt.process.cmdline | sort -event.time | limit 200
Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process name
Recommended fields
InitiatingProcessFileName: Initiating processProcessCommandLine: Created command line
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName | take 5
// HUNT: SDelete executed (Sandworm data-wiping stage)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1485, T1484.001
// CONF: medium | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the created process is sdelete.exe, sdelete64.exe or sdelete64a.exe. The parent is InitiatingProcessFileName. Advanced Hunting keeps 30 days, so the window is shorter than the CQL's 90.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude named secure-erase or decommissioning hosts by DeviceName. Never exclude by file hash, because attackers rename and the tool is the legitimate Sysinternals binary.
// LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 90d)
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Advanced Hunting retains 30 days, so executions older than that are only on the CQL tab (90d). A renamed copy of the tool is not matched by name.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where FileName in~ ("sdelete.exe", "sdelete64.exe", "sdelete64a.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FileName, FolderPath, InitiatingProcessFileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: The same SDelete command line executing on five or more distinct hosts. Group Policy deployment produces exactly this shape, one command line on many machines in a short window, which a single admin run never does. Lower the threshold in a small estate.
Known limitations and deployment notes
- PowerQuery: The grouping is by exact command line, so a rollout that varies the arguments per host splits across rows.
- PowerQuery assumes: agent.uuid identifies the endpoint and is populated on process events.
- PowerQuery assumes: estimate_distinct is approximate, so a count near the threshold of 5 may be off by one.
- KQL – Defender XDR: The grouping is by exact command line, so a rollout that varies the arguments per host splits across rows.
- KQL – Defender XDR assumes: dcount is approximate, so a count near the threshold of 5 may be off by one.
// HUNT: SDelete executed across many hosts with one command line (GPO-deployed wiper) // MITRE: T1485, T1484.001 // CONF: high FP: low COST: medium | REQUIRES: process creation with command line (ProcessRollup2) // LOOKBACK: 24h (set with the time picker; widen to 7d to catch a staged rollout) #event_simpleName=ProcessRollup2 | FileName=/^sdelete(64|64a)?\.exe$/i | groupBy([FileName, CommandLine], function=[count(aid, distinct=true, as=hosts), count(as=execs), min(@timestamp, as=firstSeen), max(@timestamp, as=lastSeen), collect([ParentBaseFileName])]) | hosts >= 5 | sort(hosts, order=desc)
5 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process nametgt.process.cmdline: Created command lineagent.uuid: Endpoint identity
Recommended fields
src.process.name: Creator process
Fallbacks
agent.uuid→endpoint.name: Counts hostnames instead of agents; a reused hostname undercounts.
Readiness test
event.type = 'Process Creation' agent.uuid = * | limit 5 | columns event.time, event.type, agent.uuid, tgt.process.name, tgt.process.cmdline
// HUNT: SDelete executed across many hosts with one command line (GPO-deployed wiper) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1485, T1484.001 // CONF: high | FP: low // EQUIVALENCE: equivalent-with-schema-assumptions - Same fan-out predicate: SDelete process creations grouped by tool name and exact command line, kept when five or more distinct hosts ran the same line. The host count is an estimate in SentinelOne where the CQL's is exact. // REQUIRES: SentinelOne endpoint process-creation telemetry (Process Creation events) // TUNING: Widen the console time picker to 7 days to catch a staged rollout. The threshold of 5 hosts is the CQL's. // LOOKBACK: 24h; set with the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: The grouping is by exact command line, so a rollout that varies the arguments per host splits across rows. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches '^sdelete(64|64a)?\\.exe$' | group hosts = estimate_distinct(agent.uuid), execs = count(), first_seen = min(event.time), last_seen = max(event.time), parent = any(src.process.name) by tgt.process.name, tgt.process.cmdline | filter hosts >= 5 | sort -hosts | limit 200
Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: Created command lineDeviceId: Device identity
Recommended fields
InitiatingProcessFileName: Initiating process
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, DeviceId, FileName, ProcessCommandLine | take 5
// HUNT: SDelete executed across many hosts with one command line (GPO-deployed wiper)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1485, T1484.001
// CONF: high | FP: low
// EQUIVALENCE: equivalent-with-schema-assumptions - Same fan-out predicate: SDelete process creations grouped by tool name and exact command line, kept when five or more distinct devices ran the same line. dcount is an estimate where the CQL's count is exact.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Widen the window to 7d to catch a staged rollout. The threshold of 5 hosts is the CQL's.
// LOOKBACK: 24h
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The grouping is by exact command line, so a rollout that varies the arguments per host splits across rows.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(24h)
| where FileName in~ ("sdelete.exe", "sdelete64.exe", "sdelete64a.exe")
| summarize Hosts = dcount(DeviceId), Execs = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp), Parents = make_set(InitiatingProcessFileName, 20) by FileName, ProcessCommandLine
| where Hosts >= 5
| sort by Hosts desc
| take 200Looks for: The three host artifacts ESET ties to this intrusion before MythicRatatoskr: a scheduled task named pdfopentask, a PowerShell payload read from temporarydoc.txt, and the HKCU Run value UpdateMonitor. This is the brief delivery-chain view only. The wider UAC-0099 toolset is covered by a separate pack.
Known limitations and deployment notes
- PowerQuery: A task registered by an API call that never appears in a process command line is not seen; the CQL's task-registration record is not reproduced.
- PowerQuery assumes: A scheduled task named pdfopentask is created or run by a process whose command line names it, as schtasks does.
- PowerQuery assumes: registry.keyPath ends at the Run key or at the value name under it.
- PowerQuery assumes: Names are matched case-insensitively, which reproduces the CQL /i intent.
- KQL – Defender XDR: The UpdateMonitor Run value under CurrentVersion\Run is not covered; that needs DeviceRegistryEvents. The scheduled-task registration record is not covered. Advanced Hunting retains 30 days, so older activity is only on the CQL tab (90d).
- KQL – Defender XDR assumes: A scheduled task named pdfopentask is created or run by a process whose command line names it, as schtasks does.
// HUNT: UAC-0099 delivery chain artifacts for this intrusion (pdfopentask, temporarydoc.txt, UpdateMonitor) // MITRE: T1053.005, T1547.001, T1059.001 // CONF: high FP: low COST: low | REQUIRES: scheduled task, process creation and autostart registry telemetry (ScheduledTaskRegistered, ProcessRollup2, AsepValueUpdate) // LOOKBACK: 90d (set with the time picker) #event_simpleName=/^(ScheduledTaskRegistered|ProcessRollup2|AsepValueUpdate)$/ | (TaskName=/(^|\\)pdfopentask$/i or CommandLine=/temporarydoc\.txt/i or (RegValueName=/^UpdateMonitor$/i and RegObjectName=/\\CurrentVersion\\Run$/i)) | table([@timestamp, aid, ComputerName, UserName, #event_simpleName, TaskName, CommandLine, RegObjectName, RegValueName, RegStringValue]) | sort(@timestamp, order=desc)
5 required fields · View requirements
Required telemetry
- Process Creation
- Registry Value Modified
Required fields
event.time: Event timeevent.type: Event typetgt.process.cmdline: Created command lineregistry.valueName: Registry value nameregistry.keyPath: Registry key path
Recommended fields
endpoint.name: Host
Optional fields
registry.value: Registry value data
Readiness test
event.type = 'Registry Value Modified' registry.keyPath = * | limit 5 | columns event.time, event.type, tgt.process.cmdline, registry.keyPath, registry.valueName
// HUNT: UAC-0099 delivery chain artifacts for this intrusion (pdfopentask, temporarydoc.txt, UpdateMonitor) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1053.005, T1547.001, T1059.001 // CONF: high | FP: low // EQUIVALENCE: approximate-analytic - SentinelOne has no attested scheduled-task registration event, so the task is found through the command line that creates or runs it. The temporarydoc.txt command-line branch and the UpdateMonitor Run value branch match the CQL; the pdfopentask task name is matched in a process command line instead of a task-registration record. // REQUIRES: SentinelOne endpoint process-creation and registry telemetry (Process Creation and Registry Value Modified events) // TUNING: All three branches are specific to this intrusion, so little tuning is expected. // LOOKBACK: 90d on the CQL tab; set the console picker to the tenant's retention // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A task registered by an API call that never appears in a process command line is not seen; the CQL's task-registration record is not reproduced. // VALIDATION LEVEL: static-reviewed (event.type = 'Process Creation' (tgt.process.cmdline contains 'temporarydoc.txt' or tgt.process.cmdline contains 'pdfopentask')) or (event.type = 'Registry Value Modified' registry.valueName matches '^UpdateMonitor$' registry.keyPath matches '\\\\CurrentVersion\\\\Run(\\\\UpdateMonitor)?$') | columns event.time, endpoint.name, event.type, src.process.user, tgt.process.cmdline, registry.keyPath, registry.valueName, registry.value | sort -event.time | limit 200
Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command line
Recommended fields
InitiatingProcessFileName: Initiating process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, ProcessCommandLine | take 5
// HUNT: UAC-0099 delivery chain artifacts for this intrusion (pdfopentask, temporarydoc.txt, UpdateMonitor) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1053.005, T1547.001, T1059.001 // CONF: high | FP: low // EQUIVALENCE: telemetry-gap - A partial pivot on the command-line branch. The table is DeviceProcessEvents, which sees the temporarydoc.txt and pdfopentask names on a command line, but the UpdateMonitor Run value needs DeviceRegistryEvents and the task-registration record has no table here, and one query reads only one table. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Pair with a DeviceRegistryEvents hunt for a Run value named UpdateMonitor to cover the third branch. // LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 90d) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: The UpdateMonitor Run value under CurrentVersion\Run is not covered; that needs DeviceRegistryEvents. The scheduled-task registration record is not covered. Advanced Hunting retains 30 days, so older activity is only on the CQL tab (90d). // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(30d) | where ProcessCommandLine contains "temporarydoc.txt" or ProcessCommandLine contains "pdfopentask" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName | sort by Timestamp desc | take 200
Looks for: Resolution of uztickets.com (MATCHWOK C&C) or egyptanimals.com (where MATCHBOIL fetched MATCHWOK from). These are the only two UAC-0099 indicators in this pack, kept because ESET ties them to this exact intrusion. FP: egyptanimals.com is probably a compromised or abused third-party site rather than purpose-built infrastructure, so a lookup alone is a lead. Require a scripting or Office parent on the same host before escalating.
Known limitations and deployment notes
- PowerQuery: A lookup that never reaches the endpoint resolver, such as one over DNS-over-HTTPS inside a browser, is not seen.
- PowerQuery assumes: DNS Resolved events carry the queried name in event.dns.request; some schema versions use dns.request instead.
- PowerQuery assumes: The name is matched case-insensitively, which reproduces the CQL /i intent.
- KQL – Defender XDR: Advanced Hunting retains 30 days, so lookups older than that are only on the CQL tab (90d). If DnsQueryResponse is not populated for the tenant the query returns nothing.
- KQL – Defender XDR assumes: The DnsQueryResponse action is recorded on this tenant and AdditionalFields holds the name under DnsQueryString or QueryName.
// HUNT: Delivery-chain domains for this intrusion (MATCHWOK C&C and staging host) // MITRE: T1071.001, T1105 // CONF: medium FP: medium COST: low | REQUIRES: DNS request telemetry (DnsRequest) // TUNING: for egyptanimals.com, pivot to the process that resolved it (Query 13 for the host) and discount plain browser lookups. // LOOKBACK: 90d (set with the time picker) #event_simpleName=DnsRequest | DomainName=/(^|\.)(uztickets\.com|egyptanimals\.com)$/i | table([@timestamp, aid, ComputerName, UserName, DomainName, ContextProcessId]) | sort(@timestamp, order=desc)
3 required fields · View requirements
Required telemetry
- DNS Resolved
Required fields
event.time: Event timeevent.type: Event typeevent.dns.request: Queried name
Recommended fields
endpoint.name: Hostsrc.process.name: Resolving process
Fallbacks
event.dns.request→dns.request: Same value under the older documented field name.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * | limit 5 | columns event.time, event.type, event.dns.request
// HUNT: Delivery-chain domains for this intrusion (MATCHWOK C&C and staging host) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1071.001, T1105 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same DNS predicate: the queried name is, or is a subdomain of, uztickets.com or egyptanimals.com. The resolving process is src.process.* because this is not a process-creation event. // REQUIRES: SentinelOne endpoint DNS telemetry (DNS Resolved events) // TUNING: For egyptanimals.com, pivot to the process that resolved it (src.process.name here, Query 13 for the host) and discount plain browser lookups. // LOOKBACK: 90d on the CQL tab; set the console picker to the tenant's retention // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A lookup that never reaches the endpoint resolver, such as one over DNS-over-HTTPS inside a browser, is not seen. // VALIDATION LEVEL: static-reviewed event.type = 'DNS Resolved' event.dns.request matches '(^|\\.)(uztickets\\.com|egyptanimals\\.com)$' | columns event.time, endpoint.name, src.process.user, event.dns.request, src.process.name | sort -event.time | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: ActionAdditionalFields: DNS details
Recommended fields
InitiatingProcessFileName: Resolving process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields | take 5
// HUNT: Delivery-chain domains for this intrusion (MATCHWOK C&C and staging host) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1071.001, T1105 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same DNS predicate: the queried name is, or is a subdomain of, uztickets.com or egyptanimals.com. Defender has no endpoint DNS table, so the name is read from the DnsQueryResponse action's AdditionalFields. // REQUIRES: Defender for Endpoint DNS action telemetry (DeviceEvents, ActionType DnsQueryResponse) // TUNING: For egyptanimals.com, pivot to the process that resolved it (InitiatingProcessFileName here, Query 13 for the host) and discount plain browser lookups. // LOOKBACK: 30d (Advanced Hunting retention; the CQL tab covers 90d) // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Advanced Hunting retains 30 days, so lookups older than that are only on the CQL tab (90d). If DnsQueryResponse is not populated for the tenant the query returns nothing. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceEvents | where Timestamp >= ago(30d) | where ActionType == "DnsQueryResponse" | extend QueryName = tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])) | where QueryName matches regex @"(?i)(^|\.)(uztickets\.com|egyptanimals\.com)$" | project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessAccountName, QueryName, InitiatingProcessFileName | sort by Timestamp desc | take 200
Looks for: sftp-server.exe or sshd.exe starting on an endpoint. ESET telemetry shows additional MythicRatatoskr samples were pushed to other machines in the victim network using an OpenSSH SFTP server. FP: Windows OpenSSH Server is legitimate where administrators enable it. The signal is an SFTP server on a host with no sanctioned SSH role, or one that precedes a new masquerade-named binary (Query 2).
Known limitations and deployment notes
- PowerQuery: An SFTP server renamed before launch is not matched by name.
- PowerQuery assumes: The name is matched case-insensitively, which reproduces the CQL /i intent.
- KQL – Defender XDR: An SFTP server renamed before launch is not matched by name.
- KQL – Defender XDR assumes: FileName holds the image name of the created process.
// HUNT: OpenSSH SFTP server used to move implants laterally // MITRE: T1021.004, T1570 // CONF: medium FP: medium COST: low | REQUIRES: process creation with parent (ProcessRollup2) // TUNING: exclude hosts with an approved OpenSSH Server role by ComputerName. Pivot on Query 2 for binaries written within 15 minutes of the hit. // LOOKBACK: 30d (set with the time picker) #event_simpleName=ProcessRollup2 | FileName=/^(sftp-server|sshd)\.exe$/i | table([@timestamp, aid, ComputerName, UserName, FileName, ImageFileName, ParentBaseFileName, CommandLine]) | sort(@timestamp, order=desc)
3 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process name
Recommended fields
endpoint.name: Hostsrc.process.name: Creator processtgt.process.cmdline: Created command line
Readiness test
event.type = 'Process Creation' tgt.process.name = * | limit 5 | columns event.time, event.type, tgt.process.name
// HUNT: OpenSSH SFTP server used to move implants laterally // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1021.004, T1570 // CONF: medium | FP: medium // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the new process is sftp-server.exe or sshd.exe. The new process is tgt.process.* and its creator is src.process.* because this is a Process Creation event. // REQUIRES: SentinelOne endpoint process-creation telemetry (Process Creation events) // TUNING: Exclude hosts with an approved OpenSSH Server role by endpoint.name. Pivot on Query 2 for binaries written within 15 minutes of the hit. // LOOKBACK: 30d; set with the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: An SFTP server renamed before launch is not matched by name. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' tgt.process.name matches '^(sftp-server|sshd)\\.exe$' | columns event.time, endpoint.name, src.process.user, tgt.process.name, tgt.process.image.path, src.process.name, tgt.process.cmdline | sort -event.time | limit 200
Automated validation: static-passed
2 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process name
Recommended fields
InitiatingProcessFileName: Initiating processProcessCommandLine: Created command line
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, FileName | take 5
// HUNT: OpenSSH SFTP server used to move implants laterally
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1021.004, T1570
// CONF: medium | FP: medium
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the created process is sftp-server.exe or sshd.exe. The parent is InitiatingProcessFileName.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude hosts with an approved OpenSSH Server role by DeviceName. Pivot on Query 2 for binaries written within 15 minutes of the hit.
// LOOKBACK: 30d
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: An SFTP server renamed before launch is not matched by name.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where FileName in~ ("sftp-server.exe", "sshd.exe")
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, FileName, FolderPath, InitiatingProcessFileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Detection Rules by Platform
CrowdStrike: Custom IOA
| IOA name | Rule type and pattern | Severity / action | Promotes | Exclusions |
|---|---|---|---|---|
| MythicRatatoskr masquerade image runs | Process Creation. Image filename regex .*\\(ieupdate|windowsdefendersvc|krbtman|onedriveliveupdater|nbtresolver)\.exe | High / Detect first, Prevent only after a clean 14-day baseline | Promote Q3 | Approved software with the same filename, by hash allowlist |
| Masquerade binary spawns cmd.exe | Process Creation. Parent image regex as above; image .*\\cmd\.exe | Critical / Detect | Promote Q10 | None expected |
| bindProxy SOCKS5 listener | Network Connection or listening-port rule on TCP 33690 | High / Detect | Promote Q9 | None expected |
| Hardcoded Yggdrasil peer connection | Network Connection. Remote IP in the ten raw-IP peers | Medium / Detect | Promote Q5 | Approved mesh-networking hosts |
| SDelete execution outside secure-erase hosts | Process Creation. Image .*\\sdelete(64|64a)?\.exe | High / Detect only. SDelete is legitimate: never Prevent on it | Promote Q11 | Named decommissioning hosts |
| Delivery-chain command line | Process Creation. Command line .*temporarydoc\.txt.* | High / Detect | Promote Q13 | None expected |
Q12 (fan-out aggregate) and Q4 (hash list) stay as scheduled searches because an aggregate or a large value list is not an IOA pattern. Keep every rule at Detect until baselined.
SentinelOne: custom detection rules
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| MythicRatatoskr masquerade image runs | Q3, PowerQuery tab | Scheduled custom detection rule | Bind 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 |
| Masquerade binary spawns cmd.exe | Q10, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| bindProxy SOCKS5 listener | Q9, PowerQuery tab | Hunt only until the gap is closed | Q9 is only an approximation here. SentinelOne's listen event type is not attested in the field model, so the hunt tests two signals for the same SOCKS5 listener on port 33690: a listen event on that local port, and a loopback connection to it. Either one finds a running bindProxy. |
| Hardcoded Yggdrasil peer connection | Q5, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| SDelete execution outside secure-erase hosts | Q11, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| Delivery-chain command line | Q13, PowerQuery tab | Hunt only until the gap is closed | Q13 is only an approximation here. SentinelOne has no attested scheduled-task registration event, so the task is found through the command line that creates or runs it. The temporarydoc.txt command-line branch and the UpdateMonitor Run value branch match the CQL; the pdfopentask task name is matched in a process command line instead... |
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
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| MythicRatatoskr masquerade image runs | Q3, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | The 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 |
| Masquerade binary spawns cmd.exe | Q10, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | The 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 |
| bindProxy SOCKS5 listener | Q9, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | The 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 |
| Hardcoded Yggdrasil peer connection | Q5, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | Make the final result include Timestamp, ReportId and DeviceId: Microsoft recommends them 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 |
| SDelete execution outside secure-erase hosts | Q11, KQL – Defender XDR tab | Custom detection rule, alert only, every hour | The 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 |
| Delivery-chain command line | Q13, KQL – Defender XDR tab | Hunt only until the gap is closed | Q13 is only an approximation here. A partial pivot on the command-line branch. The table is DeviceProcessEvents, which sees the temporarydoc.txt and pdfopentask names on a command line, but the UpdateMonitor Run value needs DeviceRegistryEvents and the task-registration record has no table here, and one query reads only one table. |
Q1, Q2, Q4, Q6, Q7, Q8, Q12, Q14 and Q15 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.
Machine-Readable IOC Appendix
type,value,action,severity,expiration,description,tags sha1,d5f9288daebf87ae4579945f8dc6cf235b093cfd,detect,critical,2027-04-23,MythicRatatoskr backdoor (Act64.exe),campaign:MythicRatatoskr sha1,b69ef0e45b401440c0fde22046775d0c57e87415,detect,critical,2027-04-23,MythicRatatoskr backdoor (ie.exe),campaign:MythicRatatoskr sha1,4e3e6577866e4ce2ed73ca089700ae04230e768f,detect,critical,2027-04-23,MythicRatatoskr backdoor (ieupdate.exe),campaign:MythicRatatoskr sha1,69969eeb7e0a3d84c4e70193636fcf934c6aa388,detect,critical,2027-04-23,MythicRatatoskr backdoor (ieupdate.exe),campaign:MythicRatatoskr sha1,01855153ca7a33ad5ff36451de5612dfba0dd2ca,detect,critical,2027-04-23,MythicRatatoskr backdoor (krbtman.exe),campaign:MythicRatatoskr sha1,e29af83a07fb32eb47c28733a9382e766d53f704,detect,critical,2027-04-23,MythicRatatoskr backdoor (OneDriveLiveUpdater.exe),campaign:MythicRatatoskr sha1,028ca11f3f0d8396043af7bf756231fc2f50f829,detect,critical,2027-04-23,MythicRatatoskr backdoor (windowsdefendersvc.exe),campaign:MythicRatatoskr sha1,9085896989947c0919a660352f75f6b233fc645b,detect,critical,2027-04-23,MythicRatatoskr backdoor (windowsdefendersvc.exe),campaign:MythicRatatoskr sha1,d7e6a5a46c6ed3510997e91b11e51be0250fd2a2,detect,critical,2027-04-23,MythicRatatoskr backdoor (updater.exe),campaign:MythicRatatoskr sha1,131a371a1e4ee78ec3b2863607c99290ec3b58a6,detect,critical,2027-04-23,bindProxy SOCKS5 server (krbtman.exe),campaign:MythicRatatoskr sha1,09c816697c0c2aff9b4ff58681558ca30d04c9cd,detect,critical,2027-04-23,bindProxy SOCKS5 server (nbtresolver.exe),campaign:MythicRatatoskr sha1,8ceb5f8bcdf4995b7164996f1629d682613bb17b,detect,critical,2027-04-23,MythicRatatoskr backdoor (ieupdate.exe) ESET article spelling; GitHub file differs by one character,campaign:MythicRatatoskr sha1,8ceb5f8bcdf4995b7164996f1429d682613bb17b,detect,high,2027-04-23,ieupdate.exe as spelled in the ESET GitHub file; differs from the article by one character,campaign:MythicRatatoskr ipv6,201:b479:2771:8df4:b5eb:d007:63b0:2838,detect,critical,2027-04-23,MythicRatatoskr C&C inside the Yggdrasil mesh; HTTPS 443 and reverse proxy 8080,campaign:MythicRatatoskr domain,uztickets.com,detect,high,2027-04-23,MATCHWOK C&C in this intrusion (delivery chain only),campaign:MythicRatatoskr domain,egyptanimals.com,detect,medium,2027-04-23,MATCHWOK fetched from here in this intrusion; likely abused third-party site,campaign:MythicRatatoskr # NOTE: every row is DETECT. No indicator has two independent sources (the ESET article and the ESET GitHub file are one vendor; press coverage carries no atomic values). # NOTE: Falcon IOC Management ingests sha256, md5, domain and IP types. The sha1 rows are for TIP, EDR search and Query 4; they are not importable as-is. # NOTE: Yggdrasil public peers are legitimate community nodes. They are in Queries 5 and 6 and the Behavioral block, not in this import. # NOTE: SDelete, OneDrive and Defender are not listed. Block only the attacker hashes above, never the stock tool or a masquerade name alone.
indicatorType,indicatorValue,action,title,description,expirationTime,severity,recommendedActions,rbacGroups,category,mitretechniques,GenerateAlert FileSha1,d5f9288daebf87ae4579945f8dc6cf235b093cfd,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (Act64.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,b69ef0e45b401440c0fde22046775d0c57e87415,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (ie.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,4e3e6577866e4ce2ed73ca089700ae04230e768f,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (ieupdate.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,69969eeb7e0a3d84c4e70193636fcf934c6aa388,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (ieupdate.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,01855153ca7a33ad5ff36451de5612dfba0dd2ca,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (krbtman.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,e29af83a07fb32eb47c28733a9382e766d53f704,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (OneDriveLiveUpdater.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,028ca11f3f0d8396043af7bf756231fc2f50f829,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (windowsdefendersvc.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,9085896989947c0919a660352f75f6b233fc645b,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (windowsdefendersvc.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,d7e6a5a46c6ed3510997e91b11e51be0250fd2a2,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (updater.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,131a371a1e4ee78ec3b2863607c99290ec3b58a6,Audit,bindProxy SOCKS5 server,bindProxy SOCKS5 server (krbtman.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,09c816697c0c2aff9b4ff58681558ca30d04c9cd,Audit,bindProxy SOCKS5 server,bindProxy SOCKS5 server (nbtresolver.exe),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,8ceb5f8bcdf4995b7164996f1629d682613bb17b,Audit,MythicRatatoskr backdoor,MythicRatatoskr backdoor (ieupdate.exe) ESET article spelling; GitHub file differs by one character,2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True FileSha1,8ceb5f8bcdf4995b7164996f1429d682613bb17b,Audit,ieupdate.exe as spelled in the ESET GitHub file; differs fro,ieupdate.exe as spelled in the ESET GitHub file; differs from the article by one character,2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,uztickets.com,Audit,MATCHWOK C&C in this intrusion,MATCHWOK C&C in this intrusion (delivery chain only),2027-04-23T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True DomainName,egyptanimals.com,Audit,MATCHWOK fetched from here in this intrusion; likely abused ,MATCHWOK fetched from here in this intrusion; likely abused third-party site,2027-04-23T00:00:00.0Z,Medium,Investigate the device and pivot into the pack's queries,,,,True
Column names and allowed values are from Microsoft's documented parameter table. Left out because this block maps only SHA-1, SHA-256, IPv4, domain and URL indicators: ipv6 1. 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).
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.
# Service and files (names are masquerades; judge by path + hash, not name) Service name: ieupdate Install paths (ESET Table 1): C:\windows\system32\updater.exe C:\Windows\system32\krbtman.exe C:\windows\system32\windowsdefendersvc.exe %localappdata%\Microsoft\OneDrive\OneDriveLiveUpdater.exe c:\program files (x86)\microsoft.net\adomd.net\110\applicationasphost.exe C:\OFFICE2010\Utilities\Act64.exe %userprofile%\Downloads\WindowsDefenderSvc.exe %userprofile%\Downloads\ieupdate.exe %userprofile%\Downloads\ie.exe %userprofile%\AppData\Local\Internet Explorer\ieupdate.exe %userprofile%\AppData\Local\ieupdate.exe Hidden encrypted config (dot-prefixed): C:\Windows\Temp\.updatecache C:\Windows\system32\.updatecache %LocalAppData%/Temp/.crond (forward slashes are the attackers' typo) /tmp/.test_config (unused string; hints at a Unix variant) bindProxy SOCKS5 server paths: C:\Windows\system32\krbtman.exe %userprofile%\Downloads\krbtman.exe %localappdata%\SMBCache\nbtresolver.exe listens 127.0.0.1:33690 # Delivery chain (this intrusion only) Scheduled task: pdfopentask -> PowerShell payload %temp%\temporarydoc.txt HKCU Run value: UpdateMonitor (HKCU\Software\Microsoft\Windows\CurrentVersion\Run) # Protocol and config constants (memory, YARA and PCAP work; not endpoint-telemetry fields) Config crypto: AES-256-CFB, first 16 bytes = IV, key (base64) US3pM9KFxrZBSgc1pGl2wO4Kir1XjZP5Z9kBXBMYd2s= Config defaults: sleep 5m, skew 10 (unused), uuid 123 (placeholder), count 5 Check-in UUID: d71f1722-cf0b-4e27-9f8e-c95ec9b24a23 HTTPS POST JSON types: checkin, tasking, result, getfile Commands: chtime, expose, upload, download, nodeinfo, screenshot, cd, ls, pwd, churl, proxy (start|stop), shell (cmd.exe) Proxy target (hardcoded): 201:b479:2771:8df4:b5eb:d007:63b0:2838:8080 ; sends the string "test" on connect Startup delay: 10 minutes in some samples Go build base: yggdrasil-go, yggstack, revsocks, go-socks5 ; debug strings "Accepting stream", "Passing off to socks5" Yggdrasil addressing: 200::/7 ; C&C TLS certificates rotate regularly (revsocks trait)
MythicRatatoskr Go backdoor, Windows service "ieupdate"; ESET detection WinGo/Agent.ZO bindProxy Go SOCKS5 server (go-socks5), 127.0.0.1:33690; ESET WinGo/Agent.AOK (krbtman.exe) and WinGo/TrojanProxy.Agent.I (nbtresolver.exe) yggstack / yggdrasil-go open-source code the backdoor is built on (legitimate projects; hunt the behavior, not the library) revsocks open-source reverse SOCKS code the proxy command is derived from MATCHBOIL UAC-0099 downloader, deployed MATCHWOK in this intrusion (documented elsewhere; delivery chain only here) MATCHWOK UAC-0099 backdoor, C&C uztickets.com, persisted as HKCU Run value UpdateMonitor SDelete Sysinternals secure-delete utility, signed and LEGITIMATE; deployed through Group Policy for the wiping stage (September 2025) OpenSSH SFTP server used to push additional samples to other machines
# 32 public Yggdrasil peers hardcoded in every ESET-analysed sample (three are chosen at random). # Legitimate community infrastructure: use for egress BLOCK/alert review, never as malware IOCs. tls://37.205.14.171:993 tls://109.176.250.101:65534 tls://65.21.57.122:61995 tls://95.217.35.92:1337 tls://51.255.223.60:54232 tls://51.15.204.214:54321 tls://s2.i2pd.xyz:39575 tls://62.210.85.80:39575 tls://vpn.ltha.de:443?key=0000006149970f245e6cec43664bce203f2514b60a153e194f31e2b229a1339d tls://mlupo.duckdns.org:9001 quic://ip6.fvm.mywire.org:443?key=000000000143db657d1d6f80b5066dd109a4cb31f7dc6cb5d56050fffb014217 tls://helium.avevad.com:1337 tls://yggdrasil.neilalexander.dev:64648?key=ecbbcb3298e7d3b4196103333c3e839cfe47a6ca47602b94a6d596683f6bb358 tls://bode.theender.net:42169?key=f91b909f43829f8b20732b3bcf80cbc4bb078dd47b41638379a078e35984c9a4 tls://g.ygg.yt:443 tls://b.ygg.yt:443 tls://n.ygg.yt:443 tls://ygg1.grin.hu:42444 tls://[2a03:90c0:85::28a]:443 tls://srl.newsdeef.eu:59999 tls://23.137.249.65:444 tls://ygg-nl.incognet.io:8884 quic://0.ygg.l1qu1d.net:11102?key=0000000998b5ff8c0f1115ce9212f772d0427151f50fe858e6de1d22600f1680 tls://london.sabretruth.org:18472 tls://yggdrasil.sunsung.fun:4443 tls://78.27.153.163:33166 tls://193.93.119.42:443 tcp://sysop.link:555 tls://sto01.yggdrasil.hosted-by.skhron.eu:8884 tls://ygg.ace.ctrl-c.liu.se:9999?key=5636b3af4738c3998284c4805d91209cab38921159c66a6f359f3f692af1c908 quic://spain.magicum.net:36900 tcp://y.zbin.eu:7743
# Hardening audit checklist (read-only checks) [ ] Outbound policy: do servers and workstations have default-deny egress? Are the 32 peers above blocked? [ ] auditpol /get /subcategory:"Directory Service Changes" (DCs: Success enabled) [ ] auditpol /get /subcategory:"Security System Extension" (all: Success enabled, event 4697) [ ] Get-Service sshd -ErrorAction SilentlyContinue (OpenSSH Server present where not sanctioned?) [ ] Get-GPPermission over GPOs: who can edit/link GPOs beyond Domain Admins? [ ] Get-MpPreference | select -Expand AttackSurfaceReductionRules_Ids (ASR rules present; Defender AV in active mode?) [ ] Offline, immutable backup restore test completed in the last 90 days?
Detection Validation Gates
| Gate | Requirement | Status in this pack |
|---|---|---|
| Telemetry ready | Endpoint sensor on servers, workstations and, ideally, domain controllers. Process creation with SHA-1, service creation, executable-written, outbound connection, listening-socket and DNS telemetry confirmed per tenant (CrowdStrike: ProcessRollup2, CreateService, PeFileWritten, NetworkConnectIP4, NetworkListenIP4, DnsRequest. SentinelOne and Defender equivalents per the platform map). Domain-controller Directory Service Changes auditing enabled for native hunt 3 | Verify per-tenant |
| Benign baseline | Run Q2, Q3, Q5, Q6, Q11, Q14 and Q15 in investigate mode for 14 days. Record approved Yggdrasil users, secure-erase hosts, OpenSSH Server hosts and any software that legitimately drops an updater.exe | Required before go-live |
| Positive tests | Lab only. Q1: create a service named ieupdate pointing at a benign executable (sc.exe create ieupdate binPath= "C:\Windows\System32\notepad.exe" then delete it). Q9: bind any test listener to 127.0.0.1:33690. Q11 and Q12: run SDelete against a scratch file on three lab hosts with one identical command line. Never run real malware or touch the live peers from production | Pending |
| Promotion criteria | Zero unexplained hits over the baseline before any IOA leaves Detect. Q1, Q4, Q9, Q10 and Q12 have a small false-positive surface and can alert on day one; Q5, Q6 and Q11 stay at review severity | Pending |
Hardening: Tiered
- Block the 32 public Yggdrasil peers at egress and DNS. ESET calls this a viable mitigation, and it is the only control that denies the backdoor its way into the mesh. MITRE M1037 Filter Network Traffic and M1031 Network Intrusion Prevention; CIS Controls v8 Control 13 (Network Monitoring and Defense). Verify: a test connection to a listed peer fails and Q5 and Q6 show only blocked attempts.
- Turn on the audit trail that the wiping stage depends on. Enable Audit Directory Service Changes on domain controllers (event 5136) and Audit Security System Extension everywhere (event 4697). MITRE M1047 Audit; Microsoft advanced security audit policy guidance and the CIS Microsoft Windows Server Benchmarks audit-policy section. Verify with
auditpol /get. - Shrink who can create, edit and link Group Policy. Remove GPO edit and link rights from everyone except named Tier 0 administrators. MITRE M1026 Privileged Account Management and M1018 User Account Management; Microsoft enterprise access model (tiering). Verify with
Get-GPPermission. - Protect backups from the wiper. Keep an offline or immutable copy that Group Policy cannot reach and test a restore. MITRE M1053 Data Backup (T1485); CIS Controls v8 Control 11 (Data Recovery).
- Application control for user-writable and System32 paths. Deny execution of unsigned binaries from Downloads, %LocalAppData% and user profile folders, and flag unsigned new files in System32. MITRE M1038 Execution Prevention; Microsoft WDAC / AppLocker documentation; CIS Controls v8 safeguards on authorized software allowlisting. Verify with Q2 and Q3 going quiet.
- Disable OpenSSH Server where it has no role. The intrusion moved implants through an OpenSSH SFTP server. MITRE M1042 Disable or Remove Feature and M1035 Limit Access to Resource over Network. Best-practice: no formal CIS item covers an unused optional Windows feature, flagged
⚠ best-practice, no formal benchmark. Verify withGet-Service sshd. - Attack surface reduction for the email entry point. Audit then enforce the rules that block executable content from email clients and Office child processes. MITRE M1040 Behavior Prevention on Endpoint and M1049 Antivirus/Antimalware; Microsoft ASR rules reference. Requires Defender Antivirus in active mode.
- Default-deny egress for servers. Servers rarely need arbitrary outbound TLS on odd ports; allow named destinations only. MITRE M1037; CIS Controls v8 Control 13.
- Privileged access workstations and a GPO change workflow. Only a hardened admin tier edits Group Policy, with change approval and an alert on any GPO change near a business off-hours window. MITRE M1026, M1032 Multi-factor Authentication; Microsoft enterprise access model.
- Inspect or proxy all outbound TLS from server tiers so mesh and tunnel traffic is visible even when addresses are not on a list. MITRE M1031.
- Treat an ieupdate hit as a Tier 0 compromise. Pre-plan the credential reset, SYSVOL review and rebuild procedure so containment starts hours, not days, after detection (Section 14).
Deployable Playbooks
Playbook 1: egress block of the hardcoded Yggdrasil peers (Windows Firewall)
Step 1. Block the ten raw-IP peers outbound on managed Windows hosts.
Prerequisites: local administrator or a GPO with firewall write rights; confirm no sanctioned Yggdrasil use (Q5 baseline).
Reboot required: No
$peers = @('37.205.14.171', '109.176.250.101', '65.21.57.122', '95.217.35.92', '51.255.223.60', '51.15.204.214', '62.210.85.80', '23.137.249.65', '78.27.153.163', '193.93.119.42')
New-NetFirewallRule -DisplayName 'HuntPack-Block-Yggdrasil-Peers' -Direction Outbound -Action Block -RemoteAddress $peers -Profile Any
Verify: Get-NetFirewallRule -DisplayName 'HuntPack-Block-Yggdrasil-Peers' | Get-NetFirewallAddressFilter
Rollback: Remove-NetFirewallRule -DisplayName 'HuntPack-Block-Yggdrasil-Peers'
Step 2. Sinkhole the hostname peers on the internal DNS server (Windows DNS policy shown; use your resolver's RPZ equivalent otherwise).
Prerequisites: Windows Server 2016 or later DNS role; DnsServer module; run on each DNS server.
Reboot required: No
Add-DnsServerQueryResolutionPolicy -Name 'HuntPack-Block-Ygg-yt' -Action DENY -Fqdn 'EQ,*.ygg.yt'
Add-DnsServerQueryResolutionPolicy -Name 'HuntPack-Block-Ygg-neilalexander' -Action DENY -Fqdn 'EQ,yggdrasil.neilalexander.dev'
# repeat for the remaining hostnames in the Yggdrasil Public Peer List block
Verify: Resolve-DnsName g.ygg.yt -Server <dns-server> (expect a refusal)
Rollback: Remove-DnsServerQueryResolutionPolicy -Name 'HuntPack-Block-Ygg-yt' -Force (and each additional policy name)
Playbook 2: audit policy for Group Policy changes and service installs
Step 1. Record the current audit policy, then enable the two subcategories. Prerequisites: domain admin for the DC step; run the first command on every host you change. Reboot required: No auditpol /backup /file:C:\Windows\Temp\audit-before.csv auditpol /set /subcategory:"Directory Service Changes" /success:enable (domain controllers) auditpol /set /subcategory:"Security System Extension" /success:enable (all hosts) Verify: auditpol /get /subcategory:"Directory Service Changes","Security System Extension" Rollback: auditpol /restore /file:C:\Windows\Temp\audit-before.csv Note: size the Security log first; Directory Service Changes is moderately chatty on busy DCs.
Playbook 3: disable OpenSSH Server where unused
Step 1. Stop and disable the sshd service on hosts with no sanctioned SSH role.
Prerequisites: inventory of administrators who rely on SSH; confirm with Q15 baseline.
Reboot required: No
if (Get-Service sshd -ErrorAction SilentlyContinue) { Stop-Service sshd -Force; Set-Service sshd -StartupType Disabled }
New-NetFirewallRule -DisplayName 'HuntPack-Block-Inbound-22' -Direction Inbound -Protocol TCP -LocalPort 22 -Action Block
Verify: Get-Service sshd | Select Status,StartType
Rollback: Set-Service sshd -StartupType Automatic; Start-Service sshd; Remove-NetFirewallRule -DisplayName 'HuntPack-Block-Inbound-22'
Playbook 4: attack surface reduction rules in audit mode
Step 1. Audit the email-executable and Office child-process rules for 30 days before enforcing. Prerequisites: Microsoft Defender Antivirus in active mode (ASR is not applied in passive mode, so skip this on hosts where another AV is primary). Reboot required: No Add-MpPreference -AttackSurfaceReductionRules_Ids be9ba2d9-53ea-4cdc-84e5-9b1eeee46550,d4f940ab-401b-4efc-aadc-ad5f3c50688a -AttackSurfaceReductionRules_Actions AuditMode,AuditMode Verify: Get-MpPreference | Select AttackSurfaceReductionRules_Ids,AttackSurfaceReductionRules_Actions Rollback: Remove-MpPreference -AttackSurfaceReductionRules_Ids be9ba2d9-53ea-4cdc-84e5-9b1eeee46550,d4f940ab-401b-4efc-aadc-ad5f3c50688a
Playbook 5: Group Policy edit-rights review (read-only, no change)
Step 1. List who can edit or link each GPO, then review for non-Tier-0 principals.
Prerequisites: GroupPolicy module (RSAT); domain read access.
Reboot required: No
Get-GPO -All | ForEach-Object { $g=$_; Get-GPPermission -Guid $g.Id -All | Where-Object { $_.Permission -match 'GpoEdit|GpoEditDeleteModifySecurity' } | Select @{n='GPO';e={$g.DisplayName}},Trustee,Permission }
Rollback: none required, this step only reads permissions. Any later permission removal is reverted with Set-GPPermission using the saved output.
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate | Network-isolate any host with the ieupdate service, an ESET hash, a masquerade binary or a 33690 listener. Do not wait for a C&C block: the C&C is mesh-internal. Block the 32 public peers at egress and DNS. If SDelete is already fanning out, disable the offending GPO link and stop the Group Policy refresh path first | IR lead, network team | Q1, Q4, Q9, Q12 results; host isolation log |
| Isolate: by platform | CrowdStrike: network-contain the host. SentinelOne: network quarantine (Disconnect from Network; confirm the label in your console version). Microsoft Defender: Isolate device (full network isolation). | IR lead, network team | Q1, Q4, Q9, Q12 results; host isolation log |
| Scope | Run Q1 to Q15 over 90 days. Pivot on each hit host for binaries written in the prior 15 minutes (Q2), SFTP server activity (Q15) and the pdfopentask / UpdateMonitor chain (Q13). Treat 2025-07-17-style timing, backdoor first and wiper weeks later, as the expected pattern | Threat hunter | Query exports; host timeline |
| Eradicate | Stop and delete the ieupdate service (sc.exe stop ieupdate, sc.exe delete ieupdate) after imaging; remove the binaries and the hidden .updatecache and .crond files; remove pdfopentask and the UpdateMonitor Run value; reset credentials for any account that edited Group Policy. If a domain admin credential could have been exposed, follow the full AD recovery procedure including resetting the krbtgt account twice | IR lead, AD team | Forensic images; before and after service lists; GPO change log |
| Recover | Restore wiped hosts from offline backups, rebuild before re-joining the domain, review SYSVOL and every GPO for unexpected scheduled tasks and scripts, then re-enable the removed GPO links in a staged way | Infrastructure team | Restore test log; SYSVOL diff |
| Harden | Apply Section 12 immediate controls first (peer block, audit policy, GPO rights, offline backups), then the near-term list | Security engineering | Verification commands from Section 13 |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | CrowdStrike coverage | SentinelOne | Defender XDR |
|---|---|---|---|---|---|---|
| T1543.003 | Service ieupdate and masquerade service images | Q1, Q3, Q4 | Q3 | Good name, path and hash. A renamed service with a new binary is missed except by Q10, Q8 and Q9 | Partial: Q1 approximate | Partial: Q1 approximate |
| T1036.005 | Masquerade names written or run from observed paths | Q2, Q3, Q4 | Q3 | Partial path-bound to ESET-observed locations; new paths are missed | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1090.003 / T1573 | Mesh C&C and public-peer joins | Q5, Q6, Q7, Q8 | Q5 | Partial underlay only; overlay traffic is user-space and invisible. Peer list is static (32 entries) | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1090.001 | bindProxy SOCKS5 on 33690 | Q9, Q4 | Q9 | Good if the sensor reports loopback listeners; confirm on a tenant | Partial: Q9 approximate | Good, with assumptions |
| T1059.003 | shell command through cmd.exe | Q10 | Q10 | Good for the masquerade-parent case; a renamed parent is missed | Good, with assumptions | Good, with assumptions |
| T1027.013 | Hidden encrypted config files | Q10 | - | GAP file creation of .updatecache and .crond is outside endpoint telemetry; native hunt 6 and Sysmon EID 11 | GAP: same limit as CrowdStrike | GAP: same limit as CrowdStrike |
| T1113 / T1005 / T1041 | screenshot, ls, download, exfiltration | - | - | GAP in-process and mesh-internal; no telemetry | GAP | GAP |
| T1678 | 10-minute start delay | - | - | Partial behavioral only; use 30-day windows | No query | No query |
| T1021.004 / T1570 | OpenSSH SFTP lateral transfer | Q15, Q2 | - | Partial depends on the host baseline | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1053.005 / T1547.001 | pdfopentask, temporarydoc.txt, UpdateMonitor | Q13 | Q13 | Good for this intrusion's names only; the wider UAC-0099 chain is a separate pack | Partial: Q13 approximate | Partial: Q13 telemetry gap |
| T1071.001 | MATCHWOK domains | Q14 | - | Partial two domains; ESET-only | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| T1484.001 | Group Policy modification | - | - | GAP domain-controller audit events, not endpoint telemetry; native hunts 3 to 5 | GAP | GAP |
| T1485 | SDelete data wiping | Q11, Q12 | Q11 | Partial execution is seen, the overwrite itself is not; Q12 is strongest at fleet scale | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike |
| Linux variant | Hints of a Unix build (.crond, /tmp/.test_config) | - | - | GAP no sample or ESET indicators; unhunted | GAP | GAP |
Validation gates (Section 11) apply: no IOA leaves Detect before a 14-day baseline. Largest gaps: config-file creation, Group Policy edits on the domain controller, and anything that happens inside the mesh.
Hunt Summary Ticket
TITLE: MythicRatatoskr Yggdrasil-enabled backdoor and Sandworm SDelete wiping stage (UAC-0099 to Sandworm handoff) SEVERITY: Critical (destructive follow-on, state-aligned actor; ESET report 2026-10-22) SCOPE: Windows endpoints and servers, domain controllers and Group Policy; egress to public Yggdrasil peers HYPOTHESIS: A masquerade-named Go service (ieupdate) is beaconing through public Yggdrasil peers, and a later Group Policy-delivered SDelete run wipes the estate QUERIES: Q1 to Q15 (Section 8); IOA candidates Q3, Q5, Q9, Q10, Q11, Q13 (Section 9); native hunts (Section 7) DO FIRST: 1. Run Q1, Q4 and Q9 over 30 days; run Q12 for any SDelete fan-out 2. Block the 32 public Yggdrasil peers at egress and DNS (Section 13, Playbook 1) 3. Verify offline backups and review who can edit Group Policy (Playbook 5) FINDINGS: [populate per engagement] GAPS: config-file creation, screenshot and file reads, Group Policy edits and all mesh-internal traffic are outside endpoint telemetry; Linux variant unhunted (Section 15) ACTIONS: block peers; isolate hits; audit GPO changes; protect backups; reset GPO-admin credentials on any hit OWNER: [assign per engagement] VERSION: v0.1, 2026-10-23
Changelog
References
| Tier | Source | Used For | Access Date |
|---|---|---|---|
| 1 | ESET Research, MythicRatatoskr report (2026-10-22) | All technical detail, hashes, C&C, peers, ATT&CK table | 2026-10-23 |
| 1 | ESET malware-ioc, mythicratatoskr folder | Hash table cross-check; SHA-1 discrepancy | 2026-10-23 |
| 2 | The Record, "Russian hackers teamed up to wipe data at Ukrainian grain firm" | Independent narrative corroboration | 2026-10-23 |
| 2 | The Next Web, ESET Yggdrasil report coverage | Independent narrative corroboration; SDelete and dates | 2026-10-23 |
| 1 | MITRE ATT&CK T1485 Data Destruction | Mapping and mitigation M1053 | 2026-10-23 |
| 1 | MITRE ATT&CK T1484.001 Group Policy Modification | Mapping and auditing guidance | 2026-10-23 |
| 1 | MITRE ATT&CK T1090.003 Multi-hop Proxy | Mapping | 2026-10-23 |
| 1 | Microsoft, Attack surface reduction rules reference | ASR rule GUIDs and requirements | 2026-10-23 |