T1589

Gather Victim Identity Information

This detection identifies adversary attempts to enumerate victim identity information—credentials, email addresses, and employee names—through active probing of authentication services and monitoring of downstream indicators of OSINT-driven targeting. Since T1589 is a PRE-ATT&CK technique occurring largely outside victim infrastructure, detection focuses on second-order observable signals: anomalous username enumeration via Azure AD sign-in failures with differential error codes (e.g., UserNameDoesNotExist vs. InvalidPassword), Self-Service Password Reset (SSPR) flow abuse, high-volume authentication probing from single sources against multiple distinct accounts, and MFA method enumeration patterns. Groups such as LAPSUS$, Scattered Spider, and HEXANE have exploited these mechanisms to build target identity lists before launching phishing, credential stuffing, or social engineering campaigns.

Microsoft Sentinel / Defender
kusto
let lookback = 1h;
let enumThreshold = 15;
// Primary: Azure AD username enumeration via differential auth error codes
let AzureADEnum = AADSignInLogs
| where TimeGenerated > ago(lookback)
| where ResultType in ("50034", "50053", "50055", "50057", "50072", "50076")
// 50034=UserNameDoesNotExist, 50053=AccountLocked, 50055=PasswordExpired, 50057=AccountDisabled
| extend 
    IsUsernameNotFound = iff(ResultType == "50034", 1, 0),
    IsLockedOrDisabled = iff(ResultType in ("50053", "50057"), 1, 0)
| summarize 
    TotalFailures = count(),
    UniqueUsernames = dcount(UserPrincipalName),
    UsernameNotFoundCount = sum(IsUsernameNotFound),
    LockedDisabledCount = sum(IsLockedOrDisabled),
    UserList = make_set(UserPrincipalName, 25),
    ErrorCodes = make_set(ResultType),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
    by IPAddress, AppDisplayName, ResultDescription
| where UniqueUsernames >= enumThreshold
| extend 
    DurationMinutes = datetime_diff('minute', LastSeen, FirstSeen),
    EnumRate = round(todouble(UniqueUsernames) / iff(datetime_diff('minute', LastSeen, FirstSeen) == 0, 1, todouble(datetime_diff('minute', LastSeen, FirstSeen))), 2),
    SuspicionScore = case(
        UniqueUsernames >= 100, "Critical",
        UniqueUsernames >= 50 or UsernameNotFoundCount >= 30, "High",
        UniqueUsernames >= 15, "Medium",
        "Low"
    )
| project 
    DetectionTime = LastSeen,
    IPAddress,
    AppDisplayName,
    UniqueUsernames,
    TotalFailures,
    UsernameNotFoundCount,
    EnumRate,
    SuspicionScore,
    UserList,
    ErrorCodes,
    DurationMinutes
| order by UniqueUsernames desc;
// Secondary: SSPR abuse for identity enumeration
let SSPREnum = AuditLogs
| where TimeGenerated > ago(lookback)
| where OperationName in ("Reset password (self-service)", "Self-service password reset flow activity", "Verify email address phone number")
| where ResultReason contains "blocked" or ResultReason contains "failed" or ActivityDisplayName contains "verify"
| extend IPAddress = tostring(InitiatedBy.user.ipAddress)
| where isnotempty(IPAddress)
| summarize
    SSPRAttempts = count(),
    UniqueTargets = dcount(tostring(TargetResources[0].userPrincipalName)),
    TargetList = make_set(tostring(TargetResources[0].userPrincipalName), 25),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
    by IPAddress
| where UniqueTargets >= 10
| extend DetectionType = "SSPR_Enumeration", SuspicionScore = iff(UniqueTargets >= 25, "High", "Medium")
| project DetectionTime = LastSeen, IPAddress, UniqueTargets, SSPRAttempts, SuspicionScore, TargetList;
// Union both detection signals
AzureADEnum
| extend DetectionType = "Auth_Username_Enumeration"
| union (SSPREnum | extend UniqueUsernames = UniqueTargets, TotalFailures = SSPRAttempts, UserList = TargetList, UsernameNotFoundCount = 0, EnumRate = 0.0, ErrorCodes = dynamic(["SSPR"]), DurationMinutes = 0)
| order by SuspicionScore asc, UniqueUsernames desc
high severity medium confidence

Data Sources

Azure Active Directory Microsoft Entra ID

Required Tables

AADSignInLogs AuditLogs

False Positives

  • Penetration testing engagements performing authorized username enumeration against Azure AD tenants
  • Misconfigured applications cycling through user lists for automated login (e.g., legacy SSO, misconfigured service accounts)
  • Employee self-service helpdesk tools that probe SSPR status for multiple users during bulk account operations
  • Password expiration notification systems contacting multiple accounts in rapid succession
  • IT onboarding scripts performing bulk account validation during directory synchronization

Unlock Pro Content

Get the full detection package for T1589 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections