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

TI map IP entity to Web Session Events ASIM Web Session schema

Back
Ide2559891-383c-4caf-ae67-55a008b9f89e
RulenameTI 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. This rule uses the Advanced Security Information Model (ASIM) and supports any web session source that complies with ASIM.
SeverityMedium
TacticsCommandAndControl
TechniquesT1071
Required data connectorsMicrosoftDefenderThreatIntelligence
SquidProxy
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.2.5
Arm templatee2559891-383c-4caf-ae67-55a008b9f89e.json
Deploy To Azure
let HAS_ANY_MAX = 10000;
let dt_lookBack = 1h;
let ioc_lookBack = 14d;
let IP_TI = ThreatIntelligenceIndicator
  | where TimeGenerated >= ago(ioc_lookBack)
  // 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."
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
  | where Active == true and ExpirationDateTime > now();
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
| project imNWS_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore,
  TI_ipEntity, Dvc, SrcIpAddr, DstIpAddr, Url, Type
relevantTechniques:
- T1071
name: TI map IP entity to Web Session Events (ASIM Web Session schema)
requiredDataConnectors:
- dataTypes:
  - SquidProxy_CL
  connectorId: SquidProxy
- dataTypes:
  - CommonSecurityLog
  connectorId: Zscaler
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: ThreatIntelligence
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: ThreatIntelligenceTaxii
- dataTypes:
  - ThreatIntelligenceIndicator
  connectorId: MicrosoftDefenderThreatIntelligence
entityMappings:
- fieldMappings:
  - identifier: Address
    columnName: DstIpAddr
  entityType: IP
triggerThreshold: 0
id: e2559891-383c-4caf-ae67-55a008b9f89e
tactics:
- CommandAndControl
version: 1.2.5
customDetails:
  IndicatorId: IndicatorId
  ThreatType: ThreatType
  IoCDescription: Description
  ActivityGroupNames: ActivityGroupNames
  EventTime: imNWS_TimeGenerated
  IoCConfidenceScore: ConfidenceScore
  IoCExpirationTime: ExpirationDateTime
alertDetailsOverride:
  alertDisplayNameFormat: The IP {{SrcIpAddr}} of the web request matches an IP IoC
  alertDescriptionFormat: The source address {{SrcIpAddr}} of the web request for the URL {{Url}} matches a known indicator of compromise of {{ThreatType}}. Consult the threat intelligence feed for more information about the indicator.
queryPeriod: 14d
kind: Scheduled
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/IPEntity_imWebSession.yaml
queryFrequency: 1h
severity: Medium
description: |
    This rule identifies Web Sessions for which the source IP address is a known IoC. This rule uses the [Advanced Security Information Model (ASIM)](https://aka.ms/AboutASIM) and supports any web session source that complies with ASIM.
query: |
  let HAS_ANY_MAX = 10000;
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let IP_TI = ThreatIntelligenceIndicator
    | where TimeGenerated >= ago(ioc_lookBack)
    // 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."
    | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
    | where Active == true and ExpirationDateTime > now();
  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
  | project imNWS_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore,
    TI_ipEntity, Dvc, SrcIpAddr, DstIpAddr, Url, Type  
triggerOperator: gt
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/e2559891-383c-4caf-ae67-55a008b9f89e')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/e2559891-383c-4caf-ae67-55a008b9f89e')]",
      "properties": {
        "alertDetailsOverride": {
          "alertDescriptionFormat": "The source address {{SrcIpAddr}} of the web request for the URL {{Url}} matches a known indicator of compromise of {{ThreatType}}. Consult the threat intelligence feed for more information about the indicator.",
          "alertDisplayNameFormat": "The IP {{SrcIpAddr}} of the web request matches an IP IoC"
        },
        "alertRuleTemplateName": "e2559891-383c-4caf-ae67-55a008b9f89e",
        "customDetails": {
          "ActivityGroupNames": "ActivityGroupNames",
          "EventTime": "imNWS_TimeGenerated",
          "IndicatorId": "IndicatorId",
          "IoCConfidenceScore": "ConfidenceScore",
          "IoCDescription": "Description",
          "IoCExpirationTime": "ExpirationDateTime",
          "ThreatType": "ThreatType"
        },
        "description": "This rule identifies Web Sessions for which the source IP address is a known IoC. This rule uses the [Advanced Security Information Model (ASIM)](https://aka.ms/AboutASIM) and supports any web session source that complies with ASIM.\n",
        "displayName": "TI map IP entity to Web Session Events (ASIM Web Session schema)",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "DstIpAddr",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Threat Intelligence/Analytic Rules/IPEntity_imWebSession.yaml",
        "query": "let HAS_ANY_MAX = 10000;\nlet dt_lookBack = 1h;\nlet ioc_lookBack = 14d;\nlet IP_TI = ThreatIntelligenceIndicator\n  | where TimeGenerated >= ago(ioc_lookBack)\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  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId\n  | where Active == true and ExpirationDateTime > now();\nlet IP_TI_list = toscalar(IP_TI\n  | 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  )\n  on $left.TI_ipEntity == $right.SrcIpAddr\n| where imNWS_TimeGenerated < ExpirationDateTime\n| summarize imNWS_TimeGenerated = arg_max(imNWS_TimeGenerated, *) by IndicatorId, DstIpAddr\n| project imNWS_TimeGenerated, Description, ActivityGroupNames, IndicatorId, ThreatType, ExpirationDateTime, ConfidenceScore,\n  TI_ipEntity, Dvc, SrcIpAddr, DstIpAddr, Url, Type\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "P14D",
        "severity": "Medium",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl"
        ],
        "techniques": [
          "T1071"
        ],
        "templateVersion": "1.2.5",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}