Query Details
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
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:
Initialize Variables:
alert_id: The specific alert ID to investigate.query_period: The time period for the query, set to 1 day.Retrieve Internet Message IDs:
InternetMessageId from AlertEvidence where the alert ID matches and the entity type is "MailMessage".Retrieve Network Message IDs:
NetworkMessageId from AlertEvidence under similar conditions as above.Filter CloudAppEvents for AlertTriggered:
CloudAppEvents to find events where an alert was triggered, matching the specific alert ID.UserPrincipalName, Severity, Workload, and sensitive information details.Filter for Exchange Workload and DataLossPrevention Category:
Project Relevant Fields:
Timestamp, Application, ActionType, AlertId, UserPrincipalName, Severity, Workload, and sensitive information details.InternetMessageId and NetworkMessageId from the previously retrieved values.Join with Email URL Information:
EmailUrlInfo to include URL details related to the email, based on NetworkMessageId.Join with Email Attachment Information:
EmailAttachmentInfo to include attachment details related to the email, based on NetworkMessageId.Join with DlpRuleMatch Information:
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.

Jose Sebastián Canós
Released: September 19, 2024
Tables
Keywords
Operators