Query Details
// HQ-015 — Identity SSPR Followed by Risky Sign-In
// Purpose : Detect cases where a user resets their own password via SSPR and then
// performs a risky sign-in within 24 hours.
// This sequence may indicate an attacker who obtained enough identity
// signals (email / phone) to pass SSPR verification but whose sign-in
// still triggers Entra ID risk detection (unfamiliar IP, impossible travel, etc.).
// Tables : AuditLogs, SigninLogs
// MITRE : TA0006 Credential Access — T1110.004 Password Spraying (post-reset attempt)
// TA0001 Initial Access — T1078 Valid Accounts
// Author : Custom
// ---------------------------------------------------------------------------
let LookbackDays = 14d;
let RiskySigninWindow = 24h; // Max time after SSPR for risky sign-in to count
let SSPRActivities = dynamic([
"Reset password (self-service)",
"Self-service password reset flow activity progress",
"User registered for self-service password reset",
"Reset password",
"User completed security info registration",
"User started security info registration"
]);
// ── Step 1: SSPR events ────────────────────────────────────────────────────
let SSPREvents = AuditLogs
| where TimeGenerated > ago(LookbackDays)
| where ActivityDisplayName in~ (SSPRActivities)
// Accept any logging service — SSPR can appear under Core Directory or Self-service
| extend SSPRUserUPN = tolower(coalesce(
tostring(TargetResources[0].userPrincipalName),
tostring(InitiatedBy.user.userPrincipalName)
))
| where isnotempty(SSPRUserUPN)
| project
SSPRTime = TimeGenerated,
SSPRUserUPN,
SSPRActivity = ActivityDisplayName,
SSPRResult = Result,
LoggedByService;
// ── Step 2: Risky sign-ins ─────────────────────────────────────────────────
let RiskySignIns = SigninLogs
| where TimeGenerated > ago(LookbackDays)
| where RiskLevelDuringSignIn in ("high", "medium")
or RiskState == "atRisk"
or IsRisky == true
| project
SigninTime = TimeGenerated,
SigninUPN = tolower(UserPrincipalName),
RiskLevel = RiskLevelDuringSignIn,
RiskState,
RiskDetail,
RiskEventTypes = tostring(RiskEventTypes_V2),
IPAddress,
AppDisplayName,
LocationDetails,
ConditionalAccessStatus,
SigninCorrelationId = CorrelationId;
// ── Step 3: Correlate — risky sign-in within window AFTER SSPR ────────────
SSPREvents
| join kind=inner (RiskySignIns)
on $left.SSPRUserUPN == $right.SigninUPN
| where SigninTime > SSPRTime
and SigninTime <= (SSPRTime + RiskySigninWindow)
| extend TimeFromSSPRToRiskySignin = SigninTime - SSPRTime
| project
SSPRTime,
SSPRUserUPN,
SSPRActivity,
SSPRResult,
SigninTime,
RiskLevel,
RiskState,
RiskDetail,
RiskEventTypes,
IPAddress,
AppDisplayName,
LocationDetails,
ConditionalAccessStatus,
TimeFromSSPRToRiskySignin,
SigninCorrelationId
| sort by SSPRTime desc
This query is designed to identify situations where a user resets their password using Self-Service Password Reset (SSPR) and then has a risky sign-in within 24 hours. This pattern might suggest that an attacker has gained enough information to reset the password but still triggers a risk alert when signing in.
Here's a simplified breakdown of the query:
Lookback Period: The query examines events from the past 14 days.
SSPR Events: It first identifies SSPR activities from the AuditLogs table, focusing on events like password resets and security info registration. It extracts the time of the event, the user's principal name, the type of SSPR activity, and the result.
Risky Sign-Ins: Next, it looks for sign-ins from the SigninLogs table that are marked as risky (high or medium risk, or explicitly flagged as "at risk"). It gathers details such as the time of sign-in, user principal name, risk level, IP address, and other sign-in details.
Correlation: The query then correlates the SSPR events with risky sign-ins for the same user. It checks if the risky sign-in occurred within 24 hours after the SSPR event.
Output: Finally, it outputs a list of these correlated events, including details about the SSPR and sign-in activities, sorted by the time of the SSPR event.
This query helps detect potential security incidents where an attacker might have reset a user's password and attempted to sign in, but the sign-in was flagged as risky due to unusual behavior or location.

David Alonso
Released: April 6, 2026
Tables
Keywords
Operators