Microsoft Defender • KQL • Threat Hunting • Real Examples

Microsoft Defender KQL Threat Hunting Guide

Nothing triggered an alert.

But the data already knew.

This guide brings together practical Microsoft Defender XDR hunting examples using KQL, EmailEvents, AuthenticationDetails, spoofed domain checks, UrlClickEvents and identity pivots. It is designed for real-world investigation, not just theory.

At GEMXIT, we use KQL to move beyond alert chasing and into behaviour-based investigation across security operations, Microsoft Defender, identity and access, and broader Microsoft Security posture.

Microsoft Defender KQL threat hunting guide by Agent Foskett
Guide summary

This page is a practical KQL threat hunting hub for Microsoft Defender XDR. It focuses on the exact investigation paths analysts use when something feels wrong but no obvious alert explains it.

EmailEvents and AuthenticationDetails
Spoofed domain and sender alignment checks
Real pivots into clicks, sign-ins and behaviour

Why this guide exists

People searching for spoofeddomain, EmailEvents, AuthenticationDetails and KQL are usually not browsing casually. They are investigating something. An email looked wrong. A user clicked something. A sender looked trusted. Or the logs showed a pattern that deserved a second look.
No alert triggered The activity may look clean from an alert perspective, but threat hunting asks a better question: does the behaviour make sense?
The email story does not line up A message can look legitimate to the user while SPF, DKIM, DMARC, sender alignment or authentication details tell a different story.
KQL connects the evidence The real value appears when email, URL clicks, sign-ins, endpoint activity and user behaviour are connected into one investigation path.

Start with failed email authentication

This is the practical starting point for many Microsoft Defender email investigations. It surfaces messages where SPF, DKIM or DMARC failed and provides the key fields needed to understand the sender, recipient, subject and delivery result.
email-authentication-failures.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
EmailEvents
| where Timestamp > ago(30d)
| where AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail")
| project
    Timestamp,
    SenderFromAddress,
    SenderFromDomain,
    SenderMailFromAddress,
    SenderMailFromDomain,
    RecipientEmailAddress,
    Subject,
    AuthenticationDetails,
    ThreatTypes,
    DeliveryAction
| order by Timestamp desc
What this finds Messages where authentication failed and the sender identity deserves closer review.
Why it matters Authentication failures are not always malicious, but they are often the first crack in the trust story.
Best pivot Move next into sender alignment, recipient targeting, URL clicks and sign-in activity around the same time.

Hunt for spoofed domain signals

The spoofeddomain keyword often appears in Defender hunting scenarios where analysts are trying to understand whether a message used a forged sender domain, failed authentication or suspicious alignment. This query keeps the output simple and investigation-friendly.
spoofeddomain-emailevents.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
EmailEvents
| where Timestamp > ago(30d)
| where AuthenticationDetails has "spoof"
    or AuthenticationDetails has "dmarc=fail"
| project
    Timestamp,
    SenderFromAddress,
    SenderFromDomain,
    SenderMailFromDomain,
    RecipientEmailAddress,
    Subject,
    AuthenticationDetails,
    DeliveryAction,
    NetworkMessageId
| order by Timestamp desc
Used for Finding messages where Defender telemetry suggests spoofing, authentication failure or suspicious domain usage.
Why it matters A spoofed domain can exploit user trust before the user ever notices the technical warning signs.
Agent Foskett tip Do not stop at the word spoof. Check whether the message was delivered, who received it and whether anyone clicked.

Compare visible sender and envelope sender

The user sees the visible From address. The email infrastructure also records the Mail From path. When those values tell different stories, the investigation gets interesting.
sender-domain-alignment.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
EmailEvents
| where Timestamp > ago(30d)
| where SenderFromDomain != SenderMailFromDomain
| project
    Timestamp,
    SenderFromAddress,
    SenderFromDomain,
    SenderMailFromAddress,
    SenderMailFromDomain,
    RecipientEmailAddress,
    Subject,
    AuthenticationDetails,
    DeliveryAction
| order by Timestamp desc
Used for Finding messages where the identity shown to the user does not match the underlying sending path.
What to check Review the sender, subject, authentication details and delivery action before deciding whether this is normal forwarding, a third-party sender or impersonation.
Best pivot Group by sender and subject to decide whether this is a one-off mismatch or part of a broader campaign.

Find repeated spoofing or failed-authentication campaigns

One suspicious email is interesting. The same sender, subject or domain pattern across multiple recipients is a campaign. This query turns individual messages into patterns.
campaign-patterns-by-sender.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
EmailEvents
| where Timestamp > ago(30d)
| where AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail", "spoof")
| summarize
    MessageCount = count(),
    RecipientCount = dcount(RecipientEmailAddress)
    by SenderFromAddress, SenderFromDomain, Subject, DeliveryAction
| where MessageCount >= 3
| order by MessageCount desc
Used for Finding repeated subject lines, sender identities or authentication failures across several recipients.
Why it matters Campaign patterns help separate background noise from active targeting.
How GEMXIT uses it To decide whether response should stay with one mailbox or expand into user communication, blocking, investigation and reporting.

Pivot from suspicious email to user clicks

A suspicious message is one thing. A suspicious message with a user click is something else entirely. This query joins suspicious email telemetry to URL click activity using NetworkMessageId.
email-to-url-click-pivot.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
let SuspiciousMessages =
EmailEvents
| where Timestamp > ago(30d)
| where AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail", "spoof")
| project NetworkMessageId, EmailTime = Timestamp, SenderFromAddress, RecipientEmailAddress, Subject;

SuspiciousMessages
| join kind=inner (
    UrlClickEvents
    | where Timestamp > ago(30d)
    | project NetworkMessageId, ClickTime = Timestamp, AccountUpn, Url, ActionType
) on NetworkMessageId
| order by ClickTime desc
Used for Confirming whether suspicious delivery became user interaction.
What to look for Successful clicks, allowed actions, repeated clicks, strange URLs and users who interacted shortly after delivery.
Best next step Take the user and timestamp into sign-ins, device activity and mailbox activity to validate impact.

Pivot from email click to sign-in activity

The next question after a suspicious click is whether the same user showed risky or unusual authentication behaviour. This helps connect email interaction to identity activity.
click-to-signin-pivot.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
let ClickedUsers =
UrlClickEvents
| where Timestamp > ago(7d)
| where ActionType has_any ("ClickAllowed", "UrlScanInProgress")
| project AccountUpn, ClickTime = Timestamp, Url;

ClickedUsers
| join kind=inner (
    IdentityLogonEvents
    | where Timestamp > ago(7d)
    | project AccountUpn, SignInTime = Timestamp, IPAddress, Location, Application, LogonType
) on AccountUpn
| where SignInTime between ((ClickTime - 2h) .. (ClickTime + 6h))
| order by ClickTime desc
Used for Checking whether a click was followed by authentication activity that deserves investigation.
What to look for New locations, unusual IP addresses, unexpected applications, strange timing or authentication patterns that do not match the user.
Important note Table names can vary depending on licensing, connectors and data availability. The hunting mindset matters more than one exact table name.

Hunt for after-hours file activity

Not every incident starts with malware. Sometimes the first useful signal is a file downloaded at a time that does not match normal user behaviour.
after-hours-file-downloads.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
CloudAppEvents
| where Timestamp > ago(14d)
| where ActionType has_any ("FileDownloaded", "FileAccessed")
| extend HourOfDay = datetime_part("hour", Timestamp)
| where HourOfDay < 6 or HourOfDay > 20
| project
    Timestamp, AccountDisplayName, AccountId,
    IPAddress, Application, ActionType, ObjectName
| order by Timestamp desc
Used for Finding activity that may be legitimate but deserves a second look because of timing.
Why it matters Attackers often blend into legitimate services. Time-of-day analysis can expose activity that alerts ignore.
Best pivot Compare the user’s normal access history, location, IP address and file sensitivity before deciding response.

Hunt for suspicious PowerShell behaviour

PowerShell is not automatically bad. But encoded commands, hidden windows, download cradles and suspicious process chains are exactly the type of behaviour KQL is good at finding.
suspicious-powershell.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
DeviceProcessEvents
| where Timestamp > ago(14d)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where ProcessCommandLine has_any (
    "-enc", "-encodedcommand", "iex", "downloadstring",
    "invoke-webrequest", "frombase64string", "hidden"
)
| project
    Timestamp, DeviceName, AccountName,
    FileName, ProcessCommandLine, InitiatingProcessFileName
| order by Timestamp desc
Used for Finding PowerShell commands that deserve review because of obfuscation, download behaviour or suspicious execution flags.
Why it matters Attackers often use legitimate administration tools. The command line tells the story.
Best pivot Investigate the initiating process, parent chain, device timeline and related network connections.

What good KQL threat hunting looks like

Good hunting is not running one magic query. It is asking better questions, validating the evidence and connecting small signals into a useful security story.
Start with behaviour Ask what looks unusual, not just what looks malicious. Timing, sender alignment, repeated activity and context matter.
Use pivots, not guesses Move from email to click, from click to sign-in, from sign-in to device, and from device to response.
Turn findings into action The goal is not a pretty query. The goal is a decision: dismiss, monitor, block, investigate, contain or improve controls.
If you are relying on alerts alone, you are only seeing part of the picture.
KQL helps show what actually happened, not just what triggered.
Contact GEMXIT

Related Agent Foskett investigations

This guide is designed to sit beside the practical Agent Foskett stories that show how these hunting patterns appear in real environments.
Email spoofing Read The Email Came From Me for a practical story about spoofed email, sender trust and authentication checks.
Identity investigation Read The Logs Already Knew for a Sentinel-style look at impossible travel and session hijacking investigation.
Security operations Review Microsoft Security Operations to see how hunting, response and visibility fit into a broader security capability.

Final thought

KQL does not replace security judgement. It sharpens it.
At GEMXIT We use Microsoft Defender, Sentinel and Entra ID visibility to turn scattered security signals into practical investigation paths.
Agent Foskett mindset The best investigations do not start with panic. They start with one clear question: what does the data say?

If you want help improving Microsoft Defender hunting, alert investigation and security visibility, 👉 review Microsoft Defender services

Develop IT. Protect IT. GEMXIT PTY LTD | GEMXIT UK LTD

Microsoft Defender KQL Threat Hunting Guide

This guide explains how GEMXIT uses Microsoft Defender XDR and KQL to investigate suspicious email, spoofed domains, authentication failures, URL clicks, sign-in activity and endpoint behaviour.

EmailEvents AuthenticationDetails SpoofedDomain KQL

Practical KQL examples include EmailEvents queries, AuthenticationDetails filtering, spoofed domain checks, sender alignment analysis, campaign pattern detection and email-to-click investigation pivots.

Microsoft 365 Security Operations and Threat Hunting

GEMXIT uses KQL to support Microsoft 365 security operations, Microsoft Defender hunting, Sentinel investigation, Entra ID visibility and practical response planning.