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
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  
relevantTechniques:
- T1078
- T1133
name: Detect IP Address Changes and Overlapping Sessions
severity: High
triggerThreshold: 0
description: |
    This query identifies network sessions based on DeviceId and UserPrincipalName, then checks for changed IP addresses and overlapping session times.
status: Available
triggerOperator: gt
tactics:
- InitialAccess
entityMappings:
- fieldMappings:
  - columnName: AccountCustomEntity
    identifier: Name
  entityType: Account
- fieldMappings:
  - columnName: IPCustomEntity
    identifier: Address
  entityType: IP
requiredDataConnectors:
- connectorId: AzureActiveDirectory
  dataTypes:
  - EnrichedMicrosoft365AuditLogs
id: 57abf863-1c1e-46c6-85b2-35370b712c1e
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Identity - SharedSessions.yaml
queryPeriod: 24h
queryFrequency: 1h
version: 1.0.0
kind: Scheduled
{
  "$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"
    }
  ]
}