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

GSA - Detect IP Address Changes and Overlapping Sessions

Back
Id57abf863-1c1e-46c6-85b2-35370b712c1e
RulenameGSA - Detect 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.2
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 array_length(set_difference(SourceIps, PreviousSourceIps)) > 0 // 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: GSA - Detect IP Address Changes and Overlapping Sessions
requiredDataConnectors:
- dataTypes:
  - EnrichedMicrosoft365AuditLogs
  connectorId: AzureActiveDirectory
entityMappings:
- fieldMappings:
  - identifier: Name
    columnName: AccountCustomEntity
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: IPCustomEntity
  entityType: IP
triggerThreshold: 0
id: 57abf863-1c1e-46c6-85b2-35370b712c1e
tactics:
- InitialAccess
version: 1.0.2
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Global Secure Access/Analytic Rules/Identity - SharedSessions.yaml
queryPeriod: 24h
kind: Scheduled
queryFrequency: 1h
severity: High
status: Available
description: |
    This query identifies network sessions based on DeviceId and UserPrincipalName, then checks for changed IP addresses and overlapping session times.
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 array_length(set_difference(SourceIps, PreviousSourceIps)) > 0 // 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  
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/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": "GSA - 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 \n      StartTime = min(TimeGenerated), \n      EndTime = max(TimeGenerated), \n      SourceIps = make_set(SourceIp) \n    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 \n        and UserPrincipalName == PreviousUserPrincipalName\n  | where array_length(set_difference(SourceIps, PreviousSourceIps)) > 0 // Check if the current and previous IP sets differ\n  | where PreviousEndTime > StartTime // Check for overlapping session times\n  | project \n      DeviceId, \n      UserPrincipalName, \n      SourceIps, \n      PreviousSourceIps, \n      StartTime, \n      EndTime, \n      PreviousEndTime\n  | extend \n      IPCustomEntity = tostring(array_slice(SourceIps, 0, 1)[0]), \n      PreviousIPCustomEntity = tostring(array_slice(PreviousSourceIps, 0, 1)[0]), \n      AccountCustomEntity = UserPrincipalName\n",
        "queryFrequency": "PT1H",
        "queryPeriod": "PT24H",
        "severity": "High",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "InitialAccess"
        ],
        "techniques": [
          "T1078",
          "T1133"
        ],
        "templateVersion": "1.0.2",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}