The most dangerous M365 attacks cross data source boundaries — the authentication is in SigninLogs, the persistence is in AuditLogs, the data access is in CloudAppEvents, the exfiltration is in DeviceNetworkEvents. Single-table hunting finds indicators. Multi-table correlation finds attack chains. This subsection teaches the join patterns that campaign modules use to connect evidence across the M365 telemetry landscape.
Deliverable: Production-ready KQL join patterns for the six most common multi-table correlations in M365 hunting, with performance optimization guidance.
⏱ Estimated completion: 30 minutes
Single tables find events. Joins find attacks.
An anomalous sign-in in SigninLogs is an indicator. That sign-in followed by an inbox rule creation in CloudAppEvents followed by an OAuth consent in AuditLogs is an attack chain. The difference is the join.
Six multi-table correlation patterns appear repeatedly across the campaign modules. Learn these patterns here. Apply them in TH4 through TH13.
//Pattern:anomaloussign-in→directorymodificationinsamewindow//Usecase:AiTM→MFAregistration,roleassignment,CApolicychangeletanomalyWindow=24h;letsuspectSignIns=SigninLogs|whereTimeGenerated>ago(7d)|whereResultType==0|whereRiskLevelDuringSignInin("medium","high")|projectSignInTime=TimeGenerated,UserPrincipalName,IPAddress,tostring(LocationDetails.countryOrRegion);//Join:whatdirectorychangesdidtheseusersmake?AuditLogs|whereTimeGenerated>ago(7d)|whereResult=="success"|extendActor=tostring(InitiatedBy.user.userPrincipalName)|joinkind=innersuspectSignInson$left.Actor==$right.UserPrincipalName|whereTimeGeneratedbetween(SignInTime..(SignInTime+anomalyWindow))//Directorychangeswithin24hofariskysign-in//Relevantoperations:"User registered security info",//"Add member to role","Update conditional access policy",//"Consent to application"|projectTimeGenerated,Actor,OperationName,SignInTime,IPAddress
Did the cloud-plane compromise reach the endpoint? The OAuth consent is in AuditLogs. The file download is in CloudAppEvents. The execution is in DeviceProcessEvents.
Pattern 6: Audit log + service principal sign-in correlation
What happened after an application was consented? The consent is in AuditLogs. The application’s subsequent authentication is in AADServicePrincipalSignInLogs.
//Pattern:consentevent→appsign-in→dataaccess//Usecase:OAuthpersistenceinvestigation(TH6)letrecentConsents=AuditLogs|whereTimeGenerated>ago(90d)|whereOperationName=="Consent to application"|whereResult=="success"|extendAppId=tostring(TargetResources[0].id)|extendConsentedBy=tostring(InitiatedBy.user.userPrincipalName)|projectConsentTime=TimeGenerated,AppId,ConsentedBy;AADServicePrincipalSignInLogs|whereTimeGenerated>ago(90d)|joinkind=innerrecentConsentsonAppId|whereTimeGenerated>ConsentTime//Appsign-insAFTERconsentwasgranted|summarizeSignInCount=count(),UniqueIPs=dcount(IPAddress),IPs=make_set(IPAddress,5)byAppId,ConsentedBy//Highsign-incountfrommanyIPspost-consent=suspicious//Lowsign-incountfromexpectedIP=likelylegitimateapp
Performance optimization
Multi-table joins are expensive. Advanced Hunting will timeout on poorly structured joins against large tables.
Pre-filter before joining. Always reduce each table to the minimum rows needed before the join. The let pattern — creating a filtered dataset and then joining against it — is not a style preference. It is a performance necessity. A join between two unfiltered 30-day tables will timeout. A join between a filtered set of 50 suspect users and a 7-day window of activity will complete in seconds.
Use kind=inner for most hunting joins. Inner join returns only rows that match on both sides. This is usually what you want — “show me the cloud activity for users who had anomalous sign-ins.” Use kind=leftouter only when you need to see users who had anomalous sign-ins but no cloud activity (the absence of activity may itself be an indicator).
Avoid join on high-cardinality columns. Joining on IPAddress across two large tables produces massive intermediate result sets. Instead, pre-filter one table to a small set of IPs (suspect IPs from the hypothesis), then join.
Figure TH1.9 — Six multi-table correlation patterns. Each connects two or more M365 data sources to trace attack chains across the telemetry landscape.
Try it yourself
Exercise: Run Pattern 5 in your environment
Pattern 5 (interactive → non-interactive IP mismatch) is the most immediately useful. Run it against your Sentinel workspace or Advanced Hunting.
Examine the results. How many users show non-interactive token refreshes from IPs not in their 30-day interactive baseline? Most will be legitimate (VPN, mobile network switching). Look for users where the non-interactive IP is in a different country from all interactive sign-ins — those warrant enrichment across the five dimensions from TH1.4.
⚠ Compliance Myth: "We can hunt effectively within a single data source"
The myth: Each data source can be hunted independently. Cross-table correlation is an advanced technique for later.
The reality: The most dangerous M365 attacks deliberately cross data source boundaries because they know most detection rules query a single table. AiTM phishing spans EmailEvents (delivery), SigninLogs (authentication), AuditLogs (persistence), and CloudAppEvents (post-compromise). A hunt that examines only SigninLogs finds the anomalous sign-in but misses the phishing email that confirms it and the inbox rule that proves persistence. Single-table hunting is valid for orientation queries (step 1). The indicator, enrichment, and pivot queries (steps 2–4) almost always require multi-table correlation to build sufficient confidence for escalation.
Extend these patterns
The six patterns cover the most common correlations. Campaign modules introduce technique-specific correlations that extend these — for example, TH12 (ransomware pre-encryption) correlates DeviceProcessEvents with DeviceFileEvents and DeviceNetworkEvents in a time-sequenced chain (reconnaissance tool execution → backup disruption → C2 beaconing). The principle is the same: pre-filter each table, join on entity (user, device, IP), and constrain by time window. The specific tables and correlation logic change per technique.
The full course continues with advanced topics, production detection rules, worked investigation scenarios, and deployable artifacts. Premium subscribers get access to all courses.