Email Security • KQL • EmailEvents • Microsoft 365

Detect Email Spoofing in Microsoft 365 with KQL

Sometimes the email looks legitimate. The sender appears familiar. The display name feels safe. The From address looks right. But the trust behind it is fake.

This is where KQL becomes useful. At GEMXIT, we use Defender XDR hunting to validate whether a message was genuinely sent, badly authenticated, domain-spoofed, or simply trusted too quickly. This sits right alongside stronger identity and access controls and practical security operations.

Agent Foskett email spoofing KQL briefing
Briefing summary

This page focuses on practical KQL for spoofed email hunting using EmailEvents, AuthenticationDetails, sender alignment, authentication failures and message patterns that deserve closer investigation.

Failed SPF, DKIM and DMARC signals
From domain vs Mail From checks
Real hunting pivots after the email lands

What this page is designed to solve

People searching for spoofeddomain, EmailEvents and KQL are usually trying to answer one question: did this message only look trusted, or was it actually legitimate?
The email looked real The sender name, domain, or message style can look familiar enough to trigger trust even when the underlying authentication story does not hold up.
The trust signal failed SPF, DKIM, DMARC, sender alignment and authentication details often tell the real story far more clearly than the visible From line.
The real job Good hunting is not just finding failed authentication. It is deciding whether this was harmless noise, brand impersonation, internal-looking spoofing, or part of something bigger.

Start with the KQL people actually came for

This is a practical baseline query to surface email events where authentication failed and the sender story deserves attention.
email-spoofing-baseline.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(14d)
| 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 it does Surfaces recent messages where key email authentication checks failed and gives you the sender, recipient, subject and final delivery context in one view.
What to look for Internal-looking senders, familiar domains, important-sounding subjects, and any combination of failed authentication that still resulted in delivery or user trust.
How GEMXIT uses it As the starting point only. Once something interesting appears, we pivot into sender alignment, recipient concentration, URLs, user clicks and related activity.

Check whether the visible sender and envelope sender disagree

One of the simplest and most useful checks is comparing the visible From domain with the Mail From domain. If they do not align, the message deserves a closer look.
from-vs-mailfrom-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(14d)
| where SenderFromDomain != SenderMailFromDomain
| project
    Timestamp,
    SenderFromAddress,
    SenderFromDomain,
    SenderMailFromAddress,
    SenderMailFromDomain,
    RecipientEmailAddress,
    Subject,
    AuthenticationDetails
| order by Timestamp desc
Used for Spotting messages where the visible sender identity and the actual envelope sender do not tell the same story.
Why it matters The user sees the From identity. The infrastructure often tells you something else. That gap is where spoofing and impersonation hide.
Best follow-up Filter to specific domains, sender names or recipients, then compare delivery action, URL presence and message concentration.

Hunt for internal-looking or self-addressed spoofing patterns

When a message appears to come from the same person it was sent to, or looks internal when it should not, it deserves immediate attention.
self-addressed-and-internal-looking.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
let TargetDomain = "yourdomain.com";
EmailEvents
| where Timestamp > ago(14d)
| where SenderFromDomain =~ TargetDomain
| where RecipientEmailAddress endswith TargetDomain
| where SenderFromAddress =~ RecipientEmailAddress
    or AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail")
| project Timestamp, SenderFromAddress, RecipientEmailAddress, Subject, AuthenticationDetails, DeliveryAction, UrlCount
| order by Timestamp desc
Used for Self-addressed spoofing, internal-looking impersonation, and messages that exploit familiarity more than technical sophistication.
Why it matters This is where users think “it came from me” or “it looks internal” and trust it before checking whether the identity was actually verified.
Best pivot Move straight into URL clicks, mailbox investigation, user reports, and any related sign-in or device activity around the same time.

Find repeated targeting patterns by sender or subject

Spoofing is often not a one-off. Clustering by sender, subject or recipient count helps you spot broader campaigns quickly.
repeat-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(14d)
| where AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail")
| summarize
    MessageCount = count(),
    RecipientCount = dcount(RecipientEmailAddress)
    by SenderFromAddress, SenderFromDomain, Subject
| where MessageCount >= 3
| order by MessageCount desc
Used for Identifying repeated spoofing attempts, same-subject campaigns, or one sender pattern targeting multiple recipients.
Why it matters A suspicious message becomes more important when it is clearly part of a broader delivery pattern rather than an isolated oddity.
How GEMXIT uses it To decide whether the issue is a single suspicious message, a spoofed sender campaign, or something that requires wider user communication and response.

Pivot after the email: who clicked and what happened next

Once a suspicious message is identified, the next question is simple: did anyone interact with it, and did that interaction lead to anything else?
email-to-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(14d)
| where AuthenticationDetails has_any ("spf=fail", "dkim=fail", "dmarc=fail")
| project NetworkMessageId, Timestamp, SenderFromAddress, RecipientEmailAddress, Subject;

SuspiciousMessages
| join kind=inner (
    UrlClickEvents
    | where Timestamp > ago(14d)
    | project NetworkMessageId, ClickTime = Timestamp, AccountUpn, Url, ActionType
) on NetworkMessageId
| order by ClickTime desc
Used for Linking suspicious messages to user interaction so the investigation can move from mail telemetry to actual user impact.
Best next step Take the user and timestamp into sign-ins, process activity and network events to confirm whether the click was contained or became compromise.
Why it matters The difference between suspicious delivery and real incident often appears only after the user interacts with the message.

What good email spoofing hunting looks like

The point is not to stare at one field. It is to build a clean progression from message suspicion to delivery context to user impact.
Check authentication first SPF, DKIM and DMARC failures are not the whole story, but they are usually the quickest way to separate “looks trusted” from “was verified”.
Compare visible identity with actual path The user sees the From address. The message path, envelope sender and authentication verdicts often tell you whether that trust should have existed at all.
Pivot into user impact quickly Once a message looks suspicious, move fast into clicks, device activity, sign-ins and response actions. That is where the real incident story forms.
If a message looks trusted but the authentication story fails,
that is exactly the moment security teams need better hunting, not just better hope.
Contact GEMXIT

Final thought

Spoofing works because it borrows trust. Good KQL hunting helps you prove whether that trust was justified.
At GEMXIT We use Microsoft hunting data to validate what is real, what only looks real, and what requires action across identity, email, endpoint and response.
Agent Foskett mindset The question is never just “Did SPF fail?” It is “What did the message pretend to be, who trusted it, and what happened next?”

If you want help improving Microsoft email visibility, hunting, and operational response, 👉 review Microsoft security operations

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

Email Spoofing Detection with KQL and EmailEvents

This page explains how GEMXIT uses KQL and Microsoft Defender XDR EmailEvents data to detect spoofed email, failed authentication signals and suspicious sender patterns in Microsoft 365.

How to Hunt Spoofed Email in Microsoft 365

Practical examples include AuthenticationDetails filtering, sender alignment checks, self-addressed spoofing, repeated sender patterns and pivots into user click activity.

Microsoft 365 Email Security Hunting by GEMXIT

GEMXIT uses KQL to turn suspicious email telemetry into useful investigation paths across delivery context, identity trust, user interaction and operational response.