1.8 Cross-Product Incident Correlation

10-14 hours · Module 1 · Free

Cross-Product Incident Correlation

Introduction

This subsection is not in Microsoft Learn. It teaches the skill that defines an advanced SOC analyst: tracing an attack across multiple Defender products using KQL and the unified Advanced Hunting schema.

Defender XDR automatically correlates alerts into incidents. But automated correlation has limits — it identifies connections based on shared entities, not on your understanding of the attack. This subsection teaches you to manually correlate across products when the automated correlation misses connections, or when you need to validate and extend what the automation found.

The key skill: using KQL joins and unions from Module 6 against the Advanced Hunting tables to build a complete attack narrative across email, identity, endpoint, and cloud apps.


The cross-product investigation pattern

A phishing attack touches every Defender product in sequence:

  1. Email (EmailEvents) — phishing email delivered
  2. Identity (IdentityLogonEvents) — attacker signs in with stolen credentials
  3. Cloud Apps (CloudAppEvents) — attacker creates inbox rule, accesses mailbox
  4. Endpoint (DeviceProcessEvents) — if the attacker drops malware

Each step lives in a different table. The entity that connects them is the user: the email recipient is the sign-in user is the inbox rule creator is the device owner.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Complete cross-product attack timeline for a single user
let targetUser = "j.morrison";
let timeWindow = 24h;
union
    (EmailEvents
        | where Timestamp > ago(timeWindow)
        | where RecipientEmailAddress has targetUser
        | where ThreatTypes has "Phish"
        | project Timestamp, Phase = "1-Email", 
            Detail = strcat("Phishing from ", SenderFromDomain, ": ", Subject),
            SourceIP = SenderIPv4),
    (IdentityLogonEvents
        | where Timestamp > ago(timeWindow)
        | where AccountUpn has targetUser
        | where ActionType == "LogonSuccess"
        | project Timestamp, Phase = "2-Identity",
            Detail = strcat("Sign-in to ", Application),
            SourceIP = IPAddress),
    (CloudAppEvents
        | where Timestamp > ago(timeWindow)
        | where AccountDisplayName has targetUser
        | where ActionType in ("New-InboxRule", "MailItemsAccessed", "Set-Mailbox")
        | project Timestamp, Phase = "3-CloudApp",
            Detail = strcat(ActionType, " in ", Application),
            SourceIP = IPAddress),
    (DeviceProcessEvents
        | where Timestamp > ago(timeWindow)
        | where AccountName has targetUser
        | where InitiatingProcessFileName in~ ("powershell.exe", "cmd.exe", "mshta.exe")
        | project Timestamp, Phase = "4-Endpoint",
            Detail = strcat(InitiatingProcessFileName, " → ", FileName),
            SourceIP = "device-local")
| order by Timestamp asc
Expected Output — Complete Attack Timeline Across All Products
TimestampPhaseDetailSourceIP
08:021-EmailPhishing from northgate-voicemail.com: New voicemail198.51.100.44
08:142-IdentitySign-in to Exchange Online198.51.100.44
08:153-CloudAppNew-InboxRule in Exchange Online198.51.100.44
08:163-CloudAppMailItemsAccessed in Exchange Online198.51.100.44
This is the complete attack story in one query: Phishing email delivered (08:02) → credential theft via AiTM → attacker signs in from the same IP (08:14) → creates inbox rule for persistence (08:15) → accesses mailbox contents (08:16). Four events across three Defender products, connected by the user and the IP. This query runs in Advanced Hunting and gives you the full narrative that the incident correlation engine may have partially assembled. You now see it end-to-end.

When automated correlation is incomplete

XDR correlation groups alerts by shared entities. But it can miss:

  • Time-delayed connections — the phishing email arrives Monday, the credential is cracked and used Thursday. XDR may not correlate events 4 days apart.
  • Different entity representations — EmailEvents uses RecipientEmailAddress, IdentityLogonEvents uses AccountUpn. If the formats differ slightly, automatic correlation may miss the link.
  • Cross-tenant activity — if the attacker uses the stolen credential to access a partner organization, that activity is in a different tenant.

In these cases, your manual KQL correlation fills the gap. The cross-product query above is your template — adapt the time window, the user, and the tables to the specific investigation.

Try it yourself

Take the cross-product timeline query above and adapt it for one of your test users. Run it in Advanced Hunting (security.microsoft.com → Hunting → Advanced Hunting). Even if the results are sparse (lab data), verify the query runs without errors and the Phase labels appear correctly. This query template is one you will use in every investigation module.

In a lab environment, you will likely see only IdentityLogonEvents (from your test sign-ins) and possibly CloudAppEvents (if you accessed Exchange or SharePoint). EmailEvents requires email activity. DeviceProcessEvents requires an onboarded device. The query structure is what matters — verify each union branch runs individually, even if it returns no results.

Check your understanding

1. XDR correlates three alerts into an incident: phishing email, suspicious sign-in, and inbox rule creation. You suspect there may also be endpoint activity, but no endpoint alert exists. How do you check?

Pivot to Advanced Hunting and query DeviceProcessEvents for the affected user during the incident time window. The absence of an endpoint alert does not mean the endpoint is clean — it means no detection rule fired. Raw device telemetry may reveal suspicious activity that did not meet an alert threshold. This is the value of manual cross-product correlation.
If there is no endpoint alert, the endpoint is clean
Check the device page in the portal only