Detect Gather Victim Identity Information in Google Chronicle
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.
MITRE ATT&CK
- Tactic
- Reconnaissance
- Technique
- T1589 Gather Victim Identity Information
- Canonical reference
- https://attack.mitre.org/techniques/T1589/
YARA-L Detection Query
rule t1589_victim_identity_enumeration {
meta:
author = "Security Operations"
description = "Detects adversary username enumeration via differential authentication error codes (T1589 — Gather Victim Identity Information). Triggers when a single source IP probes >= 15 distinct account names within 1 hour using auth error codes that distinguish non-existent from valid-but-failed accounts. Covers Azure AD sign-in codes and on-prem Windows/Kerberos failures normalized to UDM."
mitre_attack_tactic = "Reconnaissance"
mitre_attack_technique = "T1589"
mitre_attack_subtechnique = "T1589.001"
reference = "https://attack.mitre.org/techniques/T1589/"
severity = "HIGH"
confidence = "HIGH"
version = "1.0"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "BLOCK"
(
// Azure AD / Entra ID error codes — UserNameDoesNotExist, AccountLocked, AccountDisabled, PasswordExpired, MFA required
$e.security_result.rule_id = "50034" or
$e.security_result.rule_id = "50053" or
$e.security_result.rule_id = "50055" or
$e.security_result.rule_id = "50057" or
$e.security_result.rule_id = "50072" or
$e.security_result.rule_id = "50076" or
// On-prem Kerberos and NTLM failure descriptions normalized via Chronicle Windows parser
re.regex($e.security_result.description,
`(?i)(UserNameDoesNotExist|AccountLocked|AccountDisabled|PasswordExpired|client\s*not\s*found|0xc0000064|0xC0000072|0xC000006D|KDC_ERR_C_PRINCIPAL_UNKNOWN)`) or
// Windows Event 4625 SubStatus via product_event_type
($e.metadata.product_event_type = "4625" and
re.regex($e.security_result.description, `(?i)(0xc0000064|0xc0000072|0xc000006d)`)) or
// Kerberos Event 4771
($e.metadata.product_event_type = "4771" and
re.regex($e.security_result.description, `(?i)(0x0+6\b|0x18\b|0x0+18\b)`))
)
$e.principal.ip = $src_ip
$e.target.user.userid = $username
not net.ip_in_range_cidr($src_ip, "127.0.0.0/8")
not net.ip_in_range_cidr($src_ip, "::1/128")
$username != "-"
$username != ""
$username != "ANONYMOUS LOGON"
match:
$src_ip over 1h
outcome:
$unique_user_count = count_distinct($username)
$total_failures = count($e.metadata.id)
$suspicion_level = if(
$unique_user_count >= 100, "Critical",
if($unique_user_count >= 50, "High",
if($unique_user_count >= 15, "Medium", "Low")
)
)
condition:
#username >= 15
} Chronicle YARA-L 2.0 detection for T1589 victim identity enumeration. Groups USER_LOGIN BLOCK events by source IP over a 1-hour rolling window and triggers when >=15 distinct target usernames are observed from the same IP. The `#username >= 15` condition counts distinct values bound to `$username` within the match window, equivalent to the KQL `dcount(UserPrincipalName) >= enumThreshold` predicate. Covers Azure AD Entra ID error codes (50034/50053/50055/50057/50072/50076) alongside on-prem Windows NTLM SubStatus and Kerberos failure codes via regex matching on normalized UDM `security_result.description`. Chronicle log types AZURE_AD, WINDOWS_AD, and MICROSOFT_365 are primary data sources. Outcome fields provide unique user count and suspicion scoring for alert enrichment.
Data Sources
Required Tables
False Positives & Tuning
- Authorized internal security tooling (SOAR enrichment, UEBA baseline collectors) that performs batch identity resolution against Azure AD or on-prem AD for alert context, generating many USER_LOGIN BLOCK events from a single internal service account host IP
- SSO reverse proxies, WAFs, or application delivery controllers that forward authentication requests from many external users behind a single egress NAT address, causing the single-source grouping to aggregate what are actually distributed end-user failures
- Automated provisioning or deprovisioning workflows (Workday, ServiceNow HR integrations) that verify account existence for large employee cohorts during onboarding or offboarding runs, producing sequential auth failures from a single orchestration host
- Cloud application misconfigurations where a service principal retries authentication across multiple tenant IDs or user UPNs before failing over, producing multi-target failures from a single client IP within a short window
- Security assessment platforms (Tenable Identity Exposure, Semperis DSP) performing continuous Active Directory health monitoring that incidentally generates authentication probes for discovered accounts
Other platforms for T1589
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)
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/
Unlock Pro Content
Get the full detection package for T1589 including response playbook, investigation guide, and atomic red team tests.