Adversaries may use geolocated delivery locations to bypass email filtering and distribute spam more effectively. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential spam campaigns and mitigate their impact before they spread widely.
KQL Query
EmailEvents
| where Timestamp > ago(30d) // last 30 days by default, replace 30d with the desired period
| where DetectionMethods has "Spam" and EmailDirection == "Inbound"
| make-series TotalSpamDetections=count(),Quarantine = countif(DeliveryLocation == "Quarantine"),Junkfolder=countif(DeliveryLocation == "Junk folder") ,Inbox=countif(DeliveryLocation == "Inbox/folder"),Failed=countif(DeliveryLocation == "Failed"),Dropped=countif(DeliveryLocation == "Dropped") default = 0 on Timestamp step 1d
// | render timechart // Uncomment this line to render as a graph
id: 5b6fcbad-675f-4d10-bfc7-054e3453f712
name: Spam detection by delivery location
description: |
This query visualises total emails with Spam detections over time summarizing the data daily by Delivery Location.
description-detailed: |
This query visualises total emails with Spam detections over time summarizing the data daily by Delivery Location in Microsoft Defender for Office 365. Visualize with chart type "Timechart".
Taken from the the Microsoft Defender for Office 365 Detections and Insights - Microsoft Sentinel workbook.
https://techcommunity.microsoft.com/blog/microsoftdefenderforoffice365blog/part-2-build-custom-email-security-reports-and-dashboards-with-workbooks-in-micr/4411303
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- EmailEvents
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
EmailEvents
| where Timestamp > ago(30d) // last 30 days by default, replace 30d with the desired period
| where DetectionMethods has "Spam" and EmailDirection == "Inbound"
| make-series TotalSpamDetections=count(),Quarantine = countif(DeliveryLocation == "Quarantine"),Junkfolder=countif(DeliveryLocation == "Junk folder") ,Inbox=countif(DeliveryLocation == "Inbox/folder"),Failed=countif(DeliveryLocation == "Failed"),Dropped=countif(DeliveryLocation == "Dropped") default = 0 on Timestamp step 1d
// | render timechart // Uncomment this line to render as a graph
version: 1.0.0
| Sentinel Table | Notes |
|---|---|
EmailEvents | Ensure this data connector is enabled |
Scenario: Internal email reporting tool sending daily summaries to the security team
Filter/Exclusion: Exclude emails sent from the internal reporting tool (e.g., sender = "reporting@company.com") or filter by email_subject LIKE '%Daily Summary%'
Scenario: Scheduled backup job sending emails to a centralized log management system
Filter/Exclusion: Exclude emails from the backup job (e.g., sender = "backup@company.com") or filter by email_subject LIKE '%Backup Status%'
Scenario: Admin task for user account provisioning that includes email notifications
Filter/Exclusion: Exclude emails from the provisioning system (e.g., sender = "provisioning@company.com") or filter by email_subject LIKE '%User Provisioning%'
Scenario: Automated alerting system sending emails to the SOC team about system health
Filter/Exclusion: Exclude emails from the alerting system (e.g., sender = "alerting@company.com") or filter by email_subject LIKE '%System Alert%'
Scenario: Email-based collaboration tool (e.g., Microsoft Teams, Slack) sending notification emails
Filter/Exclusion: Exclude emails from collaboration tools (e.g., sender = "teams@company.com") or filter by email_subject LIKE '%Notification%' or email_subject LIKE '%Collaboration%'