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.
What is T1589 Gather Victim Identity Information?
Gather Victim Identity Information (T1589) maps to the Reconnaissance tactic — the adversary is trying to gather information they can use to plan future operations in MITRE ATT&CK.
This page provides production-ready detection logic for Gather Victim Identity Information, covering the data sources and telemetry it touches: Azure Active Directory, Microsoft Entra ID. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Reconnaissance
- Technique
- T1589 Gather Victim Identity Information
- Canonical reference
- https://attack.mitre.org/techniques/T1589/
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 Detects adversary username enumeration via two vectors: (1) Azure AD sign-in attempts producing differential error codes (50034=UserNameDoesNotExist vs. password errors) from a single source IP across 15+ distinct usernames within an hour, and (2) Self-Service Password Reset flow abuse targeting multiple unique accounts. Combines both signals to surface identity reconnaissance activity consistent with LAPSUS$, Scattered Spider, and HEXANE TTPs.
Data Sources
Required Tables
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
Sigma rule & cross-platform mapping
The detection logic for Gather Victim Identity Information (T1589) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
product: azure Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for T1589
References (6)
- https://attack.mitre.org/techniques/T1589/
- https://grimblog.net/post/username-enumeration-o365/
- https://www.obsidian.security/blog/sspr-abuse-2023
- https://www.microsoft.com/security/blog/2022/03/22/dev-0537-criminal-actor-targeting-organizations-for-data-exfiltration-and-destruction/
- https://www.mandiant.com/resources/blog/lapsus-recent-techniques-tactics-and-procedures
- https://www.clearskysec.com/siamesekitten/
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Azure AD Username Enumeration via GetCredentialType API
Expected signal: Azure AD Sign-in Logs (AADSignInLogs) will show ResultType=50034 (UserNameDoesNotExist) for non-existent accounts. Successful lookups may show ResultType=0 or MFA-related codes. Source IP will be the test machine's public IP. Check Azure AD portal under Monitoring > Sign-in Logs filtering by the test domain.
- Test 2On-Premises Active Directory Username Enumeration via Kerberos
Expected signal: Windows Security Event ID 4625 with SubStatus 0xc0000064 (user does not exist) on domain controller for each non-existent username tested. Event ID 4625 with SubStatus 0xc000006a (wrong password) for valid usernames. Event ID 4771 with Status 0x6 on DCs running Kerberos logging. Check DC Security event logs filtering: EventID=4625 AND (SubStatus=0xc0000064 OR SubStatus=0xc0000072).
- Test 3SSPR Username Existence Probing via Azure AD Password Reset Flow
Expected signal: Azure AD Audit Logs will contain SSPR-related entries under 'Self-service password reset flow activity' and 'Verify email address phone number'. Check Azure portal: Azure Active Directory > Monitoring > Audit Logs, filter Activity='Reset password (self-service)' or 'Self-service password management'. In Sentinel: AuditLogs | where OperationName contains 'password' | where TimeGenerated > ago(1h)
Unlock Pro Content
Get the full detection package for T1589 including response playbook, investigation guide, and atomic red team tests.