Detection rules › Kusto
Potential Password Spray Attack
'This query searches for failed attempts to log in from more than 15 various users within a 5 minutes timeframe from the same source. This is a potential indication of a password spray attack.'
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access | T1110 Brute Force |
Rule body kusto
id: 64d16e62-1a17-4a35-9ea7-2b9fe6f07118
name: Potential Password Spray Attack
description: |
'This query searches for failed attempts to log in from more than 15 various users within a 5 minutes timeframe from the same source. This is a potential indication of a password spray attack.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: SalesforceServiceCloudCCPDefinition
dataTypes:
- SalesforceServiceCloud
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1110
query: |
let FailureThreshold = 15;
SalesforceServiceCloud
| where EventType =~ 'Login' and LoginStatus != 'LOGIN_NO_ERROR'
| where LoginStatus in~ ('LOGIN_ERROR_INVALID_PASSWORD', 'LOGIN_ERROR_SSO_PWD_INVALID')
| extend TimestampDerived = todatetime(TimestampDerived)
| summarize UserCount=dcount(UserId), Users = make_set(UserId,100) by ClientIp, bin(TimestampDerived, 5m)
| where UserCount > FailureThreshold
customDetails:
Users: Users
entityMappings:
- entityType: IP
fieldMappings:
- identifier: Address
columnName: ClientIp
version: 1.0.4
kind: Scheduled
Stages and Predicates
Parameters
let FailureThreshold = 15;
Stage 1: source
SalesforceServiceCloud
Stage 2: where
| where EventType =~ 'Login' and LoginStatus != 'LOGIN_NO_ERROR'
Stage 3: where
| where LoginStatus in~ ('LOGIN_ERROR_INVALID_PASSWORD', 'LOGIN_ERROR_SSO_PWD_INVALID')
Stage 4: extend
| extend TimestampDerived = todatetime(TimestampDerived)
Stage 5: summarize
| summarize UserCount=dcount(UserId), Users = make_set(UserId,100) by ClientIp, bin(TimestampDerived, 5m)
Stage 6: where
| where UserCount > FailureThreshold
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
EventType | eq |
|
LoginStatus | in |
|
LoginStatus | ne |
|
UserCount | gt |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
ClientIp | summarize |
UserCount | summarize |
Users | summarize |