Query Details

04 ADFS Brute Force Single User

Query

id: d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a
name: ADFS Brute Force - Single Account Targeted by Multiple IPs
version: 1.0.0
kind: Scheduled
description: |
  Detects coordinated botnet brute force: many distinct IP addresses directing credential
  errors at a single ADFS user account. More than 20 failures against one account indicates
  a targeted attack, potentially using a distributed botnet to evade per-IP rate limiting.
  Error codes covered: invalid credentials (50126), wrong password (50055/50056/50064),
  locked account (50053), user not found (50034), sign-in blocked (50057),
  and ADFS extranet lockout (396083).
  MITRE ATT&CK: T1110 (Brute Force), T1078 (Valid Accounts)
severity: Medium
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - ADFSSignInLogs
queryFrequency: 4h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CredentialAccess
  - InitialAccess
relevantTechniques:
  - T1110
  - T1078
query: |
  let BruteForceErrors = dynamic(["50126", "50055", "50056", "50064",
                                    "50053", "50034", "50057", "396083"]);
  ADFSSignInLogs
  | where TimeGenerated > ago(1d)
  | extend ErrorCode = tostring(ResultType)
  | where ErrorCode in (BruteForceErrors)
  | summarize
      FailCount  = count(),
      UniqueIPs  = dcount(IPAddress),
      IPs        = make_set(IPAddress, 20),
      Countries  = make_set(Location),
      ErrorCodes = make_set(ErrorCode),
      FirstSeen  = min(TimeGenerated),
      LastSeen   = max(TimeGenerated)
    by UserPrincipalName
  | where FailCount > 20
  | order by FailCount desc
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: UserPrincipalName
customDetails:
  FailCount: FailCount
  UniqueIPs: UniqueIPs
  Countries: Countries
alertDetailsOverride:
  alertDisplayNameFormat: "ADFS Brute Force against {{UserPrincipalName}} - {{FailCount}} failures from {{UniqueIPs}} IPs"
  alertDescriptionFormat: "Account {{UserPrincipalName}} received {{FailCount}} ADFS credential failures from {{UniqueIPs}} unique IPs. Possible coordinated botnet brute force."
  alertSeverityColumnName: ""
  alertTacticsColumnName: ""
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: PT12H
    matchingMethod: AnyAlert
    groupByEntities:
      - Account
    groupByAlertDetails: []
    groupByCustomDetails: []

Explanation

This query is designed to detect potential brute force attacks on Active Directory Federation Services (ADFS) by identifying scenarios where multiple distinct IP addresses are attempting to log into a single user account and failing multiple times. Here's a simplified breakdown:

  1. Purpose: The query aims to identify coordinated brute force attacks, potentially using a botnet, where more than 20 failed login attempts are made against a single ADFS user account from multiple IP addresses within a day.

  2. Error Codes: It looks for specific error codes that indicate failed login attempts, such as invalid credentials, wrong password, locked account, user not found, sign-in blocked, and ADFS extranet lockout.

  3. Data Source: The query uses data from Azure Active Directory's ADFSSignInLogs.

  4. Frequency and Period: It runs every 4 hours and examines data from the past day.

  5. Detection Logic:

    • It filters login attempts from the past day that resulted in specific error codes.
    • It counts the number of failed attempts and the number of unique IP addresses involved for each user account.
    • It collects information about the IP addresses and countries involved.
  6. Alert Criteria: An alert is triggered if there are more than 20 failed login attempts for a single account.

  7. Alert Details: The alert includes the number of failures, the number of unique IPs, and the user account targeted. It suggests a possible coordinated botnet attack.

  8. Incident Management: If an alert is generated, it creates an incident and groups related alerts by the user account to manage them effectively.

Overall, this query helps security teams identify and respond to potential brute force attacks targeting ADFS user accounts by analyzing login failure patterns.

Details

David Alonso profile picture

David Alonso

Released: March 24, 2026

Tables

ADFSSignInLogs

Keywords

ADFSUserAccountIPAddressCredentialErrorAccountAzureActiveDirectory

Operators

letdynamicADFSSignInLogswhereagoextendtostringinsummarizecountdcountmake_setminmaxbyorder bydesc

Actions