Detection rules › Kusto

Potential Password Spray Attack

Status
available
Severity
medium
Time window
1h
Group by
ClientIp
Source
github.com/Azure/Azure-Sentinel

'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

TacticTechniques
Credential Access

Rule body

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

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
ClientIpsummarize
UserCountsummarize
Userssummarize