KQL: bag unpack json into single row

55 Views Asked by At

I want the bag_unpack function into a single row instead of it turning each entity into a new row without explicitly making a summarize and make_set for every column. (This is because i will not know what the column names are)

SecurityAlert
| where TimeGenerated >ago(1d)
| mv-expand parse_json(Entities)
| evaluate bag_unpack(Entities,  OutputColumnPrefix='Entities_')
1

There are 1 best solutions below

0
HarriS On

I found this query within the SecurityAlerts workbook on content hub.

SecurityAlert
| extend Entities = iff(isempty(Entities), todynamic('[{"dummy" : ""}]'), todynamic(Entities))
| mvexpand Entities
| evaluate bag_unpack(Entities, "Entity_")
| extend Entity_Type = columnifexists("Entity_Type", "")
| extend Entity_Name = columnifexists("Entity_Name", "")
| extend Entity_ResourceId = columnifexists("Entity_ResourceId", "")
| extend Entity_Directory = columnifexists("Entity_Directory", "")
| extend Entity_Value = columnifexists("Entity_Value", "")
| extend Entity_HostName = columnifexists("Entity_HostName", "")
| extend Entity_Address = columnifexists("Entity_Address", "")
| extend Entity_ProcessId = columnifexists("Entity_ProcessId", "")
| extend Entity_Url = columnifexists("Entity_Url", "")
| extend Target = iif(Entity_Type == "account", Entity_Name, iif(Entity_Type == "azure-resource", Entity_ResourceId, iif(Entity_Type == "cloud-application", Entity_Name, iif(Entity_Type == "dns", Entity_Name, iif(Entity_Type == "file", strcat(Entity_Directory, "\\", Entity_Name), iif(Entity_Type == "filehash", Entity_Value, iif(Entity_Type == "host", Entity_HostName, iif(Entity_Type == "ip" , Entity_Address, iif(Entity_Type == "malware", Entity_HostName, iif(Entity_Type == "network-connection", Entity_Name, iif(Entity_Type == "process", Entity_ProcessId, iif(Entity_Type == "registry-key", Entity_Name, iif(Entity_Type == "registry-value", Entity_Name, iif(Entity_Type == "security-group", Entity_Name, iif(Entity_Type == "url", Entity_Url, "NoTarget")))))))))))))))
| where Entity_Type in ("account", "host", "ip", "url", "azure-resource", "cloud-application", "dns", "file", "filehash", "malware", "network-connection", "process", "registry-key", "registry-value", "security-group")
| summarize count() by Target, Entity_Type
| project-away TimeGenerated
| order by count_ desc

It almost achieves what i want, just need this per alert id with all the entities row wise per alert id.

It would be nice if there was a method to this without having so many iff operators. Because custom alerts may have custom entities which arent captured.