Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

(Preview) TI map IP entity to Web Session Events (ASIM Web Session schema)

Back
Ide2559891-383c-4caf-ae67-55a008b9f89e
Rulename(Preview) TI map IP entity to Web Session Events (ASIM Web Session schema)
DescriptionThis rule identifies Web Sessions for which the source IP address is a known IoC. <br><br>This rule uses the Advanced Security Information Model (ASIM) and supports any web session source that complies with ASIM.
SeverityMedium
TacticsImpact
Required data connectorsSquidProxy
ThreatIntelligence
ThreatIntelligenceTaxii
Zscaler
KindScheduled
Query frequency1h
Query period14d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/IPEntity_imWebSession.yaml
Version1.1.0
Arm templatee2559891-383c-4caf-ae67-55a008b9f89e.json
Deploy To Azure
let HAS_ANY_MAX = 10000;
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let IoCList = materialize(externaldata(TimeGenerated:datetime,IoC:string,IoC_Type:string,ExpirationDateTime:datetime,Description:string,Action:string, ConfidenceScore:real, ThreatType:string, Active:string,Type:string, TrafficLightProtocolLevel:string, ActivityGroupNames:string)[@"https://raw.githubusercontent.com/microsoft/mstic/master/RapidReleaseTI/Indicators.csv"] with(format="csv", ignoreFirstRecord=True));
let IP_TI= (union isfuzzy=true
(ThreatIntelligenceIndicator
| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
| where Active == true
// As there is potentially more than 1 indicator type for matching IP, taking NetworkIP first, then others if that is empty.
// Taking the first non-empty value based on potential IOC match availability
| extend TI_ipEntity = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,"NO_IP")
// Picking up only IOC's that contain the entities we want
| where TI_ipEntity != "NO_IP"
//Exclude local addresses, using the ipv4_is_private operator
| where ipv4_is_private(TI_ipEntity) == false and  TI_ipEntity !startswith "fe80" and TI_ipEntity !startswith "::" and TI_ipEntity !startswith "127."
),
(IoCList
| where IoC_Type =~ 'IP'
| where ExpirationDateTime > now()
| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IoC
| where Active =~ 'True'
| extend TI_ipEntity = IoC
| project-away  IoC_Type
)
);
let IP_TI_list=toscalar(IP_TI | summarize NIoCs= dcount(TI_ipEntity), IoCs=make_set(TI_ipEntity) 
  | project IoCs=iff(NIoCs > HAS_ANY_MAX, dynamic([]), IoCs )  );
IP_TI
// 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
| join kind=innerunique (
    _Im_WebSession (starttime=ago(dt_lookBack), srcipaddr_has_any_prefix=IP_TI_list)
    | where isnotempty(SrcIpAddr)
    // renaming time column so it is clear the log this came from
    | extend imNWS_TimeGenerated = TimeGenerated
)
on $left.TI_ipEntity == $right.SrcIpAddr
| where imNWS_TimeGenerated < ExpirationDateTime
| summarize imNWS_TimeGenerated = arg_max(imNWS_TimeGenerated , *) by IndicatorId, DstIpAddr, IoC
| project imNWS_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore,
TI_ipEntity, Dvc, SrcIpAddr, DstIpAddr, Type
version: 1.1.0
queryFrequency: 1h
requiredDataConnectors:
- connectorId: SquidProxy
  dataTypes:
  - SquidProxy_CL
- connectorId: Zscaler
  dataTypes:
  - CommonSecurityLog
- connectorId: ThreatIntelligence
  dataTypes:
  - ThreatIntelligenceIndicator
- connectorId: ThreatIntelligenceTaxii
  dataTypes:
  - ThreatIntelligenceIndicator
entityMappings:
- fieldMappings:
  - columnName: DstIpAddr
    identifier: Address
  entityType: IP
kind: Scheduled
queryPeriod: 14d
severity: Medium
query: |
  let HAS_ANY_MAX = 10000;
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let IoCList = materialize(externaldata(TimeGenerated:datetime,IoC:string,IoC_Type:string,ExpirationDateTime:datetime,Description:string,Action:string, ConfidenceScore:real, ThreatType:string, Active:string,Type:string, TrafficLightProtocolLevel:string, ActivityGroupNames:string)[@"https://raw.githubusercontent.com/microsoft/mstic/master/RapidReleaseTI/Indicators.csv"] with(format="csv", ignoreFirstRecord=True));
  let IP_TI= (union isfuzzy=true
  (ThreatIntelligenceIndicator
  | where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
  | where Active == true
  // As there is potentially more than 1 indicator type for matching IP, taking NetworkIP first, then others if that is empty.
  // Taking the first non-empty value based on potential IOC match availability
  | extend TI_ipEntity = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,"NO_IP")
  // Picking up only IOC's that contain the entities we want
  | where TI_ipEntity != "NO_IP"
  //Exclude local addresses, using the ipv4_is_private operator
  | where ipv4_is_private(TI_ipEntity) == false and  TI_ipEntity !startswith "fe80" and TI_ipEntity !startswith "::" and TI_ipEntity !startswith "127."
  ),
  (IoCList
  | where IoC_Type =~ 'IP'
  | where ExpirationDateTime > now()
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IoC
  | where Active =~ 'True'
  | extend TI_ipEntity = IoC
  | project-away  IoC_Type
  )
  );
  let IP_TI_list=toscalar(IP_TI | summarize NIoCs= dcount(TI_ipEntity), IoCs=make_set(TI_ipEntity) 
    | project IoCs=iff(NIoCs > HAS_ANY_MAX, dynamic([]), IoCs )  );
  IP_TI
  // 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
  | join kind=innerunique (
      _Im_WebSession (starttime=ago(dt_lookBack), srcipaddr_has_any_prefix=IP_TI_list)
      | where isnotempty(SrcIpAddr)
      // renaming time column so it is clear the log this came from
      | extend imNWS_TimeGenerated = TimeGenerated
  )
  on $left.TI_ipEntity == $right.SrcIpAddr
  | where imNWS_TimeGenerated < ExpirationDateTime
  | summarize imNWS_TimeGenerated = arg_max(imNWS_TimeGenerated , *) by IndicatorId, DstIpAddr, IoC
  | project imNWS_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore,
  TI_ipEntity, Dvc, SrcIpAddr, DstIpAddr, Type  
triggerOperator: gt
id: e2559891-383c-4caf-ae67-55a008b9f89e
description: |
    'This rule identifies Web Sessions for which the source IP address is a known IoC. <br><br>This rule uses the [Advanced Security Information Model (ASIM)](https://aka.ms/AboutASIM) and supports any web session source that complies with ASIM.'
triggerThreshold: 0
name: (Preview) TI map IP entity to Web Session Events (ASIM Web Session schema)
customDetails:
  ActivityGroupNames: ActivityGroupNames
  IoCExpirationTime: ExpirationDateTime
  IoCDescription: Description
  EventTime: imNWS_TimeGenerated
  IoCConfidenceScore: ConfidenceScore
  IndicatorId: IndicatorId
  ThreatType: ThreatType
tactics:
- Impact
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/IPEntity_imWebSession.yaml
alertDetailsOverride:
  alertDisplayNameFormat: The IP {{SrcIpAddr}} of a web request to hostname  {{domain}} matched an IoC
  alertDescriptionFormat: The source address {{SrcIpAddr}} of a web request for URL {{Url}} matched a known indicator of compromise of {{ThreatType}}. Consult the threat intelligence blead for more information on the indicator.
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/e2559891-383c-4caf-ae67-55a008b9f89e')]",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/e2559891-383c-4caf-ae67-55a008b9f89e')]",
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
      "kind": "Scheduled",
      "apiVersion": "2022-11-01",
      "properties": {
        "displayName": "(Preview) TI map IP entity to Web Session Events (ASIM Web Session schema)",
        "description": "'This rule identifies Web Sessions for which the source IP address is a known IoC. <br><br>This rule uses the [Advanced Security Information Model (ASIM)](https://aka.ms/AboutASIM) and supports any web session source that complies with ASIM.'\n",
        "severity": "Medium",
        "enabled": true,
        "query": "let HAS_ANY_MAX = 10000;\nlet dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet IoCList = materialize(externaldata(TimeGenerated:datetime,IoC:string,IoC_Type:string,ExpirationDateTime:datetime,Description:string,Action:string, ConfidenceScore:real, ThreatType:string, Active:string,Type:string, TrafficLightProtocolLevel:string, ActivityGroupNames:string)[@\"https://raw.githubusercontent.com/microsoft/mstic/master/RapidReleaseTI/Indicators.csv\"] with(format=\"csv\", ignoreFirstRecord=True));\nlet IP_TI= (union isfuzzy=true\n(ThreatIntelligenceIndicator\n| where TimeGenerated >= ago(ioc_lookBack) and ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n| where Active == true\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 = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,\"NO_IP\")\n// Picking up only IOC's that contain the entities we want\n| where TI_ipEntity != \"NO_IP\"\n//Exclude local addresses, using the ipv4_is_private operator\n| where ipv4_is_private(TI_ipEntity) == false and  TI_ipEntity !startswith \"fe80\" and TI_ipEntity !startswith \"::\" and TI_ipEntity !startswith \"127.\"\n),\n(IoCList\n| where IoC_Type =~ 'IP'\n| where ExpirationDateTime > now()\n| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IoC\n| where Active =~ 'True'\n| extend TI_ipEntity = IoC\n| project-away  IoC_Type\n)\n);\nlet IP_TI_list=toscalar(IP_TI | summarize NIoCs= dcount(TI_ipEntity), IoCs=make_set(TI_ipEntity) \n  | project IoCs=iff(NIoCs > HAS_ANY_MAX, dynamic([]), IoCs )  );\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    _Im_WebSession (starttime=ago(dt_lookBack), srcipaddr_has_any_prefix=IP_TI_list)\n    | where isnotempty(SrcIpAddr)\n    // renaming time column so it is clear the log this came from\n    | extend imNWS_TimeGenerated = TimeGenerated\n)\non $left.TI_ipEntity == $right.SrcIpAddr\n| where imNWS_TimeGenerated < ExpirationDateTime\n| summarize imNWS_TimeGenerated = arg_max(imNWS_TimeGenerated , *) by IndicatorId, DstIpAddr, IoC\n| project imNWS_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore,\nTI_ipEntity, Dvc, SrcIpAddr, DstIpAddr, Type\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0,
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Impact"
        ],
        "alertRuleTemplateName": "e2559891-383c-4caf-ae67-55a008b9f89e",
        "alertDetailsOverride": {
          "alertDescriptionFormat": "The source address {{SrcIpAddr}} of a web request for URL {{Url}} matched a known indicator of compromise of {{ThreatType}}. Consult the threat intelligence blead for more information on the indicator.",
          "alertDisplayNameFormat": "The IP {{SrcIpAddr}} of a web request to hostname  {{domain}} matched an IoC"
        },
        "customDetails": {
          "ActivityGroupNames": "ActivityGroupNames",
          "IoCExpirationTime": "ExpirationDateTime",
          "IndicatorId": "IndicatorId",
          "IoCDescription": "Description",
          "ThreatType": "ThreatType",
          "EventTime": "imNWS_TimeGenerated",
          "IoCConfidenceScore": "ConfidenceScore"
        },
        "entityMappings": [
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "identifier": "Address",
                "columnName": "DstIpAddr"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/IPEntity_imWebSession.yaml",
        "templateVersion": "1.1.0"
      }
    }
  ]
}