Detection rules › YARA-L
Hunt for Expired Tokens Attempting to sign-in to Entra ID
Identify Entra ID OAuth refresh tokens are attempted to be used but have expired. This could be because the token hasn't been used for 90 days or it has been revoked
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Lateral Movement |
Rule body
// Copyright 2025 Google LLC. Licensed under Apache-2.0.
rule entra_id_expired_refresh_token_use {
meta:
author = "Google Cloud Security"
description = "Identify Entra ID OAuth refresh tokens are attempted to be used but have expired. This could be because the token hasn't been used for 90 days or it has been revoked"
rule_id = "mr_88826f0a-e964-4d11-8765-8732ae83b1f1"
rule_name = "Hunt for Expired Tokens Attempting to sign-in to Entra ID"
tactic = "TA0008"
technique = "T1550.001"
type = "Hunt"
data_source = "Azure Activity"
platform = "Azure"
severity = "Low"
priority = "Low"
events:
$login.metadata.event_type = "USER_LOGIN"
$login.metadata.product_name = "Azure Activity"
$login.metadata.product_event_type = "Sign-in activity"
$login.metadata.vendor_name = "Microsoft"
$login.security_result.action = "BLOCK"
//$login.metadata.description = "Fresh auth token is needed. Have the user re-sign using fresh credentials."
$login.security_result.action_details = "50173"
$login.principal.user.userid = $userid
match:
$userid over 15m
outcome:
$risk_score = 15
$event_count = count_distinct($login.metadata.id)
$principal_ip = array_distinct($login.principal.ip)
$user_agent = array_distinct($login.network.http.user_agent)
$target_application = array_distinct($login.target.application)
condition:
$login
}
YARA-L rule structure
Condition
Fires when at least one $login event in the 15m window.
Events
$login
metadata.product_event_type = "Sign-in activity"security_result.action = "BLOCK"security_result.action_details = "50173"
Match and correlation
Outcome
Outcome variables add context to a detection. When the rule generates an alert, $risk_score is displayed with it.
| Field | Expression |
|---|---|
risk_score | 15 |
event_count | count_distinct($login.metadata.id) |
principal_ip | array_distinct($login.principal.ip) |
user_agent | array_distinct($login.network.http.user_agent) |
target_application | array_distinct($login.target.application) |