Detection rules › Kusto

StealthTalk - Password brute force

Status
available
Severity
high
Time window
5h
Source
github.com/Azure/Azure-Sentinel

Identifies a brute-force authentication attempt against a single StealthTalk user account. The StealthTalk anti-brute-force subsystem emits a MultiFailLogin event when consecutive failed attempts trigger an automatic account lockout. This rule fires when the reported number of consecutive failures is 9 or more, distinguishing a credential-guessing attack from an isolated user error. The lockout duration (LoginBlockingSeconds) is surfaced as a custom detail so the SOC analyst can prioritise by attack persistence.

MITRE ATT&CK coverage

TacticTechniques
Credential Access

Rule body

id: b8e5f3a2-9c4d-4d1f-8a7b-3c2d1e0f9a8b
name: StealthTalk - Password brute force
description: |
  Identifies a brute-force authentication attempt against a single StealthTalk user account. The StealthTalk anti-brute-force subsystem emits a `MultiFailLogin` event when consecutive failed attempts trigger an automatic account lockout. This rule fires when the reported number of consecutive failures is 9 or more, distinguishing a credential-guessing attack from an isolated user error. The lockout duration (`LoginBlockingSeconds`) is surfaced as a custom detail so the SOC analyst can prioritise by attack persistence.
severity: High
requiredDataConnectors:
  - connectorId: StealthTalkAnomalousAuth
    dataTypes:
      - StealthTalkAnomalousAuth_CL
queryFrequency: 15m
queryPeriod: 5h
triggerOperator: gt
triggerThreshold: 0
status: Available
tactics:
  - CredentialAccess
  - InitialAccess
relevantTechniques:
  - T1110
query: |
  let LookbackPeriod    = 5h;
  let MinFailedAttempts = 9;
  StealthTalkAnomalousAuth_CL
  | where TimeGenerated >= ago(LookbackPeriod)
  | where EventType == "MultiFailLogin"
  | where PassedAttempts >= MinFailedAttempts
  | extend
      BlockingMinutes = LoginBlockingSeconds / 60,
      AlertName       = "PasswordBruteForce",
      AlertDetails    = strcat(
          "User ", UserId,
          " had ", PassedAttempts, " consecutive failed login attempts",
          " on device ", DeviceId, ".",
          " Account blocked for ", LoginBlockingSeconds, " seconds",
          " (", LoginBlockingSeconds / 60, " min)."
      )
  | project
      TimeGenerated, UserId, DeviceId,
      PassedAttempts, LoginBlockingSeconds, BlockingMinutes,
      AppVersion, RawEventId, AlertName, AlertDetails
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: UserId
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: DeviceId
customDetails:
  PassedAttempts: PassedAttempts
  BlockingMinutes: BlockingMinutes
  LoginBlockingSeconds: LoginBlockingSeconds
  AppVersion: AppVersion
  EventReference: RawEventId
alertDetailsOverride:
  alertDisplayNameFormat: 'StealthTalk: Password Brute Force - {{UserId}} ({{PassedAttempts}} failed attempts)'
  alertDescriptionFormat: '{{AlertDetails}}'
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: 5h
    matchingMethod: Selected
    groupByEntities:
      - Account
suppressionEnabled: false
suppressionDuration: 5h
version: 1.0.0
kind: Scheduled

Stages and Predicates

Parameters

let LookbackPeriod = 5h;
let MinFailedAttempts = 9;

Stage 1: source

StealthTalkAnomalousAuth_CL

Stage 2: where

| where TimeGenerated >= ago(LookbackPeriod)

Stage 3: where

| where EventType == "MultiFailLogin"

Stage 4: where

| where PassedAttempts >= MinFailedAttempts

Stage 5: extend

| extend
    BlockingMinutes = LoginBlockingSeconds / 60,
    AlertName       = "PasswordBruteForce",
    AlertDetails    = strcat(
        "User ", UserId,
        " had ", PassedAttempts, " consecutive failed login attempts",
        " on device ", DeviceId, ".",
        " Account blocked for ", LoginBlockingSeconds, " seconds",
        " (", LoginBlockingSeconds / 60, " min)."
    )

Stage 6: project

| project
    TimeGenerated, UserId, DeviceId,
    PassedAttempts, LoginBlockingSeconds, BlockingMinutes,
    AppVersion, RawEventId, AlertName, AlertDetails

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
AlertDetailsproject
AlertNameproject
AppVersionproject
BlockingMinutesproject
DeviceIdproject
LoginBlockingSecondsproject
PassedAttemptsproject
RawEventIdproject
TimeGeneratedproject
UserIdproject