\\d+))?', dynamic([\"IPAddress\", \"Port\"]), ClientIP)[0]\n | extend IPAddress = iff(array_length(ClientIPValues) > 0, tostring(ClientIPValues[0]), '')\n | extend OfficeActivity_TimeGenerated = TimeGenerated\n )\n on $left.TI_ipEntity == $right.IPAddress\n // Filter out OfficeActivity events that occurred after the expiration of the corresponding indicator\n | where OfficeActivity_TimeGenerated < ExpirationDateTime\n // Group the results by IndicatorId and keep the OfficeActivity event with the latest timestamp\n | summarize OfficeActivity_TimeGenerated = arg_max(OfficeActivity_TimeGenerated, *) by IndicatorId\n // Select the desired output fields\n | project OfficeActivity_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\n TI_ipEntity, ClientIP, UserId, Operation, ResultStatus, RecordType, OfficeObjectId, NetworkIP, NetworkDestinationIP, NetworkSourceIP, EmailSourceIpAddress, Type\n | extend timestamp = OfficeActivity_TimeGenerated, Name = tostring(split(UserId, '@', 0)[0]), UPNSuffix = tostring(split(UserId, '@', 1)[0])\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -5019,35 +4268,35 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "Name"
+ "columnName": "Name",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UPNSuffix"
+ "columnName": "UPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "TI_ipEntity"
+ "columnName": "TI_ipEntity",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Url"
+ "columnName": "Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -5103,7 +4352,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IPEntity_SigninLogs_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "IPEntity_SigninLogs_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion26')]",
@@ -5120,7 +4369,7 @@
"description": "This query maps any IP indicators of compromise (IOCs) from threat intelligence (TI), by searching for matches in SigninLogs.",
"displayName": "TI Map IP Entity to SigninLogs",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet aadFunc = (tableName:string){\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(NetworkIP) or isnotempty(EmailSourceIpAddress) or isnotempty(NetworkDestinationIP) or isnotempty(NetworkSourceIP)\n// As there is potentially more than 1 indicator type for matching IP, taking NetworkIP first, then others if that is empty.\n// Taking the first non-empty value based on potential IOC match availability\n| extend TI_ipEntity = iff(isnotempty(NetworkIP), NetworkIP, NetworkDestinationIP)\n| extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n| extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(EmailSourceIpAddress), EmailSourceIpAddress, TI_ipEntity)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n table(tableName) | where TimeGenerated >= ago(dt_lookBack)\n | extend Status = todynamic(Status), LocationDetails = todynamic(LocationDetails)\n | extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails), StatusReason = tostring(Status.failureReason)\n | extend State = tostring(LocationDetails.state), City = tostring(LocationDetails.city), Region = tostring(LocationDetails.countryOrRegion)\n // renaming time column so it is clear the log this came from\n | extend SigninLogs_TimeGenerated = TimeGenerated, Type = Type\n)\non $left.TI_ipEntity == $right.IPAddress\n| where SigninLogs_TimeGenerated < ExpirationDateTime\n| summarize SigninLogs_TimeGenerated = arg_max(SigninLogs_TimeGenerated, *) by IndicatorId, IPAddress\n| project SigninLogs_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\nTI_ipEntity, IPAddress, UserPrincipalName, AppDisplayName, StatusCode, StatusDetails, StatusReason, NetworkIP, NetworkDestinationIP, NetworkSourceIP, EmailSourceIpAddress, Type\n| extend timestamp = SigninLogs_TimeGenerated, Name = tostring(split(UserPrincipalName, '@', 0)[0]), UPNSuffix = tostring(split(UserPrincipalName, '@', 1)[0])\n};\nlet aadSignin = aadFunc(\"SigninLogs\");\nlet aadNonInt = aadFunc(\"AADNonInteractiveUserSignInLogs\");\nunion isfuzzy=true aadSignin, aadNonInt\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet aadFunc = (tableName:string){\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(NetworkIP) or isnotempty(EmailSourceIpAddress) or isnotempty(NetworkDestinationIP) or isnotempty(NetworkSourceIP)\n// As there is potentially more than 1 indicator type for matching IP, taking NetworkIP first, then others if that is empty.\n// Taking the first non-empty value based on potential IOC match availability\n| extend TI_ipEntity = iff(isnotempty(NetworkIP), NetworkIP, NetworkDestinationIP)\n| extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n| extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(EmailSourceIpAddress), EmailSourceIpAddress, TI_ipEntity)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n table(tableName) | where TimeGenerated >= ago(dt_lookBack)\n | extend Status = todynamic(Status), LocationDetails = todynamic(LocationDetails)\n | extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails), StatusReason = tostring(Status.failureReason)\n | extend State = tostring(LocationDetails.state), City = tostring(LocationDetails.city), Region = tostring(LocationDetails.countryOrRegion)\n // renaming time column so it is clear the log this came from\n | extend SigninLogs_TimeGenerated = TimeGenerated, Type = Type\n)\non $left.TI_ipEntity == $right.IPAddress\n| where SigninLogs_TimeGenerated < ExpirationDateTime\n| summarize SigninLogs_TimeGenerated = arg_max(SigninLogs_TimeGenerated, *) by IndicatorId, IPAddress\n| project SigninLogs_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\nTI_ipEntity, IPAddress, UserPrincipalName, AppDisplayName, StatusCode, StatusDetails, StatusReason, NetworkIP, NetworkDestinationIP, NetworkSourceIP, EmailSourceIpAddress, Type\n| extend timestamp = SigninLogs_TimeGenerated, Name = tostring(split(UserPrincipalName, '@', 0)[0]), UPNSuffix = tostring(split(UserPrincipalName, '@', 1)[0])\n};\nlet aadSignin = aadFunc(\"SigninLogs\");\nlet aadNonInt = aadFunc(\"AADNonInteractiveUserSignInLogs\");\nunion isfuzzy=true aadSignin, aadNonInt\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -5166,35 +4415,35 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "Name"
+ "columnName": "Name",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UPNSuffix"
+ "columnName": "UPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "IPAddress"
+ "columnName": "IPAddress",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Url"
+ "columnName": "Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -5250,7 +4499,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IPEntity_VMConnection_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "IPEntity_VMConnection_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion27')]",
@@ -5267,7 +4516,7 @@
"description": "This query maps any IP indicators of compromise (IOCs) from threat intelligence (TI), by searching for matches in VMConnection.",
"displayName": "TI Map IP Entity to VMConnection",
"enabled": false,
- "query": "let dt_lookBack = 1h; // Look back 1 hour for VMConnection events\nlet ioc_lookBack = 14d; // Look back 14 days for threat intelligence indicators\n// Fetch threat intelligence indicators related to IP addresses\nlet IP_Indicators = ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack)\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n | where Active == true and ExpirationDateTime > now()\n | where isnotempty(NetworkIP) or isnotempty(EmailSourceIpAddress) or isnotempty(NetworkDestinationIP) or isnotempty(NetworkSourceIP)\n | extend TI_ipEntity = iff(isnotempty(NetworkIP), NetworkIP, NetworkDestinationIP)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(EmailSourceIpAddress), EmailSourceIpAddress, TI_ipEntity)\n | where ipv4_is_private(TI_ipEntity) == false and TI_ipEntity !startswith \"fe80\" and TI_ipEntity !startswith \"::\" and TI_ipEntity !startswith \"127.\";\n// Perform a join between IP indicators and VMConnection events\nIP_Indicators\n // Use innerunique to keep performance fast and result set low, as we only need one match to indicate potential malicious activity that needs investigation\n | join kind=innerunique (\n VMConnection\n | where TimeGenerated >= ago(dt_lookBack)\n | extend VMConnection_TimeGenerated = TimeGenerated\n )\n on $left.TI_ipEntity == $right.RemoteIp\n // Filter out VMConnection events that occurred after the expiration of the corresponding indicator\n | where VMConnection_TimeGenerated < ExpirationDateTime\n // Group the results by IndicatorId and keep the VMConnection event with the latest timestamp\n | summarize VMConnection_TimeGenerated = arg_max(VMConnection_TimeGenerated, *) by IndicatorId, RemoteIp\n // Select the desired output fields\n | project VMConnection_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\n TI_ipEntity, Computer, Direction, ProcessName, SourceIp, DestinationIp, RemoteIp, Protocol, DestinationPort, NetworkIP, NetworkDestinationIP, NetworkSourceIP, EmailSourceIpAddress, Type\n | extend timestamp = VMConnection_TimeGenerated, HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
+ "query": "let dt_lookBack = 1h; // Look back 1 hour for VMConnection events\nlet ioc_lookBack = 14d; // Look back 14 days for threat intelligence indicators\n// Fetch threat intelligence indicators related to IP addresses\nlet IP_Indicators = ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack)\n | where Active == true and ExpirationDateTime > now()\n | where isnotempty(NetworkIP) or isnotempty(EmailSourceIpAddress) or isnotempty(NetworkDestinationIP) or isnotempty(NetworkSourceIP)\n | extend TI_ipEntity = iff(isnotempty(NetworkIP), NetworkIP, NetworkDestinationIP)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(EmailSourceIpAddress), EmailSourceIpAddress, TI_ipEntity)\n | where ipv4_is_private(TI_ipEntity) == false and TI_ipEntity !startswith \"fe80\" and TI_ipEntity !startswith \"::\" and TI_ipEntity !startswith \"127.\"\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId;\n// Perform a join between IP indicators and VMConnection events\nIP_Indicators\n // Use innerunique to keep performance fast and result set low, as we only need one match to indicate potential malicious activity that needs investigation\n | join kind=innerunique (\n VMConnection\n | where TimeGenerated >= ago(dt_lookBack)\n | extend VMConnection_TimeGenerated = TimeGenerated\n )\n on $left.TI_ipEntity == $right.RemoteIp\n // Filter out VMConnection events that occurred after the expiration of the corresponding indicator\n | where VMConnection_TimeGenerated < ExpirationDateTime\n // Group the results by IndicatorId and keep the VMConnection event with the latest timestamp\n | summarize VMConnection_TimeGenerated = arg_max(VMConnection_TimeGenerated, *) by IndicatorId, RemoteIp\n // Select the desired output fields\n | project VMConnection_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\n TI_ipEntity, Computer, Direction, ProcessName, SourceIp, DestinationIp, RemoteIp, Protocol, DestinationPort, NetworkIP, NetworkDestinationIP, NetworkSourceIP, EmailSourceIpAddress, Type\n | extend timestamp = VMConnection_TimeGenerated, HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -5307,35 +4556,35 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "HostName",
- "columnName": "HostName"
+ "columnName": "HostName",
+ "identifier": "HostName"
},
{
- "identifier": "DnsDomain",
- "columnName": "DnsDomain"
+ "columnName": "DnsDomain",
+ "identifier": "DnsDomain"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "RemoteIp"
+ "columnName": "RemoteIp",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Url"
+ "columnName": "Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -5391,7 +4640,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IPEntity_W3CIISLog_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "IPEntity_W3CIISLog_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion28')]",
@@ -5408,7 +4657,7 @@
"description": "This query maps any IP indicators of compromise (IOCs) from threat intelligence (TI), by searching for matches in W3CIISLog.",
"displayName": "TI Map IP Entity to W3CIISLog",
"enabled": false,
- "query": "let dt_lookBack = 1h; // Look back 1 hour for W3CIISLog events\nlet ioc_lookBack = 14d; // Look back 14 days for threat intelligence indicators\n// Fetch threat intelligence indicators related to IP addresses\nlet IP_Indicators = ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack)\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n | where Active == true and ExpirationDateTime > now()\n | where isnotempty(NetworkIP) or isnotempty(EmailSourceIpAddress) or isnotempty(NetworkDestinationIP) or isnotempty(NetworkSourceIP)\n | extend TI_ipEntity = iff(isnotempty(NetworkIP), NetworkIP, NetworkDestinationIP)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(EmailSourceIpAddress), EmailSourceIpAddress, TI_ipEntity)\n | where ipv4_is_private(TI_ipEntity) == false and TI_ipEntity !startswith \"fe80\" and TI_ipEntity !startswith \"::\" and TI_ipEntity !startswith \"127.\";\n// Perform a join between IP indicators and W3CIISLog events\nIP_Indicators\n // Use innerunique to keep performance fast and result set low, as we only need one match to indicate potential malicious activity that needs investigation\n | join kind=innerunique (\n W3CIISLog\n | where TimeGenerated >= ago(dt_lookBack)\n | where isnotempty(cIP)\n | where ipv4_is_private(cIP) == false and cIP !startswith \"fe80\" and cIP !startswith \"::\" and cIP !startswith \"127.\"\n | extend W3CIISLog_TimeGenerated = TimeGenerated\n )\n on $left.TI_ipEntity == $right.cIP\n // Filter out W3CIISLog events that occurred after the expiration of the corresponding indicator\n | where W3CIISLog_TimeGenerated < ExpirationDateTime\n // Group the results by IndicatorId and keep the W3CIISLog event with the latest timestamp\n | summarize W3CIISLog_TimeGenerated = arg_max(W3CIISLog_TimeGenerated, *) by IndicatorId, cIP\n // Select the desired output fields\n | project timestamp = W3CIISLog_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\n TI_ipEntity, Computer, sSiteName, cIP, sIP, sPort, csMethod, csUserName, scStatus, scSubStatus, scWin32Status,\n NetworkIP, NetworkDestinationIP, NetworkSourceIP, EmailSourceIpAddress, Type\n",
+ "query": "let dt_lookBack = 1h; // Look back 1 hour for W3CIISLog events\nlet ioc_lookBack = 14d; // Look back 14 days for threat intelligence indicators\n// Fetch threat intelligence indicators related to IP addresses\nlet IP_Indicators = ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack)\n | where Active == true and ExpirationDateTime > now()\n | where isnotempty(NetworkIP) or isnotempty(EmailSourceIpAddress) or isnotempty(NetworkDestinationIP) or isnotempty(NetworkSourceIP)\n | extend TI_ipEntity = iff(isnotempty(NetworkIP), NetworkIP, NetworkDestinationIP)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(EmailSourceIpAddress), EmailSourceIpAddress, TI_ipEntity)\n | where ipv4_is_private(TI_ipEntity) == false and TI_ipEntity !startswith \"fe80\" and TI_ipEntity !startswith \"::\" and TI_ipEntity !startswith \"127.\"\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId;\n// Perform a join between IP indicators and W3CIISLog events\nIP_Indicators\n // Use innerunique to keep performance fast and result set low, as we only need one match to indicate potential malicious activity that needs investigation\n | join kind=innerunique (\n W3CIISLog\n | where TimeGenerated >= ago(dt_lookBack)\n | where isnotempty(cIP)\n | where ipv4_is_private(cIP) == false and cIP !startswith \"fe80\" and cIP !startswith \"::\" and cIP !startswith \"127.\"\n | extend W3CIISLog_TimeGenerated = TimeGenerated\n )\n on $left.TI_ipEntity == $right.cIP\n // Filter out W3CIISLog events that occurred after the expiration of the corresponding indicator\n | where W3CIISLog_TimeGenerated < ExpirationDateTime\n // Group the results by IndicatorId and keep the W3CIISLog event with the latest timestamp\n | summarize W3CIISLog_TimeGenerated = arg_max(W3CIISLog_TimeGenerated, *) by IndicatorId, cIP\n // Select the desired output fields\n | project timestamp = W3CIISLog_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore,\n TI_ipEntity, Computer, sSiteName, cIP, sIP, sPort, csMethod, csUserName, scStatus, scSubStatus, scWin32Status,\n NetworkIP, NetworkDestinationIP, NetworkSourceIP, EmailSourceIpAddress, Type\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -5448,40 +4697,40 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "csUserName"
+ "columnName": "csUserName",
+ "identifier": "Name"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "HostName",
- "columnName": "Computer"
+ "columnName": "Computer",
+ "identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "cIP"
+ "columnName": "cIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Url"
+ "columnName": "Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -5537,7 +4786,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "URLEntity_AuditLogs_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "URLEntity_AuditLogs_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion29')]",
@@ -5554,7 +4803,7 @@
"description": "This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in AuditLogs.",
"displayName": "TI Map URL Entity to AuditLogs",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n AuditLogs\n | where TimeGenerated >= ago(dt_lookBack)\n // Extract the URL that is contained within the JSON data\n | extend Url = extract(\"(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+);\", 1,tostring(TargetResources))\n | where isnotempty(Url)\n | extend userPrincipalName = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)\n | extend TargetResourceDisplayName = tostring(TargetResources[0].displayName)\n | extend Audit_TimeGenerated = TimeGenerated\n) on Url\n| where Audit_TimeGenerated < ExpirationDateTime\n| summarize Audit_TimeGenerated = arg_max(Audit_TimeGenerated, *) by IndicatorId, Url\n| project Audit_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore,\nOperationName, Identity, userPrincipalName, TargetResourceDisplayName, Url\n| extend timestamp = Audit_TimeGenerated, AccountCustomEntity = userPrincipalName, HostCustomEntity = TargetResourceDisplayName, URLCustomEntity = Url\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n AuditLogs\n | where TimeGenerated >= ago(dt_lookBack)\n // Extract the URL that is contained within the JSON data\n | extend Url = extract(\"(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+);\", 1,tostring(TargetResources))\n | where isnotempty(Url)\n | extend userPrincipalName = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName)\n | extend TargetResourceDisplayName = tostring(TargetResources[0].displayName)\n | extend Audit_TimeGenerated = TimeGenerated\n) on Url\n| where Audit_TimeGenerated < ExpirationDateTime\n| summarize Audit_TimeGenerated = arg_max(Audit_TimeGenerated, *) by IndicatorId, Url\n| project Audit_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore,\nOperationName, Identity, userPrincipalName, TargetResourceDisplayName, Url\n| extend timestamp = Audit_TimeGenerated, AccountCustomEntity = userPrincipalName, HostCustomEntity = TargetResourceDisplayName, URLCustomEntity = Url\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -5594,31 +4843,31 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "AccountCustomEntity"
+ "columnName": "AccountCustomEntity",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "HostCustomEntity"
+ "columnName": "HostCustomEntity",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "URLCustomEntity"
+ "columnName": "URLCustomEntity",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -5674,7 +4923,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "URLEntity_OfficeActivity_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "URLEntity_OfficeActivity_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion30')]",
@@ -5691,7 +4940,7 @@
"description": "This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in OfficeActivity data.",
"displayName": "TI Map URL Entity to OfficeActivity Data",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n OfficeActivity\n | where TimeGenerated >= ago(dt_lookBack)\n //Extract the Url from a number of potential fields\n | extend Url = iif(OfficeWorkload == \"AzureActiveDirectory\",extract(\"(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+);\", 1,ModifiedProperties),tostring(parse_json(ModifiedProperties)[12].NewValue))\n | where isnotempty(Url)\n // Ensure we get a clean URL\n | extend Url = tostring(split(Url, ';')[0])\n | extend OfficeActivity_TimeGenerated = TimeGenerated\n // Project a single user identity that we can use for entity mapping\n | extend User = iif(isnotempty(UserId), UserId, iif(isnotempty(Actor), tostring(parse_json(Actor)[0].ID), tostring(parse_json(Parameters)[0].Value)))\n) on Url\n| where OfficeActivity_TimeGenerated < ExpirationDateTime\n| summarize OfficeActivity_TimeGenerated = arg_max(OfficeActivity_TimeGenerated, *) by IndicatorId, Url\n| project OfficeActivity_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Operation,\nUserType, OfficeWorkload, Parameters, Url, User\n| extend timestamp = OfficeActivity_TimeGenerated, Name = tostring(split(User, '@', 0)[0]), UPNSuffix = tostring(split(User, '@', 1)[0])\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n OfficeActivity\n | where TimeGenerated >= ago(dt_lookBack)\n //Extract the Url from a number of potential fields\n | extend Url = iif(OfficeWorkload == \"AzureActiveDirectory\",extract(\"(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+);\", 1,ModifiedProperties),tostring(parse_json(ModifiedProperties)[12].NewValue))\n | where isnotempty(Url)\n // Ensure we get a clean URL\n | extend Url = tostring(split(Url, ';')[0])\n | extend OfficeActivity_TimeGenerated = TimeGenerated\n // Project a single user identity that we can use for entity mapping\n | extend User = iif(isnotempty(UserId), UserId, iif(isnotempty(Actor), tostring(parse_json(Actor)[0].ID), tostring(parse_json(Parameters)[0].Value)))\n) on Url\n| where OfficeActivity_TimeGenerated < ExpirationDateTime\n| summarize OfficeActivity_TimeGenerated = arg_max(OfficeActivity_TimeGenerated, *) by IndicatorId, Url\n| project OfficeActivity_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, Operation,\nUserType, OfficeWorkload, Parameters, Url, User\n| extend timestamp = OfficeActivity_TimeGenerated, Name = tostring(split(User, '@', 0)[0]), UPNSuffix = tostring(split(User, '@', 1)[0])\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -5718,6 +4967,12 @@
"dataTypes": [
"ThreatIntelligenceIndicator"
]
+ },
+ {
+ "connectorId": "ThreatIntelligenceTaxii",
+ "dataTypes": [
+ "ThreatIntelligenceIndicator"
+ ]
}
],
"tactics": [
@@ -5725,26 +4980,26 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "Name"
+ "columnName": "Name",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UPNSuffix"
+ "columnName": "UPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Url"
+ "columnName": "Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -5800,7 +5055,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "URLEntity_PaloAlto_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "URLEntity_PaloAlto_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion31')]",
@@ -5817,7 +5072,7 @@
"description": "This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in PaloAlto Data.",
"displayName": "TI Map URL Entity to PaloAlto Data",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n CommonSecurityLog\n | extend IngestionTime = ingestion_time()\n | where IngestionTime > ago(dt_lookBack)\n // Select on Palo Alto logs\n | where DeviceVendor =~ \"Palo Alto Networks\"\n | where DeviceEventClassID =~ 'url'\n //Uncomment the line below to only alert on allowed connections\n //| where DeviceAction !~ \"block-url\"\n //Select logs where URL data is populated\n | extend PA_Url = column_ifexists(\"RequestURL\", \"None\")\n | extend PA_Url = iif(isempty(PA_Url), extract(\"([^\\\"]+)\", 1, tolower(AdditionalExtensions)), trim('\"', PA_Url))\n | extend PA_Url = iif(PA_Url !startswith \"http://\" and ApplicationProtocol !~ \"ssl\", strcat('http://', PA_Url), iif(PA_Url !startswith \"https://\" and ApplicationProtocol =~ \"ssl\", strcat('https://', PA_Url), PA_Url))\n | where isnotempty(PA_Url)\n | extend CommonSecurityLog_TimeGenerated = TimeGenerated\n) on $left.Url == $right.PA_Url\n| where CommonSecurityLog_TimeGenerated < ExpirationDateTime\n| summarize CommonSecurityLog_TimeGenerated = arg_max(CommonSecurityLog_TimeGenerated, *) by IndicatorId, PA_Url\n| project timestamp = CommonSecurityLog_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, DeviceAction, SourceIP, PA_Url, DeviceName\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n CommonSecurityLog\n | extend IngestionTime = ingestion_time()\n | where IngestionTime > ago(dt_lookBack)\n // Select on Palo Alto logs\n | where DeviceVendor =~ \"Palo Alto Networks\"\n | where DeviceEventClassID =~ 'url'\n //Uncomment the line below to only alert on allowed connections\n //| where DeviceAction !~ \"block-url\"\n //Select logs where URL data is populated\n | extend PA_Url = column_ifexists(\"RequestURL\", \"None\")\n | extend PA_Url = iif(isempty(PA_Url), extract(\"([^\\\"]+)\", 1, tolower(AdditionalExtensions)), trim('\"', PA_Url))\n | extend PA_Url = iif(PA_Url !startswith \"http://\" and ApplicationProtocol !~ \"ssl\", strcat('http://', PA_Url), iif(PA_Url !startswith \"https://\" and ApplicationProtocol =~ \"ssl\", strcat('https://', PA_Url), PA_Url))\n | where isnotempty(PA_Url)\n | extend CommonSecurityLog_TimeGenerated = TimeGenerated\n) on $left.Url == $right.PA_Url\n| where CommonSecurityLog_TimeGenerated < ExpirationDateTime\n| summarize CommonSecurityLog_TimeGenerated = arg_max(CommonSecurityLog_TimeGenerated, *) by IndicatorId, PA_Url\n| project timestamp = CommonSecurityLog_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, DeviceAction, SourceIP, PA_Url, DeviceName\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -5857,31 +5112,31 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "HostName",
- "columnName": "DeviceName"
+ "columnName": "DeviceName",
+ "identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "SourceIP"
+ "columnName": "SourceIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "PA_Url"
+ "columnName": "PA_Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -5937,7 +5192,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "URLEntity_SecurityAlerts_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "URLEntity_SecurityAlerts_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion32')]",
@@ -5954,7 +5209,7 @@
"description": "This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in SecurityAlert data.",
"displayName": "TI Map URL Entity to SecurityAlert Data",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet URLRegex = \"((https?|ftp|ldap|wss?|file):\\\\/\\\\/(([\\\\:\\\\%\\\\w\\\\_\\\\-]+(\\\\.|@))*((xn--)?[a-zA-Z0-9\\\\-]+\\\\.)+(xn--[a-z0-9]+|[A-Za-z]+)|\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{0,3})[.,:\\\\w@?^=%&\\\\/~+#-]*[\\\\w@?^=%&\\\\/~+#-])\";\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\nSecurityAlert\n| where TimeGenerated >= ago(dt_lookBack)\n| extend MSTI = case(AlertName has \"TI map\" and VendorName == \"Microsoft\" and ProductName == 'Azure Sentinel', true, false)\n| where MSTI == false\n// Extract URL from JSON data\n| extend Url = todynamic(dynamic_to_json(extract_all(URLRegex, dynamic([1]), Entities))) \n| mv-expand Url\n| extend Url = tostring(Url[0])\n// We only want alerts that actually contain URL data\n| where isnotempty(Url)\n// Extract hostname from JSON data for entity mapping\n| extend Compromised_Host = tostring(parse_json(ExtendedProperties).[\"Compromised Host\"])\n| extend Alert_TimeGenerated = TimeGenerated\n) on Url\n| where Alert_TimeGenerated < ExpirationDateTime\n| summarize Alert_TimeGenerated = arg_max(Alert_TimeGenerated, *) by IndicatorId, AlertName\n| project timestamp = Alert_TimeGenerated, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, AlertName, AlertSeverity, Description, Url, Compromised_Host\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet URLRegex = \"((https?|ftp|ldap|wss?|file):\\\\/\\\\/(([\\\\:\\\\%\\\\w\\\\_\\\\-]+(\\\\.|@))*((xn--)?[a-zA-Z0-9\\\\-]+\\\\.)+(xn--[a-z0-9]+|[A-Za-z]+)|\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{0,3})[.,:\\\\w@?^=%&\\\\/~+#-]*[\\\\w@?^=%&\\\\/~+#-])\";\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\nSecurityAlert\n| where TimeGenerated >= ago(dt_lookBack)\n| extend MSTI = case(AlertName has \"TI map\" and VendorName == \"Microsoft\" and ProductName == 'Azure Sentinel', true, false)\n| where MSTI == false\n// Extract URL from JSON data\n| extend Url = todynamic(dynamic_to_json(extract_all(URLRegex, dynamic([1]), Entities))) \n| mv-expand Url\n| extend Url = tostring(Url[0])\n// We only want alerts that actually contain URL data\n| where isnotempty(Url)\n// Extract hostname from JSON data for entity mapping\n| extend Compromised_Host = tostring(parse_json(ExtendedProperties).[\"Compromised Host\"])\n| extend Alert_TimeGenerated = TimeGenerated\n) on Url\n| where Alert_TimeGenerated < ExpirationDateTime\n| summarize Alert_TimeGenerated = arg_max(Alert_TimeGenerated, *) by IndicatorId, AlertName\n| project timestamp = Alert_TimeGenerated, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, AlertName, AlertSeverity, Description, Url, Compromised_Host\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -6000,22 +5255,22 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "HostName",
- "columnName": "Compromised_Host"
+ "columnName": "Compromised_Host",
+ "identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Url"
+ "columnName": "Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -6071,7 +5326,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "URLEntity_Syslog_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "URLEntity_Syslog_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion33')]",
@@ -6088,7 +5343,7 @@
"description": "This query identifies any URL indicators of compromise (IOCs) from threat intelligence (TI) by searching for matches in Syslog data.",
"displayName": "TI Map URL Entity to Syslog Data",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n Syslog\n | where TimeGenerated >= ago(dt_lookBack)\n // Extract URL from the Syslog message but only take messages that include URLs\n | extend Url = extract(\"(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)\", 1,SyslogMessage)\n | where isnotempty(Url)\n | extend Syslog_TimeGenerated = TimeGenerated\n) on Url\n| where Syslog_TimeGenerated < ExpirationDateTime\n| summarize Syslog_TimeGenerated = arg_max(Syslog_TimeGenerated , *) by IndicatorId, Url\n| project timestamp = Syslog_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, SyslogMessage, Computer, ProcessName, Url, HostIP\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(Url)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n// using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique (\n Syslog\n | where TimeGenerated >= ago(dt_lookBack)\n // Extract URL from the Syslog message but only take messages that include URLs\n | extend Url = extract(\"(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)\", 1,SyslogMessage)\n | where isnotempty(Url)\n | extend Syslog_TimeGenerated = TimeGenerated\n) on Url\n| where Syslog_TimeGenerated < ExpirationDateTime\n| summarize Syslog_TimeGenerated = arg_max(Syslog_TimeGenerated , *) by IndicatorId, Url\n| project timestamp = Syslog_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, SyslogMessage, Computer, ProcessName, Url, HostIP\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -6128,31 +5383,31 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "HostName",
- "columnName": "Computer"
+ "columnName": "Computer",
+ "identifier": "HostName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "HostIP"
+ "columnName": "HostIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "Url"
+ "columnName": "Url",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
]
}
@@ -6208,7 +5463,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IPEntity_DuoSecurity_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "IPEntity_DuoSecurity_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion34')]",
@@ -6225,7 +5480,7 @@
"description": "This query maps any IP indicators of compromise (IOCs) from threat intelligence (TI), by searching for matches in DuoSecurity.",
"displayName": "TI Map IP Entity to Duo Security",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(NetworkIP) or isnotempty(EmailSourceIpAddress) or isnotempty(NetworkDestinationIP) or isnotempty(NetworkSourceIP)\n// As there is potentially more than 1 indicator type for matching IP, taking NetworkIP first, then others if that is empty.\n// Taking the first non-empty value based on potential IOC match availability\n| extend TI_ipEntity = iff(isnotempty(NetworkIP), NetworkIP, NetworkDestinationIP)\n| extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n| extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(EmailSourceIpAddress), EmailSourceIpAddress, TI_ipEntity)\n| join (\n DuoSecurityAuthentication_CL\n | where TimeGenerated >= ago(dt_lookBack)\n | where isnotempty(access_device_ip_s)\n // renaming time column so it is clear the log this came from\n | extend Duo_TimeGenerated = isotimestamp_t\n)\non $left.TI_ipEntity == $right.access_device_ip_s\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| project LatestIndicatorTime, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore, Duo_TimeGenerated,\nTI_ipEntity, user_name_s, factor_s, result_s, application_name_s, event_type_s, txid_g, user_key_s, access_device_ip_s, access_device_location_city_s, access_device_location_state_s, access_device_location_country_s\n| extend timestamp = Duo_TimeGenerated, Name = tostring(split(user_name_s, '@', 0)[0]), UPNSuffix = tostring(split(user_name_s, '@', 1)[0])\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| where Active == true\n// Picking up only IOC's that contain the entities we want\n| where isnotempty(NetworkIP) or isnotempty(EmailSourceIpAddress) or isnotempty(NetworkDestinationIP) or isnotempty(NetworkSourceIP)\n// As there is potentially more than 1 indicator type for matching IP, taking NetworkIP first, then others if that is empty.\n// Taking the first non-empty value based on potential IOC match availability\n| extend TI_ipEntity = iff(isnotempty(NetworkIP), NetworkIP, NetworkDestinationIP)\n| extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n| extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(EmailSourceIpAddress), EmailSourceIpAddress, TI_ipEntity)\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| join (\n DuoSecurityAuthentication_CL\n | where TimeGenerated >= ago(dt_lookBack)\n | where isnotempty(access_device_ip_s)\n // renaming time column so it is clear the log this came from\n | extend Duo_TimeGenerated = isotimestamp_t\n)\non $left.TI_ipEntity == $right.access_device_ip_s\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| project LatestIndicatorTime, Description, ActivityGroupNames, IndicatorId, ThreatType, Url, ExpirationDateTime, ConfidenceScore, Duo_TimeGenerated,\nTI_ipEntity, user_name_s, factor_s, result_s, application_name_s, event_type_s, txid_g, user_key_s, access_device_ip_s, access_device_location_city_s, access_device_location_state_s, access_device_location_country_s\n| extend timestamp = Duo_TimeGenerated, Name = tostring(split(user_name_s, '@', 0)[0]), UPNSuffix = tostring(split(user_name_s, '@', 1)[0])\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -6265,26 +5520,26 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "Name",
- "columnName": "Name"
+ "columnName": "Name",
+ "identifier": "Name"
},
{
- "identifier": "UPNSuffix",
- "columnName": "UPNSuffix"
+ "columnName": "UPNSuffix",
+ "identifier": "UPNSuffix"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "access_device_ip_s"
+ "columnName": "access_device_ip_s",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -6340,7 +5595,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "imDns_DomainEntity_DnsEvents_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "imDns_DomainEntity_DnsEvents_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion35')]",
@@ -6439,45 +5694,45 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "HostCustomEntity"
+ "columnName": "HostCustomEntity",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "IPCustomEntity"
+ "columnName": "IPCustomEntity",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "URL",
"fieldMappings": [
{
- "identifier": "Url",
- "columnName": "URLCustomEntity"
+ "columnName": "URLCustomEntity",
+ "identifier": "Url"
}
- ]
+ ],
+ "entityType": "URL"
}
],
"customDetails": {
- "DnsQuery": "DnsQuery",
- "IndicatorId": "IndicatorId",
- "Description": "Description",
- "ThreatType": "ThreatType",
+ "QueryType": "DnsQueryType",
"ActivityGroupNames": "ActivityGroupNames",
"DNSRequestTime": "DNS_TimeGenerated",
- "QueryType": "DnsQueryType",
- "SourceIPAddress": "SrcIpAddr",
+ "IndicatorId": "IndicatorId",
+ "ThreatType": "ThreatType",
"ConfidenceScore": "ConfidenceScore",
"LatestIndicatorTime": "LatestIndicatorTime",
- "ExpirationDateTime": "ExpirationDateTime"
+ "Description": "Description",
+ "SourceIPAddress": "SrcIpAddr",
+ "ExpirationDateTime": "ExpirationDateTime",
+ "DnsQuery": "DnsQuery"
}
}
},
@@ -6532,7 +5787,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "imDns_IPEntity_DnsEvents_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "imDns_IPEntity_DnsEvents_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion36')]",
@@ -6549,7 +5804,7 @@
"description": "This rule identifies DNS requests for which response IP address is a known IoC.
\nThis analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM DNS schema.",
"displayName": "TI map IP entity to DNS Events (ASIM DNS schema)",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet IP_TI = \nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\n| extend IoC = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,\"NO_IP\")\n| where IoC != \"NO_IP\"\n;\nIP_TI\n| join kind=innerunique // using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n(\n_Im_Dns(starttime=ago(dt_lookBack))\n| where isnotempty(DnsResponseName)\n| summarize imDns_mintime=min(TimeGenerated), imDns_maxtime=max(TimeGenerated) by SrcIpAddr, DnsQuery, DnsResponseName, Dvc, EventProduct, EventVendor\n| extend addresses = extract_all (@'(\\d+\\.\\d+\\.\\d+\\.\\d+)', DnsResponseName)\n| mv-expand IoC = addresses to typeof(string)\n)\non IoC\n| where imDns_mintime < ExpirationDateTime\n| project imDns_mintime, imDns_maxtime, Description, ActivityGroupNames, IndicatorId, ThreatType, LatestIndicatorTime, ExpirationDateTime, ConfidenceScore, SrcIpAddr, IoC, Dvc, EventVendor, EventProduct, DnsQuery, DnsResponseName\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet IP_TI = \nThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| where Active == true\n| extend IoC = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,\"NO_IP\")\n| where IoC != \"NO_IP\"\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n;\nIP_TI\n| join kind=innerunique // using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n(\n_Im_Dns(starttime=ago(dt_lookBack))\n| where isnotempty(DnsResponseName)\n| summarize imDns_mintime=min(TimeGenerated), imDns_maxtime=max(TimeGenerated) by SrcIpAddr, DnsQuery, DnsResponseName, Dvc, EventProduct, EventVendor\n| extend addresses = extract_all (@'(\\d+\\.\\d+\\.\\d+\\.\\d+)', DnsResponseName)\n| mv-expand IoC = addresses to typeof(string)\n)\non IoC\n| where imDns_mintime < ExpirationDateTime\n| project imDns_mintime, imDns_maxtime, Description, ActivityGroupNames, IndicatorId, ThreatType, LatestIndicatorTime, ExpirationDateTime, ConfidenceScore, SrcIpAddr, IoC, Dvc, EventVendor, EventProduct, DnsQuery, DnsResponseName\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -6631,44 +5886,44 @@
],
"entityMappings": [
{
- "entityType": "Host",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "Dvc"
+ "columnName": "Dvc",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Host"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "IoC"
+ "columnName": "IoC",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "SrcIpAddr"
+ "columnName": "SrcIpAddr",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
],
"customDetails": {
- "DnsQuery": "DnsQuery",
- "IndicatorId": "IndicatorId",
- "Description": "Description",
- "ThreatType": "ThreatType",
"ActivityGroupNames": "ActivityGroupNames",
"DNSRequestTime": "imDns_mintime",
- "SourceIPAddress": "SrcIpAddr",
+ "IndicatorId": "IndicatorId",
+ "ThreatType": "ThreatType",
"ConfidenceScore": "ConfidenceScore",
"LatestIndicatorTime": "LatestIndicatorTime",
- "ExpirationDateTime": "ExpirationDateTime"
+ "Description": "Description",
+ "SourceIPAddress": "SrcIpAddr",
+ "ExpirationDateTime": "ExpirationDateTime",
+ "DnsQuery": "DnsQuery"
},
"alertDetailsOverride": {
"alertDisplayNameFormat": "The response {{IoC}} to DNS query matched an IoC",
@@ -6727,7 +5982,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "IPEntity_imNetworkSession_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "IPEntity_imNetworkSession_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion37')]",
@@ -6744,7 +5999,7 @@
"description": "This rule identifies a match Network Sessions for which the source or destination IP address is a known IoC.
\nThis analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM NetworkSession schema",
"displayName": "TI map IP entity to Network Session Events (ASIM Network Session schema)",
"enabled": false,
- "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet IP_TI = materialize (\n ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n | where Active == true\n | extend TI_ipEntity = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,\"NO_IP\")\n | where TI_ipEntity != \"NO_IP\"\n);\nIP_TI\n // using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique \n(\n _Im_NetworkSession (starttime=ago(dt_lookBack))\n | where isnotempty(SrcIpAddr)\n | summarize imNWS_mintime=min(TimeGenerated), imNWS_maxtime=max(TimeGenerated) by SrcIpAddr, DstIpAddr, Dvc, EventProduct, EventVendor \n | lookup (IP_TI | project TI_ipEntity, Active) on $left.SrcIpAddr == $right.TI_ipEntity\n | project-rename SrcMatch = Active\n | lookup (IP_TI | project TI_ipEntity, Active) on $left.DstIpAddr == $right.TI_ipEntity\n | project-rename DstMatch = Active\n | where SrcMatch or DstMatch\n | extend \n IoCIP = iff(SrcMatch, SrcIpAddr, DstIpAddr),\n IoCDirection = iff(SrcMatch, \"Source\", \"Destination\")\n)on $left.TI_ipEntity == $right.IoCIP\n| where imNWS_mintime < ExpirationDateTime\n| project imNWS_mintime, imNWS_maxtime, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, SrcIpAddr, DstIpAddr, IoCDirection, IoCIP, Dvc, EventVendor, EventProduct\n",
+ "query": "let dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet IP_TI = materialize (\n ThreatIntelligenceIndicator\n | where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n | where Active == true\n | extend TI_ipEntity = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,\"NO_IP\")\n | where TI_ipEntity != \"NO_IP\"\n | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n);\nIP_TI\n // using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated\n| join kind=innerunique \n(\n _Im_NetworkSession (starttime=ago(dt_lookBack))\n | where isnotempty(SrcIpAddr)\n | summarize imNWS_mintime=min(TimeGenerated), imNWS_maxtime=max(TimeGenerated) by SrcIpAddr, DstIpAddr, Dvc, EventProduct, EventVendor \n | lookup (IP_TI | project TI_ipEntity, Active) on $left.SrcIpAddr == $right.TI_ipEntity\n | project-rename SrcMatch = Active\n | lookup (IP_TI | project TI_ipEntity, Active) on $left.DstIpAddr == $right.TI_ipEntity\n | project-rename DstMatch = Active\n | where SrcMatch or DstMatch\n | extend \n IoCIP = iff(SrcMatch, SrcIpAddr, DstIpAddr),\n IoCDirection = iff(SrcMatch, \"Source\", \"Destination\")\n)on $left.TI_ipEntity == $right.IoCIP\n| where imNWS_mintime < ExpirationDateTime\n| project imNWS_mintime, imNWS_maxtime, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore, SrcIpAddr, DstIpAddr, IoCDirection, IoCIP, Dvc, EventVendor, EventProduct\n",
"queryFrequency": "PT1H",
"queryPeriod": "P14D",
"severity": "Medium",
@@ -6856,6 +6111,12 @@
"Syslog",
"CiscoMerakiNativePoller"
]
+ },
+ {
+ "connectorId": "ThreatIntelligenceTaxii",
+ "dataTypes": [
+ "ThreatIntelligenceIndicator"
+ ]
}
],
"tactics": [
@@ -6863,25 +6124,25 @@
],
"entityMappings": [
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "IoCIP"
+ "columnName": "IoCIP",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
],
"customDetails": {
- "IndicatorId": "IndicatorId",
- "IoCConfidenceScore": "ConfidenceScore",
"IoCDescription": "Description",
- "IoCExpirationTime": "ExpirationDateTime",
- "EventEndTime": "imNWS_maxtime",
+ "IoCConfidenceScore": "ConfidenceScore",
"ActivityGroupNames": "ActivityGroupNames",
+ "EventStartTime": "imNWS_mintime",
+ "IndicatorId": "IndicatorId",
"ThreatType": "ThreatType",
"IoCIPDirection": "IoCDirection",
- "EventStartTime": "imNWS_mintime"
+ "EventEndTime": "imNWS_maxtime",
+ "IoCExpirationTime": "ExpirationDateTime"
},
"alertDetailsOverride": {
"alertDisplayNameFormat": "A network session {{IoCDirection}} address {{IoCIP}} matched an IoC.",
@@ -6940,7 +6201,7 @@
"[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]"
],
"properties": {
- "description": "Threat Intel Matches to GitHub Audit Logs_AnalyticalRules Analytics Rule with template version 3.0.1",
+ "description": "Threat Intel Matches to GitHub Audit Logs_AnalyticalRules Analytics Rule with template version 3.0.2",
"mainTemplate": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "[variables('analyticRuleVersion38')]",
@@ -6991,22 +6252,22 @@
],
"entityMappings": [
{
- "entityType": "Account",
"fieldMappings": [
{
- "identifier": "FullName",
- "columnName": "AccountCustomEntity"
+ "columnName": "AccountCustomEntity",
+ "identifier": "FullName"
}
- ]
+ ],
+ "entityType": "Account"
},
{
- "entityType": "IP",
"fieldMappings": [
{
- "identifier": "Address",
- "columnName": "IPCustomEntity"
+ "columnName": "IPCustomEntity",
+ "identifier": "Address"
}
- ]
+ ],
+ "entityType": "IP"
}
]
}
@@ -7058,12 +6319,12 @@
"apiVersion": "2023-04-01-preview",
"location": "[parameters('workspace-location')]",
"properties": {
- "version": "3.0.1",
+ "version": "3.0.2",
"kind": "Solution",
"contentSchemaVersion": "3.0.0",
"displayName": "Threat Intelligence",
"publisherDisplayName": "Microsoft Sentinel, Microsoft Corporation",
- "descriptionHtml": "Note: There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Threat Intelligence solution contains data connectors for import of threat indicators into Microsoft Sentinel, analytic rules for matching TI data with event data, workbook, and hunting queries. Threat indicators can be malicious IP's, URL's, filehashes, domains, email addresses etc.
\nData Connectors: 4, Workbooks: 1, Analytic Rules: 38, Hunting Queries: 5
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
+ "descriptionHtml": "Note: There may be known issues pertaining to this Solution, please refer to them before installing.
\nThe Threat Intelligence solution contains data connectors for import of threat indicators into Microsoft Sentinel, analytic rules for matching TI data with event data, workbook, and hunting queries. Threat indicators can be malicious IP's, URL's, filehashes, domains, email addresses etc.
\nWorkbooks: 1, Analytic Rules: 38, Hunting Queries: 5
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n",
"contentKind": "Solution",
"contentProductId": "[variables('_solutioncontentProductId')]",
"id": "[variables('_solutioncontentProductId')]",
@@ -7088,26 +6349,6 @@
"dependencies": {
"operator": "AND",
"criteria": [
- {
- "kind": "DataConnector",
- "contentId": "[variables('_dataConnectorContentId1')]",
- "version": "[variables('dataConnectorVersion1')]"
- },
- {
- "kind": "DataConnector",
- "contentId": "[variables('_dataConnectorContentId2')]",
- "version": "[variables('dataConnectorVersion2')]"
- },
- {
- "kind": "DataConnector",
- "contentId": "[variables('_dataConnectorContentId3')]",
- "version": "[variables('dataConnectorVersion3')]"
- },
- {
- "kind": "DataConnector",
- "contentId": "[variables('_dataConnectorContentId4')]",
- "version": "[variables('dataConnectorVersion4')]"
- },
{
"kind": "Workbook",
"contentId": "[variables('_workbookContentId1')]",
diff --git a/Solutions/Threat Intelligence/ReleaseNotes.md b/Solutions/Threat Intelligence/ReleaseNotes.md
index c024a79d3fd..5f51f0c86d2 100644
--- a/Solutions/Threat Intelligence/ReleaseNotes.md
+++ b/Solutions/Threat Intelligence/ReleaseNotes.md
@@ -1,5 +1,6 @@
| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** |
-|-------------|--------------------------------|---------------------------------------------|
+|-------------|--------------------------------|---------------------------------------------|]
+| 3.0.2 | 23-10-2023 | Updated KQL of analytic rules to improve performance in large datasets |
| 3.0.1 | 22-08-2023 | Removed (Preview) from Name field in **Analytical Rules** |
| 3.0.0 | 14-08-2023 | Modified **Analytical Rule** (TI map Domain entity to SecurityAlert). Updated dynamic([1]) to dynamic([1,1]) so as to make result array of array consistent. |
| | | Updated **Hunting Queries** to have descriptions that meet the 255 characters limit. |