Query Details

06 ROPC Authentication Detected

Query

id: f1a7b9c0-d5e6-8f2a-3b4c-5d6e7f8a9b0c
name: ROPC Authentication Detected - Credential Pass-Through Bypass
version: 1.1.0
kind: Scheduled
description: |
  Detects successful Resource Owner Password Credential (ROPC) grant flow in non-interactive
  sign-ins. ROPC passes user credentials directly to Entra ID, completely bypassing MFA,
  Conditional Access policies, and any security controls. This grant type should NEVER appear
  in a healthy enterprise tenant. Its presence indicates either a misconfigured legacy app or
  an attacker using stolen credentials via command-line tooling.

  Tuning:
    - Only successful ROPC (ResultType == 0). Failures are covered by rule 24 (ROPC-CredentialStuffing).
    - AppDisplayName allowlist excludes documented legitimate ROPC clients
      (Microsoft Authentication Broker, Intune Company Portal, etc.). Edit LegitRopcApps to extend.
    - UserPrincipalName allowlist (LegitRopcUsers) for sanctioned sync / service accounts.
    - Allowlist IPs are stripped via ExcludeAllowlistedIPs_AADNI() (NetworkAllowlist watchlist).

  MITRE ATT&CK: T1110 (Brute Force), T1078 (Valid Accounts), T1550 (Use Alternate Auth Material)
severity: High
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AADNonInteractiveUserSignInLogs
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CredentialAccess
  - DefenseEvasion
  - InitialAccess
relevantTechniques:
  - T1110
  - T1078
  - T1550
query: |
  let LegitRopcApps = dynamic([
      "Microsoft Authentication Broker",
      "Microsoft Intune Company Portal",
      "Azure AD Connect",
      "Microsoft Office",
      "Microsoft Office Authentication Broker"
  ]);
  let LegitRopcUsers = dynamic([]);
  AADNonInteractiveUserSignInLogs
  | invoke ExcludeAllowlistedIPs_AADNI()
  | where TimeGenerated > ago(1h)
  | where AuthenticationProtocol =~ "ropc"
  | where ResultType == 0
  | where AppDisplayName !in~ (LegitRopcApps)
  | where tolower(UserPrincipalName) !in~ (LegitRopcUsers)
  | summarize
      Count     = count(),
      IPs       = make_set(IPAddress),
      Countries = make_set(Location),
      Apps      = make_set(AppDisplayName),
      FirstSeen = min(TimeGenerated),
      LastSeen  = max(TimeGenerated)
    by UserPrincipalName
  | extend IPAddress = tostring(IPs[0])
  | order by Count desc
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: UserPrincipalName
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPAddress
customDetails:
  SignInCount: Count
  Countries: Countries
  Apps: Apps
alertDetailsOverride:
  alertDisplayNameFormat: "ROPC Authentication Detected for {{UserPrincipalName}} - MFA Bypass Risk"
  alertDescriptionFormat: "Successful ROPC authentication for {{UserPrincipalName}} ({{Count}} sign-ins from {{Countries}}). ROPC bypasses MFA and Conditional Access. Verify if this is an authorised legacy app or investigate for credential stuffing."
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: PT5H
    matchingMethod: AnyAlert
    groupByEntities:
      - Account
    groupByAlertDetails: []
    groupByCustomDetails: []

Explanation

This query is designed to detect suspicious use of the Resource Owner Password Credential (ROPC) grant flow in non-interactive sign-ins within an organization's Azure Active Directory (AAD). Here's a simplified breakdown:

  1. Purpose: The query identifies instances where user credentials are passed directly to AAD, bypassing Multi-Factor Authentication (MFA) and other security controls. This behavior is unusual and could indicate a misconfigured application or an attacker using stolen credentials.

  2. Detection Criteria:

    • It looks for successful ROPC authentications (ResultType == 0).
    • It excludes known legitimate applications and users from the analysis using predefined allowlists (LegitRopcApps and LegitRopcUsers).
    • It filters out IP addresses that are on a predefined allowlist.
  3. Data Source: The query uses logs from AADNonInteractiveUserSignInLogs.

  4. Output:

    • It summarizes the data by counting occurrences, listing IP addresses, countries, and applications involved, and noting the first and last time the activity was seen.
    • Results are ordered by the number of occurrences.
  5. Alerting:

    • If any suspicious activity is detected, an alert is generated with details about the user, number of sign-ins, and countries involved.
    • The alert suggests verifying whether the activity is from an authorized legacy app or if it requires investigation for potential credential stuffing.
  6. Severity and Response:

    • The severity of this detection is marked as high.
    • An incident is created for each detection, and similar alerts are grouped together for easier management.

Overall, this query helps security teams identify and respond to potential security risks associated with improper use of ROPC authentication in their environment.

Details

David Alonso profile picture

David Alonso

Released: May 29, 2026

Tables

AADNonInteractiveUserSignInLogs

Keywords

AzureActiveDirectoryAADNonInteractiveUserSignInLogsUserPrincipalNameIPAddressAppDisplayNameTimeGeneratedLocation

Operators

letdynamicinvokewhere=~==!in~tolowersummarizecountmake_setminmaxbyextendtostringorder by

Actions