Free Cheatsheet

KQL Query Reference

Production detection queries for Microsoft Sentinel and Defender XDR, organized by ATT&CK tactic. 39 queries across 11 tactics, each with its source table, technique, and confidence. Copy, adapt, run. No account needed.

Part of the M365 & Entra ID Detection Reference This guide is one part of Ridgeline's unified M365 detection reference. See the full technique coverage map and the other guides in the set.

These run in Microsoft Sentinel (Logs) and Defender XDR (Advanced Hunting). Tune the time windows and thresholds to your environment before relying on them for alerting. Each query is tagged with its source table, the ATT&CK technique it detects, and a confidence level reflecting how prone it is to false positives.

Credential Access 6

Credential theft is the pivot point of most intrusions: once an attacker has valid credentials, their activity blends into legitimate authentication. These detections target the act of stealing them rather than their later use. Most of the signal is on the endpoint (DeviceProcessEvents) where the dumping tool runs, with the LSASS-access and SAM-hive queries being high-confidence because legitimate software rarely touches those in these specific ways. The cloud-side query catches MFA registration from an unexpected context, which is how attackers make stolen access durable.

LSASS access via comsvcs.dll MiniDump DeviceProcessEventsT1003.001High
DeviceProcessEvents | where Timestamp > ago(1h) | where FileName =~ "rundll32.exe" | where ProcessCommandLine has "comsvcs" and ProcessCommandLine has "MiniDump" | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName
LSASS access via Procdump DeviceProcessEventsT1003.001High
DeviceProcessEvents | where Timestamp > ago(1h) | where FileName =~ "procdump.exe" or FileName =~ "procdump64.exe" | where ProcessCommandLine has_any ("lsass", "-ma") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine
SAM hive access via reg save DeviceProcessEventsT1003.002High
DeviceProcessEvents | where Timestamp > ago(1h) | where FileName =~ "reg.exe" | where ProcessCommandLine has "save" and ProcessCommandLine has_any ("sam", "system", "security") | project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName
Credential file discovery DeviceProcessEventsT1552.001Medium
DeviceProcessEvents | where Timestamp > ago(7d) | where ProcessCommandLine has_any ("findstr /si password", "dir /s *pass*", "dir /s *cred*", "Get-ChildItem -Recurse *password*") | project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName
Kerberoasting indicators DeviceProcessEventsT1558.003High
DeviceProcessEvents | where Timestamp > ago(7d) | where ProcessCommandLine has_any ("Invoke-Kerberoast", "Get-SPNUsers", "Rubeus kerberoast") | project Timestamp, DeviceName, AccountName, ProcessCommandLine
MFA registration from suspicious context AuditLogsT1556.006High
AuditLogs | where TimeGenerated > ago(24h) | where OperationName == "User registered security info" | extend UserPrincipalName = tostring(TargetResources[0].userPrincipalName) | join kind=inner (SigninLogs | where TimeGenerated > ago(24h) | where ResultType == "0") on UserPrincipalName | where IPAddress != IPAddress1 | project TimeGenerated, UserPrincipalName, OperationName, IPAddress, IPAddress1
Tuning: The LSASS and SAM queries are high-confidence but not zero false-positive: some EDR, backup, and crash-handling tools legitimately read LSASS or save registry hives. Baseline the known-good callers in your environment and exclude them by signer or path, not by suppressing the rule.

Initial Access 4

Initial access is where the intrusion crosses your perimeter, so the signal is split between the endpoint (a malicious document or mounted image executing) and the identity plane (a sign-in that should not have succeeded). The endpoint queries look for the classic delivery patterns: Office applications spawning script interpreters, and ISO/VHD containers used to bypass Mark-of-the-Web. The SigninLogs queries catch the cloud equivalents, password spraying and impossible-travel sign-ins, where the attacker is brute-forcing or using stolen credentials from an implausible location.

Office spawning suspicious child processes DeviceProcessEventsT1204.002Medium
DeviceProcessEvents | where Timestamp > ago(7d) | where InitiatingProcessFileName in~ ("winword.exe", "excel.exe", "powerpnt.exe", "outlook.exe") | where FileName in~ ("powershell.exe", "cmd.exe", "wscript.exe", "cscript.exe", "mshta.exe", "rundll32.exe") | summarize Count = count() by DeviceName, AccountName, InitiatingProcessFileName, FileName | order by Count desc
ISO/VHD mount followed by execution DeviceFileEventsT1566.001Medium
DeviceFileEvents | where Timestamp > ago(7d) | where FileName endswith_any (".iso", ".vhd", ".vhdx", ".img") | project DeviceName, FileName, Timestamp, AccountName
Password spray detection (cloud) SigninLogsT1110.003Medium
SigninLogs | where TimeGenerated > ago(1h) | where ResultType == "50126" | summarize FailedAttempts = count(), TargetAccounts = dcount(UserPrincipalName), SourceIPs = dcount(IPAddress) by bin(TimeGenerated, 10m) | where FailedAttempts > 20 and TargetAccounts > 5
Impossible travel detection SigninLogsT1078Medium
SigninLogs | where TimeGenerated > ago(24h) | where ResultType == "0" | summarize Locations = make_set(Location), LocationCount = dcount(Location), IPs = make_set(IPAddress) by UserPrincipalName | where LocationCount > 1
Tuning: Impossible-travel and password-spray thresholds are environment-specific. VPNs, cloud egress, and mobile roaming generate benign 'impossible travel'; legitimate bulk auth (a misconfigured app) can look like spray. Tune the distance, time, and count thresholds against a week of your own baseline before alerting.

Execution 4

Execution detections catch code running through the mechanisms attackers favour because they blend in: signed LOLBins, script interpreters, and WMI. The common thread across these queries is not the binary itself (powershell.exe, mshta.exe, certutil.exe are all legitimate) but the command line, the parent process, or the network behaviour that betrays malicious intent. Read the ProcessCommandLine field, not just the FileName.

PowerShell with suspicious flags DeviceProcessEventsT1059.001Medium
DeviceProcessEvents | where Timestamp > ago(7d) | where FileName in~ ("powershell.exe", "pwsh.exe") | where ProcessCommandLine has_any ("-nop", "-noni", "-w hidden", "-enc", "-EncodedCommand", "bypass", "iex", "invoke-expression", "downloadstring", "Net.WebClient") | project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName
MSHTA executing remote content DeviceProcessEventsT1218.005High
DeviceProcessEvents | where Timestamp > ago(7d) | where FileName =~ "mshta.exe" | where ProcessCommandLine has_any ("http://", "https://", "javascript:", "vbscript:") | project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName
LOLBin download and execute DeviceProcessEventsT1105Medium
DeviceProcessEvents | where Timestamp > ago(1h) | where FileName in~ ("certutil.exe", "bitsadmin.exe", "mshta.exe") | where ProcessCommandLine has_any ("http://", "https://", "urlcache", "transfer", "download") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine
WMI process creation DeviceProcessEventsT1047Medium
DeviceProcessEvents | where Timestamp > ago(7d) | where InitiatingProcessFileName =~ "wmiprvse.exe" | where FileName !in~ ("csc.exe", "mofcomp.exe") | summarize Count = count() by DeviceName, FileName, ProcessCommandLine | where Count < 5
Tuning: These lean on command-line content matching, so they are inherently medium-confidence: legitimate administration uses the same tools. The MSHTA-with-remote-content query is higher signal because fetching remote script through mshta is almost never legitimate in a modern environment.

Persistence 6

Persistence is how an attacker survives a reboot or a remediation, so it is one of the highest-value things to hunt: finding it often means finding a foothold you did not know about. The mechanisms span the registry (Run keys, service ImagePaths), the filesystem (startup folders), WMI event subscriptions, and, in the cloud, OAuth consent grants. Watch the InitiatingProcessFileName on the endpoint queries: persistence written by a script interpreter rather than an installer is the tell.

Scheduled task from suspicious parent DeviceProcessEventsT1053.005Medium
DeviceProcessEvents | where Timestamp > ago(1h) | where FileName =~ "schtasks.exe" and ProcessCommandLine has "/create" | where InitiatingProcessFileName in~ ("cmd.exe", "powershell.exe", "wscript.exe", "cscript.exe", "mshta.exe") | project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName
Service creation with unusual binary path DeviceRegistryEventsT1543.003Medium
DeviceRegistryEvents | where Timestamp > ago(1h) | where RegistryKey has @"Services\" and RegistryValueName == "ImagePath" | where RegistryValueData has_any (@"\temp\", @"\tmp\", @"\appdata\", @"\users\public\") | project Timestamp, DeviceName, AccountName, RegistryKey, RegistryValueData
Registry run key modification DeviceRegistryEventsT1547.001Medium
DeviceRegistryEvents | where Timestamp > ago(7d) | where RegistryKey has_any (@"CurrentVersion\Run", @"CurrentVersion\RunOnce") | where ActionType in ("RegistryValueSet", "RegistryKeyCreated") | project Timestamp, DeviceName, AccountName, RegistryKey, RegistryValueName, RegistryValueData, InitiatingProcessFileName
WMI permanent event subscription DeviceEventsT1546.003High
DeviceEvents | where Timestamp > ago(1h) | where ActionType == "WmiBindEventFilterToConsumer" | project Timestamp, DeviceName, AccountName, ActionType, InitiatingProcessFileName
Startup folder file drops DeviceFileEventsT1547.001Medium
DeviceFileEvents | where Timestamp > ago(7d) | where FolderPath has @"Start Menu\Programs\Startup" | project Timestamp, DeviceName, AccountName, FileName, FolderPath, InitiatingProcessFileName
Suspicious OAuth consent grant AuditLogsT1098.003High
AuditLogs | where TimeGenerated > ago(7d) | where OperationName == "Consent to application" | extend AppName = tostring(TargetResources[0].displayName) | extend Permissions = tostring(TargetResources[0].modifiedProperties) | where Permissions has_any ("Mail.Read", "Mail.ReadWrite", "Files.ReadWrite.All", "User.ReadWrite.All") | project TimeGenerated, UserPrincipalName = tostring(InitiatedBy.user.userPrincipalName), AppName, Permissions
Tuning: Run-key and startup-folder writes happen constantly through legitimate software installation and updates. The value is in the parent process and the path: persistence dropped into a user-writable directory by powershell.exe or wscript.exe is far more interesting than a vendor installer writing to Program Files.

Lateral Movement 4

Lateral movement is the attacker spreading from the first compromised host to others, and it is where containment decisions get made: every new host in the chain widens the incident. These queries catch the common techniques, PsExec service installs, pass-the-hash (NTLM NewCredentials logons), SMB copies to admin shares, and RDP from unexpected sources. The logon-based queries (DeviceLogonEvents) are where the cross-host story assembles: follow the RemoteIP and account across hosts.

PsExec service installation DeviceProcessEventsT1570High
DeviceProcessEvents | where Timestamp > ago(1h) | where FileName =~ "psexesvc.exe" or (FileName =~ "services.exe" and ProcessCommandLine has "PSEXESVC") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine
Pass-the-Hash detection (NTLM Type 9) DeviceLogonEventsT1550.002High
DeviceLogonEvents | where Timestamp > ago(1h) | where LogonType == "NewCredentials" | where Protocol == "NTLM" | where InitiatingProcessFileName !in ("services.exe", "lsass.exe") | project Timestamp, DeviceName, AccountName, RemoteIP, Protocol, InitiatingProcessFileName
SMB file copy to admin shares DeviceFileEventsT1021.002Medium
DeviceFileEvents | where Timestamp > ago(7d) | where FolderPath has_any (@"\ADMIN$\", @"\C$\") | where FileName endswith_any (".exe", ".dll", ".bat", ".ps1") | project Timestamp, DeviceName, AccountName, FileName, FolderPath
RDP from unexpected source DeviceLogonEventsT1021.001Medium
DeviceLogonEvents | where Timestamp > ago(1h) | where LogonType == "RemoteInteractive" | where AccountName !endswith "$" | project Timestamp, DeviceName, AccountName, RemoteIP, RemoteDeviceName
Tuning: Admin tooling and legitimate remote administration produce the same artifacts as lateral movement. The pass-the-hash query (NTLM NewCredentials, excluding services.exe/lsass.exe) is high-confidence; the RDP and SMB queries need a baseline of who normally administers what before the alerts mean anything.

Defense Evasion 6

Defense evasion is the attacker actively working against your visibility, which makes these among the most important detections to get right: a successful evasion blinds your other rules. The queries here catch tampering with the security stack itself, AMSI bypasses, ETW provider tampering, Defender exclusion changes, event log clearing, and process masquerading (a system binary name running from the wrong path). Several are high-confidence precisely because there is no legitimate reason to perform them.

AMSI bypass indicators DeviceProcessEventsT1562.001Medium
DeviceProcessEvents | where Timestamp > ago(1h) | where ProcessCommandLine has_any ("AmsiScanBuffer", "amsiInitFailed", "AmsiUtils", "amsi.dll") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine
ETW provider tampering DeviceProcessEventsT1562.006High
DeviceProcessEvents | where Timestamp > ago(1h) | where ProcessCommandLine has_any ("logman stop", "logman delete", "Remove-EtwTraceProvider", "Set-EtwTraceProvider") | project Timestamp, DeviceName, AccountName, ProcessCommandLine
Process masquerading (system names from wrong paths) DeviceProcessEventsT1036.005High
DeviceProcessEvents | where Timestamp > ago(7d) | where FileName in~ ("svchost.exe", "csrss.exe", "lsass.exe", "services.exe") | where not(FolderPath has @"C:\Windows\System32" or FolderPath has @"C:\Windows\SysWOW64") | project Timestamp, DeviceName, FileName, FolderPath, SHA256
Event log clearing DeviceProcessEventsT1070.001High
DeviceProcessEvents | where Timestamp > ago(7d) | where ProcessCommandLine has_any ("wevtutil cl", "Clear-EventLog", "Remove-EventLog") | project Timestamp, DeviceName, AccountName, ProcessCommandLine
Defender exclusion modification DeviceRegistryEventsT1562.001High
DeviceRegistryEvents | where Timestamp > ago(7d) | where RegistryKey has @"Windows Defender\Exclusions" | project Timestamp, DeviceName, AccountName, RegistryKey, RegistryValueName, RegistryValueData
Encoded PowerShell from unusual parent DeviceProcessEventsT1059.001Medium
DeviceProcessEvents | where Timestamp > ago(1h) | where FileName in~ ("powershell.exe", "pwsh.exe") | where ProcessCommandLine has_any ("-enc", "-EncodedCommand") | where InitiatingProcessFileName !in~ ("svchost.exe", "services.exe") | project Timestamp, DeviceName, AccountName, ProcessCommandLine, InitiatingProcessFileName
Tuning: Event log clearing, ETW tampering, and Defender exclusion modification are high-signal because legitimate operations rarely touch them, but they are also late indicators: by the time you see them, the attacker is already established and trying to cover tracks. Treat a hit as an active incident, not a tuning candidate.

Discovery 2

Discovery is the reconnaissance an attacker runs after landing on a host, mapping the domain, the network, and the privileges available to them. Any single discovery command is benign (administrators run them too), so these queries lean on volume and clustering: a burst of recon commands from one process in a short window is the pattern, not the individual command. This is an early-stage signal, useful for catching an intrusion before the attacker acts on what they found.

Rapid discovery pattern (multiple recon commands) DeviceProcessEventsT1087Medium
DeviceProcessEvents | where Timestamp > ago(7d) | where FileName in~ ("whoami.exe", "hostname.exe", "ipconfig.exe", "net.exe", "systeminfo.exe", "tasklist.exe") | summarize CommandCount = dcount(FileName), Commands = make_set(FileName) by DeviceName, AccountName, bin(Timestamp, 10m) | where CommandCount >= 4
AD reconnaissance commands DeviceProcessEventsT1087.002Medium
DeviceProcessEvents | where Timestamp > ago(7d) | where ProcessCommandLine has_any ("nltest /dclist", "net group \"domain admins\"", "dsquery", "Get-ADUser", "Get-ADComputer") | where AccountName !endswith "$" | summarize Commands = make_set(ProcessCommandLine), Count = count() by DeviceName, AccountName, bin(Timestamp, 1h) | where Count > 3
Tuning: Discovery commands are the noisiest category for false positives because administrators, scripts, and monitoring tools run the same enumeration constantly. The rapid-pattern query mitigates this by requiring multiple distinct recon commands in a short window from the same context; do not alert on individual commands.

Collection 2

Collection is the attacker gathering what they came for before taking it, so it sits right before exfiltration in the kill chain and is a strong point to intervene. On the endpoint, the signal is archive creation, data being staged into a zip or rar for transfer. In the cloud, the highest-value collection signal for business email compromise is inbox rule creation: an attacker who has taken a mailbox sets a rule to hide or forward mail.

Archive creation (staging for exfiltration) DeviceProcessEventsT1560.001Medium
DeviceProcessEvents | where Timestamp > ago(7d) | where FileName in~ ("7z.exe", "7za.exe", "rar.exe", "winrar.exe") or (FileName =~ "powershell.exe" and ProcessCommandLine has "Compress-Archive") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine
Inbox rule creation (BEC indicator) OfficeActivityT1114.003High
OfficeActivity | where TimeGenerated > ago(7d) | where Operation in ("New-InboxRule", "Set-InboxRule") | where Parameters has_any ("DeleteMessage", "ForwardTo", "RedirectTo", "MoveToFolder") | project TimeGenerated, UserId, Operation, Parameters, ClientIP
Tuning: The inbox-rule query (OfficeActivity) is high-confidence for BEC because malicious rules have tell-tale shapes: forwarding to external addresses, or moving mail matching finance keywords to a folder the user never checks. Archive creation is medium-confidence on its own; it matters most when it correlates with prior discovery or credential access on the same host.

Exfiltration 1

Exfiltration is data leaving your environment, the outcome most incidents are ultimately about. It is also the hardest to detect cleanly from volume alone, which is why the single query here is marked low-confidence: large outbound transfers happen constantly through legitimate cloud sync, backups, and software updates. The value is in correlation, a large transfer becomes meaningful when it follows collection and credential access on the same host, or goes to a destination nothing else talks to.

Large outbound data transfer DeviceNetworkEventsT1048Low
DeviceNetworkEvents | where Timestamp > ago(7d) | where ActionType == "ConnectionSuccess" | where RemotePort in (80, 443, 8080, 8443) | where RemoteIPType == "Public" | summarize TotalBytesSent = sum(SentBytes) by DeviceName, RemoteIP | where TotalBytesSent > 50000000 | order by TotalBytesSent desc
Tuning: Do not alert on outbound volume in isolation; it will bury you in false positives from OneDrive, backup agents, and updates. Use this query as an enrichment or correlation input: pair it with the collection and C2 detections, and weight a destination that appears nowhere else in your network telemetry.

Command and Control 1

Command and control is the channel an attacker uses to operate a foothold remotely, and catching it means catching an active, ongoing compromise. Beaconing, the implant calling home at regular intervals, is the canonical signal, and the query here looks for that periodicity in network connections rather than any single connection. Modern C2 hides in normal-looking HTTPS, so the timing pattern is often a better discriminator than the destination.

Beaconing detection (regular interval connections) DeviceNetworkEventsT1071.001Medium
DeviceNetworkEvents | where Timestamp > ago(7d) | where ActionType == "ConnectionSuccess" | where RemoteIPType == "Public" | summarize ConnectionTimes = make_list(Timestamp), Count = count() by DeviceName, RemoteIP, RemotePort | where Count > 50
Tuning: Beaconing detection by interval regularity catches unsophisticated C2 but is evaded by jitter (randomised call-home timing), which most modern frameworks enable by default. Treat a hit as high-value but treat the absence of hits as no assurance; pair interval analysis with destination rarity and JA3/TLS fingerprinting where you have it.

Monitoring 3

These are not threat detections but health checks: queries that tell you whether your detection coverage is actually working. Stale MDE sensors, out-of-date AV signatures, and ASR audit visibility are the blind spots attackers exploit, and a gap here silently degrades every other query on this page. Run these on a schedule and treat a coverage gap with the same urgency as a detection, because an unmonitored host is where the next intrusion will land.

Device health: stale MDE sensors DeviceInfoHealth
DeviceInfo | where Timestamp > ago(30d) | summarize LastSeen = max(Timestamp) by DeviceId, DeviceName, OSPlatform | where LastSeen < ago(7d) | extend DaysSilent = datetime_diff('day', now(), LastSeen) | order by DaysSilent desc
AV signature currency DeviceInfoHealth
DeviceInfo | where Timestamp > ago(1d) | summarize arg_max(Timestamp, *) by DeviceId | extend SignatureAge = datetime_diff('day', now(), AntivirusSignatureUpdateTime) | where SignatureAge > 3 | project DeviceName, OSPlatform, AntivirusSignatureUpdateTime, SignatureAge
ASR audit events by rule DeviceEventsHealth
DeviceEvents | where Timestamp > ago(30d) | where ActionType startswith "Asr" | summarize AuditCount = countif(ActionType endswith "Audited"), BlockCount = countif(ActionType endswith "Blocked") by ActionType | order by AuditCount desc

From queries to detections that hold up

These hunt and detect. Windows Endpoint Investigation teaches the method behind them: validating a hit, ruling out the false positive, and reconstructing what the query surfaced into a defensible account of the incident.

Explore the course