This hypothesis targets adversaries leveraging phishing campaigns (T1566) that embed malicious URLs in inbound emails to deliver malware, a common initial access vector for threat actors. Proactively hunting for trends in these URL-based detections allows the SOC to identify emerging phishing waves or specific threat actor campaigns before they result in widespread compromise within the Azure environment.
let TimeStart = startofday(ago(30d));
let TimeEnd = startofday(now());
EmailEvents
| where Timestamp >= TimeStart
| where OrgLevelPolicy != "Phishing simulation" and OrgLevelPolicy != "SecOps Mailbox"
| extend Key = strcat(NetworkMessageId, "-", RecipientEmailAddress)
| summarize arg_max(Timestamp, *) by Key
| where DetectionMethods has "Malware"
| mv-expand MalwareMethod = parse_json(DetectionMethods).Malware to typeof(string)
| where MalwareMethod contains "URL"
| make-series Count = count() default = 0 on Timestamp from TimeStart to TimeEnd step 1d by MalwareMethod
| render timechart
id: 7a25af1f-c757-490e-909d-f803b94ed8d2
name: Malware URL Detections Trend
description: |
This query visualises inbound email malware detections attributed to URL-based detection technologies over time.
description-detailed: |
This query visualises inbound email malware detections in Microsoft Defender for Office 365 over time, limited to URL-based malware detection technologies (for example URL detonation). Messages are de-duplicated to the latest record per NetworkMessageId and recipient, and deliveries to the SecOps mailbox and by the phishing simulation system are excluded.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- EmailEvents
tactics:
- InitialAccess
relevantTechniques:
- T1566
query: |
let TimeStart = startofday(ago(30d));
let TimeEnd = startofday(now());
EmailEvents
| where Timestamp >= TimeStart
| where OrgLevelPolicy != "Phishing simulation" and OrgLevelPolicy != "SecOps Mailbox"
| extend Key = strcat(NetworkMessageId, "-", RecipientEmailAddress)
| summarize arg_max(Timestamp, *) by Key
| where DetectionMethods has "Malware"
| mv-expand MalwareMethod = parse_json(DetectionMethods).Malware to typeof(string)
| where MalwareMethod contains "URL"
| make-series Count = count() default = 0 on Timestamp from TimeStart to TimeEnd step 1d by MalwareMethod
| render timechart
version: 1.0.0
| Sentinel Table | Notes |
|---|---|
EmailEvents | Ensure this data connector is enabled |
Scenario: Automated security scanning tools (e.g., Qualys, Tenable, or internal vulnerability scanners) periodically probe external or internal URLs to verify link integrity and detect broken links or redirects. These probes may trigger URL reputation engines if the target domain has a low historical score or is newly registered.
Security-Scanners network range or filter by user agent strings containing Qualys, Tenable, or Nessus.Scenario: Enterprise backup and disaster recovery solutions (e.g., Veeam, Commvault) or database replication services (e.g., SQL Server Always On, Oracle Data Guard) generate high-volume HTTP/HTTPS traffic to synchronize metadata or health check endpoints. If these endpoints are hosted on cloud storage buckets (e.g., S3, Azure Blob) with dynamic or temporary URLs, they may be flagged by URL-based malware detection if the bucket domain has a mixed reputation.
VeeamBackup, Commvault, or SQLServer, or filter by known backup service CIDR ranges.Scenario: CI/CD pipelines (e.g., Jenkins, GitLab CI, Azure DevOps) fetch dependencies, container images, or build artifacts from package registries (e.g., PyPI, npm, Docker Hub) or internal artifact repositories. These URLs are often long, dynamic, and may include version hashes that URL reputation engines misinterpret as suspicious due to their length or novelty.
CI-CD-Runners subnet or filter by user agents containing Jenkins, GitLab-Runner, or AzureDevOps.Scenario: Application health checks and monitoring agents (e.g., Dat