Skip to content

Commit 10a187e

Browse files
committed
Remove duplicate time filter in IP entity analytic rule
Eliminated a redundant 'TimeGenerated >= ago(ioc_lookBack)' filter from the IPEntity_AppServiceHTTPLogs analytic rule and updated the mainTemplate.json accordingly. This change streamlines the query logic for improved clarity and efficiency.
1 parent 4a0f8cb commit 10a187e

File tree

3 files changed

+1
-2
lines changed

3 files changed

+1
-2
lines changed

Solutions/Threat Intelligence (NEW)/Analytic Rules/IPEntity_AppServiceHTTPLogs.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ query: |
3333
| extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)
3434
// Filter out indicators without relevant IP address fields
3535
| where TimeGenerated >= ago(ioc_lookBack)
36-
| where TimeGenerated >= ago(ioc_lookBack)
3736
// Filtering out rows where the Confidence Score is less than 50 as they would not have an Alert Priority label.
3837
| where Confidence > 50
3938
// Select the IP entity based on availability of different IP fields
2.65 KB
Binary file not shown.

Solutions/Threat Intelligence (NEW)/Package/mainTemplate.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5044,7 +5044,7 @@
50445044
"description": "Identifies a match in AppServiceHTTPLogs from any IP IOC from TI",
50455045
"displayName": "TI map IP entity to AppServiceHTTPLogs",
50465046
"enabled": false,
5047-
"query": "let dt_lookBack = 1h; // Look back 1 hour for AppServiceHTTPLogs\nlet ioc_lookBack = 14d; // Look back 14 days for threat intelligence indicators\n// Fetch threat intelligence indicators related to IP addresses\nlet IP_Indicators = ThreatIntelIndicators\n //extract key part of kv pair\n | extend IndicatorType = replace(@\"\\[|\\]|\\\"\"\", \"\", tostring(split(ObservableKey, \":\", 0)))\n | where IndicatorType in (\"ipv4-addr\", \"ipv6-addr\", \"network-traffic\")\n | extend NetworkSourceIP = ObservableValue\n | extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)\n // Filter out indicators without relevant IP address fields\n | where TimeGenerated >= ago(ioc_lookBack)\n | where TimeGenerated >= ago(ioc_lookBack)\n // Filtering out rows where the Confidence Score is less than 50 as they would not have an Alert Priority label. \n | where Confidence > 50\n // Select the IP entity based on availability of different IP fields\n | extend TI_ipEntity = iff(isnotempty(NetworkSourceIP), NetworkSourceIP, NetworkSourceIP)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n | extend Url = iff(ObservableKey == \"url:value\", ObservableValue, \"\")\n // Determine Severity based on ConfidenceScore\n | extend Severity = case(Confidence > 82, \"High\",\n Confidence > 74, \"Medium\",\n \"Low\")\n // Exclude local addresses using the ipv4_is_private operator and filtering out specific address prefixes\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 Id, ObservableValue\n | where IsActive and (ValidUntil > now() or isempty(ValidUntil));\n // Perform a join between IP indicators and AppServiceHTTPLogs to identify potential malicious activity\nIP_Indicators\n| project-reorder *, IsActive, Tags, TrafficLightProtocolLevel, NetworkSourceIP, Type, TI_ipEntity, Severity\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 AppServiceHTTPLogs | where TimeGenerated >= ago(dt_lookBack)\n | where isnotempty(CIp)\n | extend WebApp = split(_ResourceId, '/')[8]\n | extend AppService_TimeGenerated = TimeGenerated // Rename time column for clarity\n )\n on $left.TI_ipEntity == $right.CIp\n // Filter out logs that occurred after the expiration of the corresponding indicator\n | where AppService_TimeGenerated < ValidUntil\n // Group the results by IndicatorId and CIp, and keep the log entry with the latest timestamp\n | summarize AppService_TimeGenerated = arg_max(AppService_TimeGenerated, *) by Id, CIp\n // Select the desired output fields\n | extend Description = tostring(parse_json(Data).description)\n | extend ActivityGroupNames = extract(@\"ActivityGroup:(\\S+)\", 1, tostring(parse_json(Data).labels))\n | project AppService_TimeGenerated, Description, ActivityGroupNames, Id, ValidUntil, Confidence, TI_ipEntity, CsUsername, WebApp = split(_ResourceId, '/')[8], CIp, CsHost, NetworkSourceIP, _ResourceId, Type, Url\n // Extract hostname and DNS domain from the CsHost field\n | extend HostName = tostring(split(CsHost, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(CsHost, '.'), 1, -1), '.'))\n // Rename the timestamp field\n | extend timestamp = AppService_TimeGenerated\n",
5047+
"query": "let dt_lookBack = 1h; // Look back 1 hour for AppServiceHTTPLogs\nlet ioc_lookBack = 14d; // Look back 14 days for threat intelligence indicators\n// Fetch threat intelligence indicators related to IP addresses\nlet IP_Indicators = ThreatIntelIndicators\n //extract key part of kv pair\n | extend IndicatorType = replace(@\"\\[|\\]|\\\"\"\", \"\", tostring(split(ObservableKey, \":\", 0)))\n | where IndicatorType in (\"ipv4-addr\", \"ipv6-addr\", \"network-traffic\")\n | extend NetworkSourceIP = ObservableValue\n | extend TrafficLightProtocolLevel = tostring(parse_json(AdditionalFields).TLPLevel)\n // Filter out indicators without relevant IP address fields\n | where TimeGenerated >= ago(ioc_lookBack)\n // Filtering out rows where the Confidence Score is less than 50 as they would not have an Alert Priority label. \n | where Confidence > 50\n // Select the IP entity based on availability of different IP fields\n | extend TI_ipEntity = iff(isnotempty(NetworkSourceIP), NetworkSourceIP, NetworkSourceIP)\n | extend TI_ipEntity = iff(isempty(TI_ipEntity) and isnotempty(NetworkSourceIP), NetworkSourceIP, TI_ipEntity)\n | extend Url = iff(ObservableKey == \"url:value\", ObservableValue, \"\")\n // Determine Severity based on ConfidenceScore\n | extend Severity = case(Confidence > 82, \"High\",\n Confidence > 74, \"Medium\",\n \"Low\")\n // Exclude local addresses using the ipv4_is_private operator and filtering out specific address prefixes\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 Id, ObservableValue\n | where IsActive and (ValidUntil > now() or isempty(ValidUntil));\n // Perform a join between IP indicators and AppServiceHTTPLogs to identify potential malicious activity\nIP_Indicators\n| project-reorder *, IsActive, Tags, TrafficLightProtocolLevel, NetworkSourceIP, Type, TI_ipEntity, Severity\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 AppServiceHTTPLogs | where TimeGenerated >= ago(dt_lookBack)\n | where isnotempty(CIp)\n | extend WebApp = split(_ResourceId, '/')[8]\n | extend AppService_TimeGenerated = TimeGenerated // Rename time column for clarity\n )\n on $left.TI_ipEntity == $right.CIp\n // Filter out logs that occurred after the expiration of the corresponding indicator\n | where AppService_TimeGenerated < ValidUntil\n // Group the results by IndicatorId and CIp, and keep the log entry with the latest timestamp\n | summarize AppService_TimeGenerated = arg_max(AppService_TimeGenerated, *) by Id, CIp\n // Select the desired output fields\n | extend Description = tostring(parse_json(Data).description)\n | extend ActivityGroupNames = extract(@\"ActivityGroup:(\\S+)\", 1, tostring(parse_json(Data).labels))\n | project AppService_TimeGenerated, Description, ActivityGroupNames, Id, ValidUntil, Confidence, TI_ipEntity, CsUsername, WebApp = split(_ResourceId, '/')[8], CIp, CsHost, NetworkSourceIP, _ResourceId, Type, Url\n // Extract hostname and DNS domain from the CsHost field\n | extend HostName = tostring(split(CsHost, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(CsHost, '.'), 1, -1), '.'))\n // Rename the timestamp field\n | extend timestamp = AppService_TimeGenerated\n",
50485048
"queryFrequency": "PT1H",
50495049
"queryPeriod": "P14D",
50505050
"severity": "Medium",

0 commit comments

Comments
 (0)