-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[ASIM] AlertEvent - Microsoft Defender XDR Parser updates #13418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
oshezaf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments. However the major issue here is that AlertEvidence does not map well because it has multiple rows for the same alert (it lists the evidence or entities). Think about someone counring alerts using the Alerts schema.... Not something we will change at this point in time.
| | where not(disabled) | ||
| // Mapping Inspection Fields | ||
| | extend AdditionalFields = todynamic(AdditionalFields) | ||
| | extend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
project-rename for those applicable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed
| AlertVerdictDate_s = todatetime(AdditionalFields.ThreatAnalysisSummary[0].AnalysisDate), | ||
| AttackTactics = iff(Categories has_any (AttackTacticSet), replace_regex(Categories, @"[\[\]\""]", ""), ""), | ||
| AlertOriginalStatus = tostring(AdditionalFields.LastRemediationState), | ||
| AlertStatus = iif(isnotempty(AdditionalFields.LastRemediationState), iif(AdditionalFields.LastRemediationState == "Active", "Active", "Closed"), ""), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
case statement, and can use AlertOriginalStatus (splitting to to extend of course)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed
| // Mapping Device Entity | ||
| | extend | ||
| DvcId = coalesce(DeviceId, tostring(AdditionalFields.Host.MachineId)), | ||
| DvcIpAddr = coalesce(LocalIP, tostring(AdditionalFields.Host.IpInterfaces[0].Address), RemoteIP), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how RemoteIP can be a DevIpAddr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the fault of the AlertEvent schema. It does not contain DstIpAddr, where we could potentially map RemoteIP to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect RemoteIP is SrcIpAddr
| DvcOsVersion = tostring(coalesce(AdditionalFields.OSVersion, AdditionalFields.Host.OSVersion)), | ||
| DeviceName = coalesce(DeviceName, tostring(AdditionalFields.Host.NetBiosName)), | ||
| DvcScopeId = coalesce(tostring(split(AdditionalFields.AzureID, "/")[2]), (tostring(split(AdditionalFields.ResourceId, "/")[2]))) | ||
| | extend DvcIdType = iif(isnotempty(DvcId), "MDEid", "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this would depend on the DvcId selected by the coalesce operator above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking with sample data, both are the same. However, it should be FQDN, and not MDEid
According to doc,
DeviceName | string | Fully qualified domain name (FQDN) of the machine.
https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/alertevidence
| AlertEvidence | ||
| | where not(disabled) | ||
| // Mapping Inspection Fields | ||
| | extend AdditionalFields = todynamic(AdditionalFields) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't parse JSON (which is what todynamic does) prior to pre-filtering. You prefilter on the string and post verify after the parsing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Artifact of the RDA table treating this column as string and not dynamic. Will remove.
https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/alertevidence
oshezaf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can discuss the pre-fitlering topic Monday.
| | extend AdditionalFields = todynamic(AdditionalFields) | ||
| | where (isnull(starttime) or Timestamp >= starttime) | ||
| and (isnull(endtime) or Timestamp <= endtime) | ||
| and ((array_length(ipaddr_has_any_prefix) == 0) or (has_any_ipv4_prefix(LocalIP, ipaddr_has_any_prefix)) or (has_any_ipv4_prefix(tostring(AdditionalFields.Host.IpInterfaces[0].Address), ipaddr_has_any_prefix)) or (has_any_ipv4_prefix(RemoteIP, ipaddr_has_any_prefix))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was the field always dynamic? So you could just remove the todynamic? Anyways, the efficient way to do the prefiltering is not just to not convert to dynamic, but to actually use test over the entire string. Otherwise, you are back to calculated fields conditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The field was always dynamic. It is string in RDA
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comparing to WindowsEvent where EventData is dynamic, the filtering performance here should be similar.'
oshezaf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two comments:
- Requiring change - we again have here the issue of searching in a value that may not get into the normalized event (i.e. RemoteIP being matched by not selected as DcvIpAddr. Let's use again the AdditionalFields solution.
- No change required, but please look into string vs. dynamic "has" performance.
Fixes: