Query Details

Session Ids From Multiple OS And User Agents Token Theft Session Hijack Detection

Query

// thx to my ♥ Buddy Sergio Albea for the wonderful ASN Part from this Query
let CIDRASN = (externaldata (CIDR:string, CIDRASN:int, CIDRASNName:string)
['https://firewalliplists.gypthecat.com/lists/kusto/kusto-cidr-asn.csv.zip']
with (ignoreFirstRecord=true));
EntraIdSignInEvents
| where TimeGenerated > ago(12h)
| where isnotempty(SessionId)
| where UserAgent !contains "node-fetch"
| extend OS = tostring(parse_user_agent(UserAgent, "os").OperatingSystemFamily)
| extend Browser = tostring(parse_user_agent(UserAgent, "browser").BrowserFamily)
| evaluate ipv4_lookup(CIDRASN, IPAddress, CIDR, return_unmatched=true)
| summarize 
    OSFamilyCount = dcount(OS),
    BrowserFamilyCount = dcount(Browser),
    IPAddressCount = dcount(IPAddress),
    ASNCount = dcount(CIDRASNName),
    IPAddressList = make_set(IPAddress),
    ASNNameList = make_set(CIDRASNName),
    UserAgentList = make_set(UserAgent),
    UserPrincipalNames = make_set(AccountUpn) 
    by SessionId
| where IPAddressCount > 1 
| where OSFamilyCount > 1 or BrowserFamilyCount > 1

About this query

Explanation

This query is designed to detect suspicious login activities that may indicate session hijacking or token theft. It focuses on identifying "impossible travel" scenarios where a single user session, identified by a SessionId, shows sign-ins from multiple distinct IP addresses and changes in the operating system or browser within a short timeframe. This behavior suggests that an attacker might have compromised a user's credentials and is trying to access resources from different locations or devices, potentially bypassing security measures like multi-factor authentication.

Here's a simplified breakdown of the query:

  1. Data Source: The query analyzes sign-in events from the EntraIdSignInEvents table over the past 12 hours (or 3 days in the extended version).

  2. Session Filtering: It filters out sessions without a SessionId and those using a specific user agent ("node-fetch").

  3. User Agent Parsing: The query extracts the operating system and browser family from the user agent string.

  4. IP and ASN Lookup: It uses an external data source to map IP addresses to their respective Autonomous System Numbers (ASNs).

  5. Session Analysis: The query summarizes data by SessionId, counting distinct operating systems, browsers, IP addresses, and ASNs. It also compiles lists of IP addresses, ASNs, user agents, and user principal names associated with each session.

  6. Suspicious Activity Detection: It flags sessions with more than one IP address and either multiple operating systems or browsers as suspicious.

  7. Output: The query outputs sessions that meet these criteria, providing details like the number of distinct ASNs, lists of IP addresses, user agents, and user principal names.

Overall, this query helps security teams identify potential security breaches by highlighting unusual login patterns that could indicate compromised user sessions.

Details

Benjamin Zulliger profile picture

Benjamin Zulliger

Released: April 25, 2026

Tables

EntraIdSignInEvents

Keywords

SessionIdsUserAgentsTokenTheftSessionHijackDetectionMultiFactorAuthenticationInterceptionExternalRemoteServicesImpossibleTravelScenariosIPAddressesOperatingSystemBrowserFamilyAttackersCredentialsResourcesLocationsDevicesControlsBenjaminZulligerSergioAlbeaASNEntraIdSignInEventsTimeGeneratedOSIPAddressAccountUpnCIDRASNName

Operators

letexternaldatawithwhereisnotempty!containsextendtostringparse_user_agentevaluateipv4_lookupsummarizedcountmake_setby>ormaterializeprojectproject-awayhint.shufflekeymv-expanddistinctjoinkind=leftoutertake_any

MITRE Techniques

Actions

GitHub