- Access exclusive content
- Connect with peers
- Share your expertise
- Find support resources
11-27-2025 02:30 AM
Hi,
Could you provide an XQL query to detect password spraying, specifically when the same IP address attempts logins on multiple AD accounts?
Thank you.
01-06-2026 12:11 PM
Hello @Hichamchakik ,
Greetings for the day!
The following query identifies unique IP addresses attempting to authenticate against multiple distinct accounts within a specified timeframe:
dataset = xdr_data
| filter action_evtlog_event_id in (4625, 4771, 4768, 4769) // Windows Logon Failure and Kerberos Pre-auth failure IDs
| alter
TargetUserName = json_extract_scalar(action_evtlog_data_fields, "$.TargetUserName"),
SourceIp = replace(json_extract_scalar(action_evtlog_data_fields, "$.IpAddress"), "::ffff:", "")
| filter TargetUserName != null and SourceIp not in ("-", "", "127.0.0.1", "::1")
| filter TargetUserName not contains "$" // Exclude machine accounts
| comp
count_distinct(TargetUserName) as unique_accounts_targeted,
count(TargetUserName) as total_failure_count,
values(TargetUserName) as list_of_accounts
by SourceIp
| filter unique_accounts_targeted > 10 // Threshold: More than 10 unique accounts from one IP
| sort desc unique_accounts_targeted
Licensing Requirements:
To collect and forward specific Windows Event Logs (such as Event ID 4625) from internal endpoints or Domain Controllers, an Extended Threat Hunting (XTH) add-on license is typically required.
Built-in Analytics:
Cortex XDR includes native analytics detectors for this behavior, such as “Internal Login Password Spray on many users.” These detectors are often set to Informational or Low severity by default unless the activity volume is exceptionally high.
Internal vs. External IPs:
Native XDR detectors are primarily optimized for external IP addresses. For internal IP addresses, behavior-based detection may require the baseline learning period (typically around 30 days) to be completed.
Data Extraction:
When querying xdr_data, usernames and IP addresses are often nested within the action_evtlog_data_fields JSON object and must be extracted using alter with json_extract_scalar (or equivalent operators).
If you are specifically investigating password spraying against GlobalProtect or VPN gateways, use the vpn_logs dataset:
dataset = vpn_logs
| filter auth_outcome = "FAILURE"
| comp
count_distinct(auth_identity) as unique_auth_ids,
values(auth_identity) as attempted_accounts
by auth_client // Source IP
| filter unique_auth_ids >= 5
If you feel this has answered your query, please let us know by clicking like and on "mark this as a Solution".
Happy New Year!!
Thanks & Regards,
S. Subashkar Sekar
Click Accept as Solution to acknowledge that the answer to your question has been provided.
The button appears next to the replies on topics you’ve started. The member who gave the solution and all future visitors to this topic will appreciate it!
These simple actions take just seconds of your time, but go a long way in showing appreciation for community members and the LIVEcommunity as a whole!
The LIVEcommunity thanks you for your participation!

