Suspicious Email Access by First-Party Application via Microsoft Graph

Identifies access to email resources via Microsoft Graph API using an first-party application on behalf of a user principal. This behavior may indicate an adversary using a phished OAuth refresh token or a Primary Refresh Token (PRT) to access email resources. The pattern includes requests to Microsoft Graph API endpoints related to email, such as /me/mailFolders/inbox/messages or /users/{user_id}/messages, using a public client application ID and a user principal object ID. This is a New Terms rule that only signals if the application ID and user principal object ID have not been seen doing this activity in the last 14 days.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2025/05/06"
  3integration = ["azure"]
  4maturity = "production"
  5updated_date = "2025/05/06"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies access to email resources via Microsoft Graph API using an first-party application on behalf of a user
 11principal. This behavior may indicate an adversary using a phished OAuth refresh token or a Primary Refresh Token (PRT)
 12to access email resources. The pattern includes requests to Microsoft Graph API endpoints related to email, such as
 13/me/mailFolders/inbox/messages or /users/{user_id}/messages, using a public client application ID and a user principal
 14object ID. This is a New Terms rule that only signals if the application ID and user principal object ID have not been
 15seen doing this activity in the last 14 days.
 16"""
 17from = "now-9m"
 18index = ["filebeat-*", "logs-azure.graphactivitylogs-*"]
 19language = "kuery"
 20license = "Elastic License v2"
 21name = "Suspicious Email Access by First-Party Application via Microsoft Graph"
 22note = """## Triage and analysis
 23
 24### Investigating Suspicious Email Access by First-Party Application via Microsoft Graph
 25
 26This rule detects instances where a previously unseen or rare Microsoft Graph application client ID accesses email-related APIs, such as `/me/messages`, `/sendMail`, or `/mailFolders/inbox/messages`. These accesses are performed via delegated user credentials using common OAuth scopes like `Mail.Read`, `Mail.ReadWrite`, `Mail.Send`, or `email`. This activity may indicate unauthorized use of a newly consented or compromised application to read or exfiltrate mail content. This is a New Terms rule that only signals if the application ID (`azure.graphactivitylogs.properties.app_id`) and user principal object ID (`azure.graphactivitylogs.properties.user_principal_object_id`) have not been seen doing this activity in the last 14 days.
 27
 28### Possible Investigation Steps:
 29
 30- `azure.graphactivitylogs.properties.app_id`: Investigate the application ID involved. Is it known and sanctioned in your tenant? Pivot to Azure Portal → Enterprise Applications → Search by App ID to determine app details, publisher, and consent status.
 31- `azure.graphactivitylogs.properties.scopes`: Review the scopes requested by the application. Email-related scopes such as `Mail.ReadWrite` and `Mail.Send` are especially sensitive and suggest the app is interacting with mail content.
 32- `url.path` / `azure.graphactivitylogs.properties.requestUri`: Determine exactly which mail-related APIs were accessed (e.g., reading inbox, sending messages, enumerating folders).
 33- `user.id`: Identify the user whose credentials were used. Determine if the user recently consented to a new app, clicked a phishing link, or reported suspicious activity.
 34- `user_agent.original`: Check for suspicious automation tools (e.g., `python-requests`, `curl`, non-browser agents), which may suggest scripted access.
 35- `source.ip` and `client.geo`: Investigate the source IP and geography. Look for unusual access from unexpected countries, VPS providers, or anonymizing services.
 36- `http.request.method`: Determine intent based on HTTP method — `GET` (reading), `POST` (sending), `PATCH`/`DELETE` (modifying/removing messages).
 37- `token_issued_at` and `@timestamp`: Determine how long the token has been active and whether access is ongoing or recent.
 38- `azure.graphactivitylogs.properties.c_sid`: Use the session correlation ID to identify other related activity in the same session. This may help identify if the app is accessing multiple users' mailboxes or if the same user is accessing multiple apps.
 39- Correlate with Microsoft Entra ID (`azure.auditlogs` and `azure.signinlogs`) to determine whether:
 40  - The app was recently granted admin or user consent
 41  - Risky sign-ins occurred just prior to or after mail access
 42  - The same IP or app ID appears across multiple users
 43
 44### False Positive Analysis
 45
 46- New legitimate apps may appear after a user consents via OAuth. Developers, third-party tools, or IT-supplied utilities may access mail APIs if users consent.
 47- Users leveraging Microsoft development environments (e.g., Visual Studio Code) may trigger this behavior with delegated `.default` permissions.
 48- Admin-approved apps deployed via conditional access may trigger similar access logs if not previously seen in detection baselines.
 49
 50### Response and Remediation
 51
 52- If access is unauthorized or unexpected:
 53  - Revoke the app's consent in Azure AD via the Enterprise Applications blade.
 54  - Revoke user refresh tokens via Microsoft Entra or PowerShell.
 55  - Investigate the user's session and alert them to possible phishing or OAuth consent abuse.
 56- Review and restrict risky OAuth permissions in Conditional Access and App Governance policies.
 57- Add known, trusted app IDs to a detection allowlist to reduce noise in the future.
 58- Continue monitoring the app ID for additional usage across the tenant or from suspicious IPs.
 59"""
 60references = [
 61    "https://www.volexity.com/blog/2025/04/22/phishing-for-codes-russian-threat-actors-target-microsoft-365-oauth-workflows/",
 62    "https://github.com/dirkjanm/ROADtools",
 63    "https://dirkjanm.io/phishing-for-microsoft-entra-primary-refresh-tokens/",
 64]
 65risk_score = 47
 66rule_id = "e882e934-2aaa-11f0-8272-f661ea17fbcc"
 67severity = "medium"
 68tags = [
 69    "Domain: Cloud",
 70    "Data Source: Azure",
 71    "Data Source: Microsoft Graph",
 72    "Data Source: Microsoft Graph Activity Logs",
 73    "Use Case: Threat Detection",
 74    "Tactic: Collection",
 75    "Resources: Investigation Guide",
 76]
 77timestamp_override = "event.ingested"
 78type = "new_terms"
 79
 80query = '''
 81event.dataset: "azure.graphactivitylogs" and
 82azure.graphactivitylogs.properties.app_id: * and
 83azure.graphactivitylogs.result_signature: 200 and
 84azure.graphactivitylogs.properties.c_idtyp: "user" and
 85azure.graphactivitylogs.properties.client_auth_method: 0 and
 86http.request.method: (GET or POST or PUT or PATCH or DELETE) and (
 87  url.path: (/v1.0/me/*cc or /v1.0/users/*) and
 88  (
 89    url.path: (*mail* or *messages* or *inbox*) or
 90    azure.graphactivitylogs.properties.requestUri: (*mail* or *messages* or *inbox*)
 91  ) or
 92  azure.graphactivitylogs.properties.scopes: (
 93    "Mail.Read" or "Mail.ReadWrite" or "Mail.Send" or "email"
 94  )
 95)
 96'''
 97
 98
 99[[rule.threat]]
100framework = "MITRE ATT&CK"
101[[rule.threat.technique]]
102id = "T1114"
103name = "Email Collection"
104reference = "https://attack.mitre.org/techniques/T1114/"
105
106
107[rule.threat.tactic]
108id = "TA0009"
109name = "Collection"
110reference = "https://attack.mitre.org/tactics/TA0009/"
111
112[rule.new_terms]
113field = "new_terms_fields"
114value = [
115    "azure.graphactivitylogs.properties.app_id",
116    "azure.graphactivitylogs.properties.user_principal_object_id",
117]
118[[rule.new_terms.history_window_start]]
119field = "history_window_start"
120value = "now-14d"

Triage and analysis

Investigating Suspicious Email Access by First-Party Application via Microsoft Graph

This rule detects instances where a previously unseen or rare Microsoft Graph application client ID accesses email-related APIs, such as /me/messages, /sendMail, or /mailFolders/inbox/messages. These accesses are performed via delegated user credentials using common OAuth scopes like Mail.Read, Mail.ReadWrite, Mail.Send, or email. This activity may indicate unauthorized use of a newly consented or compromised application to read or exfiltrate mail content. This is a New Terms rule that only signals if the application ID (azure.graphactivitylogs.properties.app_id) and user principal object ID (azure.graphactivitylogs.properties.user_principal_object_id) have not been seen doing this activity in the last 14 days.

Possible Investigation Steps:

  • azure.graphactivitylogs.properties.app_id: Investigate the application ID involved. Is it known and sanctioned in your tenant? Pivot to Azure Portal → Enterprise Applications → Search by App ID to determine app details, publisher, and consent status.
  • azure.graphactivitylogs.properties.scopes: Review the scopes requested by the application. Email-related scopes such as Mail.ReadWrite and Mail.Send are especially sensitive and suggest the app is interacting with mail content.
  • url.path / azure.graphactivitylogs.properties.requestUri: Determine exactly which mail-related APIs were accessed (e.g., reading inbox, sending messages, enumerating folders).
  • user.id: Identify the user whose credentials were used. Determine if the user recently consented to a new app, clicked a phishing link, or reported suspicious activity.
  • user_agent.original: Check for suspicious automation tools (e.g., python-requests, curl, non-browser agents), which may suggest scripted access.
  • source.ip and client.geo: Investigate the source IP and geography. Look for unusual access from unexpected countries, VPS providers, or anonymizing services.
  • http.request.method: Determine intent based on HTTP method — GET (reading), POST (sending), PATCH/DELETE (modifying/removing messages).
  • token_issued_at and @timestamp: Determine how long the token has been active and whether access is ongoing or recent.
  • azure.graphactivitylogs.properties.c_sid: Use the session correlation ID to identify other related activity in the same session. This may help identify if the app is accessing multiple users' mailboxes or if the same user is accessing multiple apps.
  • Correlate with Microsoft Entra ID (azure.auditlogs and azure.signinlogs) to determine whether:
    • The app was recently granted admin or user consent
    • Risky sign-ins occurred just prior to or after mail access
    • The same IP or app ID appears across multiple users

False Positive Analysis

  • New legitimate apps may appear after a user consents via OAuth. Developers, third-party tools, or IT-supplied utilities may access mail APIs if users consent.
  • Users leveraging Microsoft development environments (e.g., Visual Studio Code) may trigger this behavior with delegated .default permissions.
  • Admin-approved apps deployed via conditional access may trigger similar access logs if not previously seen in detection baselines.

Response and Remediation

  • If access is unauthorized or unexpected:
    • Revoke the app's consent in Azure AD via the Enterprise Applications blade.
    • Revoke user refresh tokens via Microsoft Entra or PowerShell.
    • Investigate the user's session and alert them to possible phishing or OAuth consent abuse.
  • Review and restrict risky OAuth permissions in Conditional Access and App Governance policies.
  • Add known, trusted app IDs to a detection allowlist to reduce noise in the future.
  • Continue monitoring the app ID for additional usage across the tenant or from suspicious IPs.

References

Related rules

to-top