Query Details

HQ 008 O Auth Sensitive Scope Permission Grant

Query

// =========================================================================
// HQ-008: Delegated Permission Grant Including Sensitive API Scopes
// =========================================================================
// Description : Consent events that include high-privilege delegated scopes
//               (Mail.Read, Directory.ReadWrite.All, offline_access, etc.)
//               are a primary indicator of OAuth phishing attacks (Device
//               Code flow abuse via TokenTactics, consent-phishing via
//               AADInternals). The offline_access scope is especially
//               dangerous as it allows long-lived refresh tokens.
// MITRE ATT&CK: TA0006 Credential Access
//               T1528 – Steal Application Access Token
// Tools       : TokenTactics, ROADtools, AADInternals (Device Code flow)
// Severity    : High
// Data Source : AuditLogs (Azure Active Directory)
// =========================================================================

let SensitiveScopes = dynamic([
    "Mail.Read", "Mail.ReadWrite", "Mail.Send",
    "Files.ReadWrite.All", "Directory.ReadWrite.All",
    "User.ReadWrite.All", "RoleManagement.ReadWrite.Directory",
    "Application.ReadWrite.All", "Sites.FullControl.All",
    "EWS.AccessAsUser.All", "IMAP.AccessAsUser.All",
    "POP.AccessAsUser.All", "SMTP.Send",
    "ChannelMessage.Read.All", "TeamSettings.ReadWrite.All",
    "offline_access"
]);

AuditLogs
| where TimeGenerated > ago(7d)
| where ActivityDisplayName in (
    "Add delegated permission grant",
    "Consent to application")
| extend InitiatedByUPN  = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatedByApp  = tostring(InitiatedBy.app.displayName)
| extend Actor           = iff(isnotempty(InitiatedByUPN), InitiatedByUPN, InitiatedByApp)
| extend TargetApp       = tostring(TargetResources[0].displayName)
| extend TargetAppId     = tostring(TargetResources[0].id)
| extend PermDetailRaw   = tostring(AdditionalDetails)
// Match any sensitive scope in the AdditionalDetails blob
| where PermDetailRaw has_any (SensitiveScopes)
| extend MatchedScopes = extract_all(
    @"(Mail\.[^\s,""]+|Directory\.[^\s,""]+|offline_access|Application\.[^\s,""]+|Files\.[^\s,""]+|User\.ReadWrite\.All|RoleManagement\.[^\s,""]+|Sites\.[^\s,""]+|EWS\.[^\s,""]+|IMAP\.[^\s,""]+|SMTP\.[^\s,""]+|Channel[^\s,""]+|Team[^\s,""]+)",
    PermDetailRaw)
| project
    TimeGenerated,
    Actor,
    TargetApp,
    TargetAppId,
    MatchedScopes,
    ActivityDisplayName,
    LoggedByService,
    Result,
    CorrelationId
| order by TimeGenerated desc

Explanation

This KQL query is designed to identify and analyze potentially risky consent events in Azure Active Directory audit logs. Here's a simplified breakdown of what the query does:

  1. Purpose: The query aims to detect consent events where high-privilege delegated permissions are granted. These permissions include access to sensitive data or capabilities, such as reading emails, accessing directories, and offline access, which could be exploited in OAuth phishing attacks.

  2. Sensitive Scopes: A list of sensitive permission scopes is defined, including permissions like Mail.Read, Directory.ReadWrite.All, and offline_access. These scopes are considered high-risk because they provide significant access to resources.

  3. Data Source: The query examines audit logs from Azure Active Directory, specifically looking at events from the past 7 days.

  4. Event Filtering: It filters for events where delegated permissions were added or consent was given to an application. These events are identified by specific activity names like "Add delegated permission grant" and "Consent to application".

  5. Data Extraction: The query extracts details about who initiated the event (either a user or an application), the target application involved, and the raw permission details.

  6. Scope Matching: It checks if any of the sensitive scopes are present in the permission details. If a match is found, those scopes are extracted and listed.

  7. Output: The query projects relevant information such as the time of the event, the actor (user or app) who initiated it, the target application, matched sensitive scopes, and other event details. The results are sorted by the time the event occurred, in descending order.

Overall, this query helps security analysts identify potentially malicious consent events that could indicate phishing attacks or unauthorized access attempts.

Details

David Alonso profile picture

David Alonso

Released: April 6, 2026

Tables

AuditLogs

Keywords

AuditLogsAzureActiveDirectoryMailDirectoryUserApplicationSitesEWSIMAPSMTPChannelTeamRoleManagementFiles

Operators

letdynamicinextendtostringiffisnotemptyhas_anyextract_allprojectorder bydesc

Actions