Query Details

Purview DLP Exchange Alert Info

Query

let alert_id = "<<<>>>";
let query_period = 1d;
let internet_message_ids = toscalar(
    AlertEvidence
    | where Timestamp > ago(query_period)
    | where AlertId == strcat("dl", alert_id) and EntityType == "MailMessage"
    | extend AdditionalFields = todynamic(AdditionalFields)
    | summarize make_set(AdditionalFields["InternetMessageId"])
);
let network_message_ids = toscalar(
    AlertEvidence
    | where Timestamp > ago(query_period)
    | where AlertId == strcat("dl", alert_id) and EntityType == "MailMessage"
    | summarize make_set(NetworkMessageId)
);
CloudAppEvents
| where Timestamp > ago(query_period)
| where ActionType == "AlertTriggered" and tostring(RawEventData["AlertId"]) == alert_id
| extend
    AlertId = tostring(RawEventData["AlertId"]),
    Data = todynamic(tostring(RawEventData["Data"]))
| extend
    UserPrincipalName = tolower(tostring(Data["f3u"])),
    Severity = tostring(Data["sev"]),
    Workload = tostring(Data["wl"]),
    SensitiveInformationContentType = split(tostring(Data["sict"]), ";"),
    SensitiveInformationTypeMatchInfo = split(tostring(Data["sitmi"]), ";")
| where Workload == "Exchange" and tostring(RawEventData["Category"]) == "DataLossPrevention"
| project
    Timestamp,
    Application,
    ActionType,
    AlertId,
    UserPrincipalName,
    Severity,
    Workload,
    SensitiveInformationContentType,
    SensitiveInformationTypeMatchInfo,
    AlertTriggered_RawEventData = RawEventData,
    AlertTriggered_ReportId = ReportId,
    // We will assume there is only 1 email associated to an alert
    InternetMessageId = tostring(internet_message_ids[0]),
    NetworkMessageId = tostring(network_message_ids[0])
| lookup kind=leftouter (
    EmailUrlInfo
    | where Timestamp > ago(query_period)
    | where NetworkMessageId == tostring(network_message_ids[0])
    | summarize EmailUrlInfo = make_list(bag_pack("Url", Url, "UrlDomain", UrlDomain, "UrlLocation", UrlLocation)) by NetworkMessageId
    ) on NetworkMessageId
| lookup kind=leftouter (
    EmailAttachmentInfo
    | where Timestamp > ago(query_period)
    | where NetworkMessageId == tostring(network_message_ids[0])
    | distinct NetworkMessageId, FileName, FileType, SHA256, FileSize
    | summarize EmailAttachmentInfo = make_list(bag_pack("FileName", FileName, "FileType", FileType, "FileSize", FileSize, "SHA256", SHA256)) by NetworkMessageId
    ) on NetworkMessageId
| lookup kind=leftouter (
    CloudAppEvents
    | where Timestamp > ago(query_period)
    | where ActionType == "AlertEntityGenerated" and tostring(RawEventData["AlertId"]) == alert_id
    | extend
        AlertId = tostring(RawEventData["AlertId"]),
        EntityType = tostring(RawEventData["EntityType"]),
        Data = todynamic(tostring(RawEventData["Data"]))
    | where EntityType == "DlpRuleMatch"
    | extend
        PolicyId = coalesce(tostring(Data["cid"]), tostring(Data["dpid"])),
        PolicyName = tostring(Data["dpn"]),
        ManagementRuleId = tostring(Data["dmrid"]),
        RuleId = tostring(Data["drid"]),
        RuleName = tostring(Data["drn"]),
        ProtectionActions = split(tostring(Data["dact"]), ", "),
        ObjectName = tostring(Data["von"]),
        DMC = split(tostring(Data["dmc"]), ","),
        SenderFromAddress = tostring(Data["mfrm"]),
        RecipientEmailAddress = split(tostring(Data["to"]), ","),
        CCEmailAddress = split(tostring(Data["cc"]), ","),
        BCCEmailAddress = split(tostring(Data["bcc"]), ",")
    | project
        AlertId,
        PolicyId,
        PolicyName,
        ManagementRuleId,
        RuleId,
        RuleName,
        DMC,
        ProtectionActions,
        Subject = ObjectName,
        SenderFromAddress,
        RecipientEmailAddress,
        CCEmailAddress,
        BCCEmailAddress,
        AlertEntityGenerated_DlpRuleMatch_RawEventData = RawEventData,
        AlertEntityGenerated_DlpRuleMatch_ReportId = ReportId
    ) on AlertId

Explanation

This KQL query is designed to gather and correlate information related to a specific alert in a data loss prevention (DLP) context. Here's a simplified breakdown of what the query does:

  1. Initialize Variables:

    • alert_id: The specific alert ID to investigate.
    • query_period: The time period for the query, set to 1 day.
  2. Retrieve Internet Message IDs:

    • Extracts the InternetMessageId from AlertEvidence where the alert ID matches and the entity type is "MailMessage".
  3. Retrieve Network Message IDs:

    • Extracts the NetworkMessageId from AlertEvidence under similar conditions as above.
  4. Filter CloudAppEvents for AlertTriggered:

    • Filters CloudAppEvents to find events where an alert was triggered, matching the specific alert ID.
    • Extracts and processes various fields such as UserPrincipalName, Severity, Workload, and sensitive information details.
  5. Filter for Exchange Workload and DataLossPrevention Category:

    • Further filters the results to only include events related to the Exchange workload and categorized under Data Loss Prevention.
  6. Project Relevant Fields:

    • Projects relevant fields including Timestamp, Application, ActionType, AlertId, UserPrincipalName, Severity, Workload, and sensitive information details.
    • Adds InternetMessageId and NetworkMessageId from the previously retrieved values.
  7. Join with Email URL Information:

    • Left outer join with EmailUrlInfo to include URL details related to the email, based on NetworkMessageId.
  8. Join with Email Attachment Information:

    • Left outer join with EmailAttachmentInfo to include attachment details related to the email, based on NetworkMessageId.
  9. Join with DlpRuleMatch Information:

    • Left outer join with CloudAppEvents to include DLP rule match details, extracting fields such as PolicyId, PolicyName, RuleId, RuleName, and email addresses (sender, recipient, CC, BCC).

The final result is a comprehensive dataset that includes alert details, email metadata, URL information, attachment details, and DLP rule match information, all correlated by the specific alert ID.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: September 19, 2024

Tables

AlertEvidence CloudAppEvents EmailUrlInfo EmailAttachmentInfo

Keywords

MailMessageCloudAppEventsAlertEvidenceEmailUrlInfoEmailAttachmentInfoDlpRuleMatch

Operators

lettoscalarwhereagoandstrcatextendtodynamicsummarizemake_settostringsplitprojectlookupkindleftoutermake_listbag_packdistinctcoalesce

Actions