Spike in invalid token usage (50173)
Platform
Data Sources
Related Blog Post
Read the full blog post about this hunt →MITRE ATT&CK
Tactics
Techniques
Threat Actors
Tags
Hunt Hypothesis
Threat Actors will use token theft as a means of initial access, privilege escalation and persistence. Poorly secured tokens by third parties can increase the risk of token theft and replay.
Spike in invalid token usage (50173)
Analytic #1This analytic looks for cases where there is a spike in invalid token usage, with a short time span. This could be indicative of mass token replay against accounts. This analytic is reliant on the error code 50173 "The provided grant has expired due to it being revoked, a fresh auth token is needed.....". This could indicate exfiltration of tokens for replay where some of the tokens have expired or are no longer valid.
Detection Queries
let LookbackPeriod = 7d;
let BinSize = 5m; // Tighter window to catch bursts
let MinEvents = 10;
AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(LookbackPeriod)
| where ResultType == 50173
| summarize
Count = count(),
UniqueIPs = dcount(IPAddress),
IPAddresses = make_set(IPAddress),
UniqueTokens = dcount(UniqueTokenIdentifier),
UniqueUsers = dcount(UserPrincipalName),
Users = make_set(UserPrincipalName),
Locations = make_set(Location),
UniqueLocations = dcount(Location),
UserAgents = make_set(UserAgent),
ResourcesAccessed = make_set(ResourceDisplayName),
IncomingTokenTypes = make_set(IncomingTokenType),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by bin(TimeGenerated, BinSize), AppDisplayName, AppId
| where Count >= MinEvents
| extend
TimeWindow = strcat(format_datetime(FirstSeen, 'HH:mm:ss'), " - ", format_datetime(LastSeen, 'HH:mm:ss')),
IPLocationRatio = round(todouble(UniqueIPs) / todouble(UniqueLocations), 2),
TokensPerIP = round(todouble(UniqueTokens) / todouble(UniqueIPs), 2)
| project
TimeGenerated,
TimeWindow,
AppDisplayName,
AppId,
Count,
UniqueIPs,
UniqueTokens,
UniqueUsers,
UniqueLocations,
IPLocationRatio,
TokensPerIP,
IPAddresses,
Users,
Locations,
UserAgents,
ResourcesAccessed,
IncomingTokenTypes
| order by Count desc
Triage Steps
- Review the time window and count of failed authentications - high volume in short time indicates mass replay
- Check if there were recent password changes or token revocations for the affected users
- Investigate the application generating the invalid token errors
- Review if multiple users are affected or just a single account
- Analyze the UserAgent to identify if automated tooling is being used
- Check the IP addresses and locations to identify potential attacker infrastructure
- Look for successful authentications before or after the spike that may indicate compromise
- If confirmed mass replay attempt, reset credentials and revoke application access
True Positive Example
Example 1
{
"TimeGenerated": "06/12/2025, 19:55:00.000",
"TimeWindow": "19:55:02 - 19:57:07",
"AppDisplayName": "TruffleHog Test App",
"AppId": "c32a4v3a-c5bd-4d70-b388-091430657d83",
"Count": 86,
"UniqueIPs": 1,
"UniqueTokens": 86,
"UniqueUsers": 1,
"UniqueLocations": 1,
"IPLocationRatio": 1,
"TokensPerIP": 86,
"IPAddresses": [
"79.135.105.18"
],
"Users": [
"hunter1@REDACTED.onmicrosoft.com"
],
"Locations": [
"AZ"
],
"UserAgents": [
"python-requests/2.31.0"
],
"ResourcesAccessed": [
"Microsoft Graph"
],
"IncomingTokenTypes": [
"refreshToken"
],
"UserDisplayName": "Hunter",
"ResourceDisplayName": "Microsoft Graph",
"IPAddress": "79.135.105.18",
"Location": "AZ",
"Browser": "Python Requests 2.31",
"DeviceId": "",
"IncomingTokenType": "refreshToken",
"SessionStatus": "unbound"
} Mass replay attempt detected - 86 invalid tokens attempted in a 2-minute window from a single IP using Python automation. This pattern indicates an attacker attempting to use a large cache of stolen tokens, many of which have been revoked or expired.
Example 2
{
"TimeGenerated": "06/12/2025, 19:50:00.000",
"TimeWindow": "19:54:24 - 19:54:57",
"AppDisplayName": "TruffleHog Test App",
"AppId": "ca2a4f3a-c6bd-4b70-b888-0914b0657d83",
"Count": 13,
"UniqueIPs": 1,
"UniqueTokens": 13,
"UniqueUsers": 1,
"UniqueLocations": 1,
"IPLocationRatio": 1,
"TokensPerIP": 13,
"IPAddresses": [
"79.135.105.18"
],
"Users": [
"hunter1@REDACTED.onmicrosoft.com"
],
"Locations": [
"AZ"
],
"UserAgents": [
"python-requests/2.31.0"
],
"ResourcesAccessed": [
"Microsoft Graph"
],
"IncomingTokenTypes": [
"refreshToken"
],
"UserDisplayName": "Hunter",
"ResourceDisplayName": "Microsoft Graph",
"IPAddress": "79.135.105.18",
"Location": "AZ",
"Browser": "Python Requests 2.31",
"DeviceId": "",
"IncomingTokenType": "refreshToken",
"SessionStatus": "unbound"
} Smaller burst of 13 invalid token attempts in 33 seconds. While lower volume than the previous spike, the rapid-fire automation pattern is consistent with credential stuffing or token replay attacks from compromised application data.