← Back to SOC feed Coverage →

Automated Investigation Outcomes by Day

kql MEDIUM Azure-Sentinel
T1566
AlertEvidence
huntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-09-03T23:00:00Z · Confidence: medium

Hunt Hypothesis

This hypothesis targets adversaries leveraging phishing (T1566) to deliver malicious payloads, where automated investigations may fail to fully remediate threats or incorrectly classify alerts as clean. Proactively hunting for discrepancies between automated outcomes and raw email delivery events allows the SOC to identify missed detections or false negatives in the email security pipeline, ensuring that subtle phishing campaigns are not overlooked by automated triage.

KQL Query

let AutoRemediations =
    EmailPostDeliveryEvents
    | where Timestamp > ago(30d)
    | where ActionType == "Automated Remediation"
    | summarize arg_max(Timestamp, ActionResult) by NetworkMessageId, RecipientEmailAddress
    | project NetworkMessageId, RecipientEmailAddress, Timestamp;
let EvidenceVerdicts =
    AlertEvidence
    | where Timestamp > ago(30d)
    | where EntityType in ("MailMessage", "MailCluster")
    | extend extra = todynamic(AdditionalFields)
    | extend networkIds = iff(
        isnull(extra.NetworkMessageIds) or array_length(extra.NetworkMessageIds) == 0,
        pack_array(NetworkMessageId),
        extra.NetworkMessageIds)
    | mv-expand nmID = networkIds
    | extend lastVerdict = tolower(tostring(extra.LastVerdict)),
             threatAIList = extra.ThreatAnalysisSummary,
             threatInt = extra.ThreatIntelligence
    | extend verdictFromAnalysis = iff(array_length(threatAIList) > 0, tolower(tostring(threatAIList[0].Verdict)), ""),
             verdictTI = iff(array_length(threatInt) > 0, "malicious", "")
    | extend ThreatDetectedFlag = case(
        lastVerdict in ("malicious", "suspicious") or verdictFromAnalysis in ("malicious", "suspicious") or verdictTI == "malicious",
        true, false)
    | extend MailCountInt = toint(extra.MailCount)
    | extend Weight = iff(EntityType == "MailCluster", coalesce(MailCountInt, 1), 1)
    | summarize IsThreatDetected = any(ThreatDetectedFlag), WeightSum = max(Weight) by nmID = tostring(nmID);
AutoRemediations
| join kind=leftouter EvidenceVerdicts on $left.NetworkMessageId == $right.nmID
| extend isThreat = coalesce(IsThreatDetected, false), effectiveWeight = coalesce(WeightSum, 1)
| extend InvestigationOutcome = iif(isThreat, "Threat Detected", "Clean")
| summarize PreventionCount = sum(effectiveWeight) by Day = bin(Timestamp, 1d), InvestigationOutcome
| order by Day asc, InvestigationOutcome asc
| render timechart

Analytic Rule Definition

id: e13d7b0c-1cfa-41dd-a5cf-45d598055cef
name: Automated Investigation Outcomes by Day
description: |
  This query summarizes daily automated investigation outcomes (threat detected versus clean) by correlating automated remediation events with alert evidence, using the EmailPostDeliveryEvents and AlertEvidence tables.
description-detailed: |
  This query classifies each automated remediation as Threat Detected or Clean by deriving the verdict from AlertEvidence (last verdict, threat analysis summary, and threat intelligence), weighting mail clusters by their message count, and summarizes the daily volume of each outcome, so SOC teams can see how many post-delivery investigations actually caught a threat.
  Query is also included as part of the Defender for Office 365 solution in Sentinel: https://techcommunity.microsoft.com/blog/microsoftdefenderforoffice365blog/part-2-build-custom-email-security-reports-and-dashboards-with-workbooks-in-micr/4411303
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - EmailPostDeliveryEvents
  - AlertEvidence
tactics:
  - InitialAccess
relevantTechniques:
  - T1566
query: |
  let AutoRemediations =
      EmailPostDeliveryEvents
      | where Timestamp > ago(30d)
      | where ActionType == "Automated Remediation"
      | summarize arg_max(Timestamp, ActionResult) by NetworkMessageId, RecipientEmailAddress
      | project NetworkMessageId, RecipientEmailAddress, Timestamp;
  let EvidenceVerdicts =
      AlertEvidence
      | where Timestamp > ago(30d)
      | where EntityType in ("MailMessage", "MailCluster")
      | extend extra = todynamic(AdditionalFields)
      | extend networkIds = iff(
          isnull(extra.NetworkMessageIds) or array_length(extra.NetworkMessageIds) == 0,
          pack_array(NetworkMessageId),
          extra.NetworkMessageIds)
      | mv-expand nmID = networkIds
      | extend lastVerdict = tolower(tostring(extra.LastVerdict)),
               threatAIList = extra.ThreatAnalysisSummary,
               threatInt = extra.ThreatIntelligence
      | extend verdictFromAnalysis = iff(array_length(threatAIList) > 0, tolower(tostring(threatAIList[0].Verdict)), ""),
               verdictTI = iff(array_length(threatInt) > 0, "malicious", "")
      | extend ThreatDetectedFlag = case(
          lastVerdict in ("malicious", "suspicious") or verdictFromAnalysis in ("malicious", "suspicious") or verdictTI == "malicious",
          true, false)
      | extend MailCountInt = toint(extra.MailCount)
      | extend Weight = iff(EntityType == "MailCluster", coalesce(MailCountInt, 1), 1)
      | summarize IsThreatDetected = any(ThreatDetectedFlag), WeightSum = max(Weight) by nmID = tostring(nmID);
  AutoRemediations
  | join kind=leftouter EvidenceVerdicts on $left.NetworkMessageId == $right.nmID
  | extend isThreat = coalesce(IsThreatDetected, false), effectiveWeight = coalesce(WeightSum, 1)
  | extend InvestigationOutcome = iif(isThreat, "Threat Detected", "Clean")
  | summarize

Required Data Sources

Sentinel TableNotes
AlertEvidenceEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/Microsoft 365 Defender/Email and Collaboration Queries/Remediation/Automated Investigation Outcomes by Day.yaml