Detection rules › Panther

Azure Microsoft Graph Single Session from Multiple IP Addresses

Status
Experimental
Severity
medium
Group by
properties.sessionId, properties.userPrincipalName
Log types
Azure.Audit
Tags
Initial Access, Valid Accounts, Use Alternate Authentication Material
Reference
https://github.com/elastic/detection-rules/blob/main/rules/integrations/azure/initial_access_entra_id_graph_single_session_from_multiple_addresses.toml
Source
github.com/panther-labs/panther-analysis

Detects when a user signs in to Microsoft Entra ID and subsequently accesses Microsoft Graph from a different IP address using the same session ID. This behavior may indicate OAuth application abuse, session hijacking, token replay attacks, or adversary-in-the-middle attacks where an attacker has obtained a valid session token and is using it from their own infrastructure.

MITRE ATT&CK coverage

Rules detecting the same action

Other rules on this platform that filter on the same API call or operation.

Rule body yaml

AnalysisType: rule
Filename: azure_graph_session_multiple_ips.py
RuleID: "Azure.Audit.GraphSessionMultipleIPs"
DisplayName: "Azure Microsoft Graph Single Session from Multiple IP Addresses"
Enabled: true
Status: Experimental
LogTypes:
  - Azure.Audit
Severity: Medium
Threshold: 2
DedupPeriodMinutes: 60
Description: >
  Detects when a user signs in to Microsoft Entra ID and subsequently accesses Microsoft Graph from
  a different IP address using the same session ID. This behavior may indicate OAuth application abuse,
  session hijacking, token replay attacks, or adversary-in-the-middle attacks where an attacker has
  obtained a valid session token and is using it from their own infrastructure.
Tags:
  - Initial Access
  - Valid Accounts
  - Use Alternate Authentication Material
Reports:
  MITRE ATT&CK:
    - TA0001:T1078
    - TA0001:T1078.004
    - TA0005:T1550
    - TA0005:T1550.001
Runbook: |
  1. Query Azure.Audit logs for all Microsoft Graph access events with properties:sessionId in the 4 hours around this alert to identify all source IP addresses, user agents, and accessed resources
  2. Compare the geographic locations and ASN information for all distinct callerIpAddress values to determine if they represent different countries, cloud providers, or inconsistent network types
  3. Review Azure.Audit logs for properties:userPrincipalName in the 7 days before this session to identify OAuth consent grants, new application registrations, risky sign-ins, or token issuance events that may indicate initial compromise
Reference: https://github.com/elastic/detection-rules/blob/main/rules/integrations/azure/initial_access_entra_id_graph_single_session_from_multiple_addresses.toml
SummaryAttributes:
  - properties:userPrincipalName
  - callerIpAddress
  - properties:sessionId
  - properties:appDisplayName
Tests:
  - Name: Multiple IP Access to Same Microsoft Graph Session
    ExpectedResult: true
    Log:
      {
        "time": "2025-01-15 09:35:20.456",
        "resourceId": "/tenants/tenant-123/providers/Microsoft.aadiam",
        "operationName": "Sign-in activity",
        "operationVersion": "1.0",
        "category": "SignInLogs",
        "tenantId": "tenant-123",
        "resultType": "Success",
        "resultSignature": "SUCCESS",
        "durationMs": 0,
        "callerIpAddress": "5.5.5.5",
        "correlationId": "graph-session-002",
        "Level": "4",
        "properties":
          {
            "createdDateTime": "2025-01-15T09:35:20.4567890Z",
            "userPrincipalName": "gandalf@lotr.com",
            "userId": "user-123",
            "ipAddress": "5.5.5.5",
            "sessionId": "session-abc-123",
            "resourceDisplayName": "Microsoft Graph",
            "resourceId": "00000003-0000-0000-c000-111111111111",
            "appDisplayName": "Custom Graph App",
            "appId": "app-custom-789",
            "userAgent": "python-requests/2.28.1",
            "isInteractive": true,
            "authenticationProtocol": "oAuth2",
            "conditionalAccessStatus": "success",
          },
        "p_event_time": "2025-01-15 09:35:20.456",
        "p_log_type": "Azure.Audit",
        "p_parse_time": "2025-01-15 09:35:21.000",
        "p_row_id": "row-456",
      }
  - Name: Non-Interactive Sign-In via NonInteractiveUserSignInLogs Category
    ExpectedResult: false
    Log:
      {
        "time": "2026-02-18 07:34:37.443",
        "resourceId": "/tenants/18360841-3f87-44a6-8c9a-3ffc680611a0/providers/Microsoft.aadiam",
        "operationName": "Sign-in activity",
        "operationVersion": "1.0",
        "category": "NonInteractiveUserSignInLogs",
        "tenantId": "18360841-3f87-44a6-8c9a-3ffc680611a0",
        "resultType": "0",
        "resultSignature": "SUCCESS",
        "durationMs": 0,
        "callerIpAddress": "203.0.113.10",
        "correlationId": "6d657aae-f797-466f-8b35-31eb5b7ffde2",
        "Level": "4",
        "properties":
          {
            "createdDateTime": "2026-02-18T07:32:50.552947800Z",
            "userPrincipalName": "jane.doe@example.com",
            "userId": "3b4e2783-2b5d-4f1f-a3d9-ddc0ed1c623f",
            "ipAddress": "203.0.113.10",
            "sessionId": "00baf379-e510-523f-1c0e-346163d4a768",
            "resourceDisplayName": "Microsoft Graph",
            "resourceId": "00000003-0000-0000-c000-000000000000",
            "appDisplayName": "Custom App",
            "appId": "app-noninteractive-test-999",
            "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
            "isInteractive": false,
            "signInEventTypes": ["nonInteractiveUser"],
            "authenticationProtocol": "none",
            "conditionalAccessStatus": "notApplied",
          },
        "p_event_time": "2026-02-18 07:34:37.443",
        "p_log_type": "Azure.Audit",
      }
  - Name: Whitelisted Office 365
    ExpectedResult: false
    Log:
      {
        "time": "2025-01-15 10:00:30.789",
        "resourceId": "/tenants/tenant-456/providers/Microsoft.aadiam",
        "operationName": "Sign-in activity",
        "operationVersion": "1.0",
        "category": "SignInLogs",
        "tenantId": "tenant-456",
        "resultType": "Success",
        "resultSignature": "SUCCESS",
        "durationMs": 0,
        "callerIpAddress": "192.0.2.100",
        "correlationId": "office365-001",
        "Level": "4",
        "properties":
          {
            "createdDateTime": "2025-01-15T10:00:30.7890123Z",
            "userPrincipalName": "employee@company.com",
            "userId": "user-456",
            "ipAddress": "192.0.2.100",
            "sessionId": "session-office-456",
            "resourceDisplayName": "Microsoft Graph",
            "resourceId": "00000003-0000-0000-c000-000000000000",
            "appDisplayName": "Office 365",
            "appId": "00000003-0000-0ff1-ce00-000000000000",
            "userAgent": "Microsoft Office/16.0",
            "isInteractive": true,
            "authenticationProtocol": "oAuth2",
            "conditionalAccessStatus": "success",
          },
        "p_event_time": "2025-01-15 10:00:30.789",
        "p_log_type": "Azure.Audit",
      }

Detection logic

Condition

not (properties.resourceDisplayName not contains "Microsoft Graph" or properties.appId in ["00000003-0000-0ff1-ce00-000000000000", "00000006-0000-0ff1-ce00-000000000000", "00b41c95-dab0-4487-9791-b9d2c32c80f2", "d3590ed6-52b3-4102-aeff-aad2292ab01c", "1fec8e78-bce4-4aaf-ab1b-5451cc387264", "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", "cc15fd57-2c6c-4117-a88c-83b1d56b4bbe", "ab9b8c07-8f02-4f72-87fa-80105867a763", "ea5a67f6-b6f3-4338-b240-c655ddc3cc8e", "ecd6b820-32c2-49b6-98a6-444530e5a77a", "f44b1140-bc5e-48c6-8dc0-5cf5a53c0e34", "797f4846-ba00-4fd7-ba43-dac1f8f63013", "8edd93e1-2103-40b4-bd70-6e34e586362d", "c44b4083-3bb0-49c1-b47d-974e53cbdf3c", "04b07795-8ddb-461a-bbee-02f9e1bf7b46", "4962773b-9cdb-44cf-a8bf-237846a00ab7", "fc780465-2017-40d4-a0c5-307022471b92", "8ee8fdad-f234-4243-8f3b-15c294843740", "2793995e-0a7d-40d7-bd35-6968ba142197", "3f6aecb4-6dbf-4e45-9141-440abdced562", "7b7531ad-5926-4f2d-8a1d-38495ad33e17", "df77edef-903d-416b-bcc0-cc8b91af54ea", "8b3391f4-af01-4ee8-b4ea-9871b2499735", "f8f7a2aa-e116-4ba6-8aea-ca162cfa310d", "01fc33a7-78ba-4d2f-a4b7-768e336e890e", "bd11ca0f-4fd6-4bb7-a259-4a36693b6e13", "abc63b55-0325-4305-9e1e-3463b182a6dc", "eace8149-b661-472f-b40d-939f89085bd4", "b46c3ac5-9da6-418f-a849-0a07a10b3c6c", "0469d4cd-df37-4d93-8a61-f8c75b809164", "18fbca16-2224-45f6-85b0-f7bf2b39b3f3", "98db8bd6-0cc0-4e67-9de5-f187f1cd1b41", "6821c7a6-ae62-49ba-8669-3f2e72d8d803", "7eadcef8-456d-4611-9480-4fff72b8b9e2"])
not (properties.isInteractive is_null or category eq "NonInteractiveUserSignInLogs")
not (properties.sessionId is_null or properties.userPrincipalName is_null or properties.ipAddress is_null or resultSignature ne "SUCCESS")

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
properties.resourceDisplayNamecontainsMicrosoft Graph
properties.appIdin00000003-0000-0ff1-ce00-000000000000, 00000006-0000-0ff1-ce00-000000000000, 00b41c95-dab0-4487-9791-b9d2c32c80f2, 01fc33a7-78ba-4d2f-a4b7-768e336e890e, 0469d4cd-df37-4d93-8a61-f8c75b809164, 04b07795-8ddb-461a-bbee-02f9e1bf7b46, 18fbca16-2224-45f6-85b0-f7bf2b39b3f3, 1fec8e78-bce4-4aaf-ab1b-5451cc387264, 2793995e-0a7d-40d7-bd35-6968ba142197, 3f6aecb4-6dbf-4e45-9141-440abdced562, 4962773b-9cdb-44cf-a8bf-237846a00ab7, 5e3ce6c0-2b1f-4285-8d4b-75ee78787346, 6821c7a6-ae62-49ba-8669-3f2e72d8d803, 797f4846-ba00-4fd7-ba43-dac1f8f63013, 7b7531ad-5926-4f2d-8a1d-38495ad33e17, 7eadcef8-456d-4611-9480-4fff72b8b9e2, 8b3391f4-af01-4ee8-b4ea-9871b2499735, 8edd93e1-2103-40b4-bd70-6e34e586362d, 8ee8fdad-f234-4243-8f3b-15c294843740, 98db8bd6-0cc0-4e67-9de5-f187f1cd1b41, ab9b8c07-8f02-4f72-87fa-80105867a763, abc63b55-0325-4305-9e1e-3463b182a6dc, b46c3ac5-9da6-418f-a849-0a07a10b3c6c, bd11ca0f-4fd6-4bb7-a259-4a36693b6e13, c44b4083-3bb0-49c1-b47d-974e53cbdf3c, cc15fd57-2c6c-4117-a88c-83b1d56b4bbe, d3590ed6-52b3-4102-aeff-aad2292ab01c, df77edef-903d-416b-bcc0-cc8b91af54ea, ea5a67f6-b6f3-4338-b240-c655ddc3cc8e, eace8149-b661-472f-b40d-939f89085bd4, ecd6b820-32c2-49b6-98a6-444530e5a77a, f44b1140-bc5e-48c6-8dc0-5cf5a53c0e34, f8f7a2aa-e116-4ba6-8aea-ca162cfa310d, fc780465-2017-40d4-a0c5-307022471b92
categoryeqNonInteractiveUserSignInLogs
properties.isInteractiveis_null(no value, null check)
properties.ipAddressis_null(no value, null check)
properties.sessionIdis_null(no value, null check)
properties.userPrincipalNameis_null(no value, null check)
resultSignatureneSUCCESS

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
properties.resourceDisplayNamecontains
  • Microsoft Graph

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
userPrincipalNameproperties.userPrincipalName
sessionIdproperties.sessionId