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

Detect IP Address Changes and Overlapping Sessions

Back
Id57abf863-1c1e-46c6-85b2-35370b712c1e
RulenameDetect IP Address Changes and Overlapping Sessions
DescriptionThis query identifies network sessions based on DeviceId and UserPrincipalName, then checks for changed IP addresses and overlapping session times.
SeverityHigh
TacticsInitialAccess
TechniquesT1078
T1133
Required data connectorsAzureActiveDirectory
KindScheduled
Query frequency1h
Query period24h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Identity - SharedSessions.yaml
Version1.0.0
Arm template57abf863-1c1e-46c6-85b2-35370b712c1e.json
Deploy To Azure
// Identify sessions
let sessions = 
  NetworkAccessTraffic
  | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), SourceIps = make_set(SourceIp) by DeviceId, UserPrincipalName, SessionId
  | sort by StartTime asc;
// Check for changed IP addresses and overlapping session times
sessions
  | extend PreviousSourceIps = prev(SourceIps, 1)
  | extend PreviousEndTime = prev(EndTime, 1)
  | extend PreviousDeviceId = prev(DeviceId, 1)
  | extend PreviousUserPrincipalName = prev(UserPrincipalName, 1)
  | where DeviceId == PreviousDeviceId and UserPrincipalName == PreviousUserPrincipalName
  | where set_difference(SourceIps, PreviousSourceIps) != dynamic([]) // Check if the current and previous IP sets differ
  | where PreviousEndTime > StartTime // Check for overlapping session times
  | project DeviceId, UserPrincipalName, SourceIps, PreviousSourceIps, StartTime, EndTime, PreviousEndTime
  | extend IPCustomEntity = tostring(array_slice(SourceIps, 0, 1)[0]), PreviousIPCustomEntity = tostring(array_slice(PreviousSourceIps, 0, 1)[0]), AccountCustomEntity = UserPrincipalName
id: 57abf863-1c1e-46c6-85b2-35370b712c1e
queryFrequency: 1h
version: 1.0.0
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Identity - SharedSessions.yaml
requiredDataConnectors:
- dataTypes:
  - EnrichedMicrosoft365AuditLogs
  connectorId: AzureActiveDirectory
query: |
  // Identify sessions
  let sessions = 
    NetworkAccessTraffic
    | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), SourceIps = make_set(SourceIp) by DeviceId, UserPrincipalName, SessionId
    | sort by StartTime asc;
  // Check for changed IP addresses and overlapping session times
  sessions
    | extend PreviousSourceIps = prev(SourceIps, 1)
    | extend PreviousEndTime = prev(EndTime, 1)
    | extend PreviousDeviceId = prev(DeviceId, 1)
    | extend PreviousUserPrincipalName = prev(UserPrincipalName, 1)
    | where DeviceId == PreviousDeviceId and UserPrincipalName == PreviousUserPrincipalName
    | where set_difference(SourceIps, PreviousSourceIps) != dynamic([]) // Check if the current and previous IP sets differ
    | where PreviousEndTime > StartTime // Check for overlapping session times
    | project DeviceId, UserPrincipalName, SourceIps, PreviousSourceIps, StartTime, EndTime, PreviousEndTime
    | extend IPCustomEntity = tostring(array_slice(SourceIps, 0, 1)[0]), PreviousIPCustomEntity = tostring(array_slice(PreviousSourceIps, 0, 1)[0]), AccountCustomEntity = UserPrincipalName  
name: Detect IP Address Changes and Overlapping Sessions
status: Available
kind: Scheduled
description: |
    This query identifies network sessions based on DeviceId and UserPrincipalName, then checks for changed IP addresses and overlapping session times.
severity: High
triggerOperator: gt
entityMappings:
- entityType: Account
  fieldMappings:
  - columnName: AccountCustomEntity
    identifier: Name
- entityType: IP
  fieldMappings:
  - columnName: IPCustomEntity
    identifier: Address
triggerThreshold: 0
queryPeriod: 24h
tactics:
- InitialAccess
relevantTechniques:
- T1078
- T1133
{
  "$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/57abf863-1c1e-46c6-85b2-35370b712c1e')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/57abf863-1c1e-46c6-85b2-35370b712c1e')]",
      "properties": {
        "alertRuleTemplateName": "57abf863-1c1e-46c6-85b2-35370b712c1e",
        "customDetails": null,
        "description": "This query identifies network sessions based on DeviceId and UserPrincipalName, then checks for changed IP addresses and overlapping session times.\n",
        "displayName": "Detect IP Address Changes and Overlapping Sessions",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "AccountCustomEntity",
                "identifier": "Name"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "IPCustomEntity",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Identity - SharedSessions.yaml",
        "query": "// Identify sessions\nlet sessions = \n  NetworkAccessTraffic\n  | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), SourceIps = make_set(SourceIp) by DeviceId, UserPrincipalName, SessionId\n  | sort by StartTime asc;\n// Check for changed IP addresses and overlapping session times\nsessions\n  | extend PreviousSourceIps = prev(SourceIps, 1)\n  | extend PreviousEndTime = prev(EndTime, 1)\n  | extend PreviousDeviceId = prev(DeviceId, 1)\n  | extend PreviousUserPrincipalName = prev(UserPrincipalName, 1)\n  | where DeviceId == PreviousDeviceId and UserPrincipalName == PreviousUserPrincipalName\n  | where set_difference(SourceIps, PreviousSourceIps) != dynamic([]) // Check if the current and previous IP sets differ\n  | where PreviousEndTime > StartTime // Check for overlapping session times\n  | project DeviceId, UserPrincipalName, SourceIps, PreviousSourceIps, StartTime, EndTime, PreviousEndTime\n  | extend IPCustomEntity = tostring(array_slice(SourceIps, 0, 1)[0]), PreviousIPCustomEntity = tostring(array_slice(PreviousSourceIps, 0, 1)[0]), AccountCustomEntity = UserPrincipalName\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT24H",
        "severity": "High",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess"
        ],
        "techniques": [
          "T1078",
          "T1133"
        ],
        "templateVersion": "1.0.0",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}