Potential Token Replay from Different ASNs
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.
Potential Token Replay from Different ASNs
Analytic #1This analytic looks for cases where we see two different ASNs for the initial authentication to an app in Entra, and then a second and different ASN, for the same token, in GraphAPI logs. This could be indicative of token replay. There’s also an exclusion list to bin off noise from Microsoft, any any other ranges you’re not interested in.
Detection Queries
let ExcludedGraphASNs = dynamic([8075]);
let CIDRASN = (externaldata (CIDR:string, CIDRASN:int, CIDRASNName:string)
['https://firewalliplists.gypthecat.com/lists/kusto/kusto-cidr-asn.csv.zip']
with (ignoreFirstRecord=true));
let GraphLogs =
MicrosoftGraphActivityLogs
| evaluate ipv4_lookup(CIDRASN, IPAddress, CIDR, return_unmatched=true)
| extend GraphASN = CIDRASN
| extend GraphASNName = CIDRASNName
| project SignInActivityId, GraphIPAddress = IPAddress, GraphASN, GraphASNName,
Location, ResponseStatusCode, UserAgent, RequestMethod, RequestUri, TimeGenerated;
let AADLogs =
AADNonInteractiveUserSignInLogs
| extend TokenDetails = parse_json(TokenProtectionStatusDetails)
| extend signInSessionStatus = tostring(TokenDetails.signInSessionStatus)
| project UniqueTokenIdentifier, AADIPAddress = IPAddress,
AADLocation = Location, AADASN = AutonomousSystemNumber,
DeviceName = tostring(parse_json(DeviceDetail).displayName),
signInSessionStatus, Identity, AppDisplayName;
GraphLogs
| join kind=inner (AADLogs) on $left.SignInActivityId == $right.UniqueTokenIdentifier
| where isnotempty(GraphASN) and isnotempty(AADASN)
| where GraphASN != AADASN
| where GraphASN !in (ExcludedGraphASNs)
| project TimeGenerated, SignInActivityId, Identity, AppDisplayName,
GraphIPAddress, GraphASN, GraphASNName,
AADIPAddress, AADASN,
Location, AADLocation,
DeviceName, signInSessionStatus,
RequestMethod, RequestUri, ResponseStatusCode, UserAgent
| order by TimeGenerated desc
Triage Steps
- Review the ASN mismatch between the initial authentication location and Graph API access location
- Check if the user has legitimate reasons to travel between these geographic locations
- Investigate the application involved and verify if it's authorized within your environment
- Review the Graph API requests to identify what data was accessed during the suspected replay
- Check if the UserAgent indicates automated tooling or custom scripts
- Verify the token protection status - unbound tokens are easier to replay
- Look for other suspicious activity from the same user or application within the same timeframe
- If confirmed malicious, revoke the application's access and reset user credentials
True Positive Example
Example 1
{
"log_entry": {
"TimeGenerated": "06/12/2025, 14:14:07.035",
"SignInActivityId": "70ObFHiCDUW42aMM2OEcAA",
"Identity": "Hunter",
"AppDisplayName": "TruffleHog Test App",
"GraphIPAddress": "79.135.105.18",
"GraphASN": 212238,
"GraphASNName": "Datacamp Limited",
"AADIPAddress": "85.139.240.135",
"AADASN": 2856,
"Location": "UAE North",
"AADLocation": "GB",
"DeviceName": "HUNTERWORK",
"signInSessionStatus": "bound",
"RequestMethod": "GET",
"RequestUri": "https://graph.microsoft.com/v1.0/me/followedSites",
"ResponseStatusCode": 403,
"UserAgent": "data_exfil_tool"
}
} Token replay detected from different ASN. The access token was obtained from ASN 2856 (GB) but replayed from ASN 212238 (UAE North/Datacamp Limited), indicating potential token theft and replay attack.
Example 2
{
"log_entry": {
"TimeGenerated": "06/12/2025, 14:14:05.738",
"SignInActivityId": "70ObFHiCDUW42aMM2OEcAA",
"Identity": "Hunter",
"AppDisplayName": "TruffleHog Test App",
"GraphIPAddress": "79.135.105.18",
"GraphASN": 212238,
"GraphASNName": "Datacamp Limited",
"AADIPAddress": "85.139.240.135",
"AADASN": 2856,
"Location": "UAE North",
"AADLocation": "GB",
"DeviceName": "HUNTERWORK",
"signInSessionStatus": "bound",
"RequestMethod": "GET",
"RequestUri": "https://graph.microsoft.com/v1.0/me/drive/recent?%24top=5",
"ResponseStatusCode": 200,
"UserAgent": "data_exfil_tool"
}
} Successful token replay accessing user's recent files. The attacker successfully accessed sensitive data from a different geographic location using the stolen token.
Example 3
{
"log_entry": {
"TimeGenerated": "06/12/2025, 14:13:54.940",
"SignInActivityId": "70ObFHiCDUW42aMM2OEcAA",
"Identity": "Hunter",
"AppDisplayName": "TruffleHog Test App",
"GraphIPAddress": "79.135.105.18",
"GraphASN": 212238,
"GraphASNName": "Datacamp Limited",
"AADIPAddress": "85.139.240.135",
"AADASN": 2856,
"Location": "UAE North",
"AADLocation": "GB",
"DeviceName": "HUNTERWORK",
"signInSessionStatus": "bound",
"RequestMethod": "GET",
"RequestUri": "https://graph.microsoft.com/v1.0/me/drive/root/search(q='%7B%7D')?%24top=5",
"ResponseStatusCode": 200,
"UserAgent": "data_exfil_tool"
}
} Attacker performing search operations on user's OneDrive from unauthorized location. The custom UserAgent 'data_exfil_tool' combined with ASN mismatch indicates automated data exhilaration activity.