← Back to SOC feed Coverage →

Anomaly of MailItemAccess by GraphAPI [Nobelium]

kql MEDIUM Azure-Sentinel
CloudAppEvents
huntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-05-21T11:00:00Z · Confidence: medium

Hunt Hypothesis

The hypothesis is that the anomaly in MailItemAccess events via GraphAPI could indicate unauthorized or automated access to email data, potentially linked to adversary reconnaissance or data exfiltration. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential compromises and mitigate lateral movement or data theft by adversaries like Nobelium.

KQL Query

let starttime = 30d;
let STDThreshold = 2.5;
let allMailAccsessByGraphAPI = CloudAppEvents
| where   ActionType == "MailItemsAccessed"
| where Timestamp between (startofday(ago(starttime))..now())
| where isnotempty(RawEventData['ClientAppId'] ) and RawEventData['AppId'] has "00000003-0000-0000-c000-000000000000"
| extend ClientAppId = tostring(RawEventData['ClientAppId'])
| extend OperationCount = toint(RawEventData['OperationCount'])
| project Timestamp,OperationCount , ClientAppId;
let calculateNumberOfMailPerDay = allMailAccsessByGraphAPI
| summarize NumberOfMailPerDay =sum(toint(OperationCount)) by ClientAppId,format_datetime(Timestamp, 'y-M-d');
let calculteAvgAndStdev=calculateNumberOfMailPerDay
| summarize avg=avg(NumberOfMailPerDay),stev=stdev(NumberOfMailPerDay) by ClientAppId;
calculteAvgAndStdev  | join calculateNumberOfMailPerDay on ClientAppId
| sort by ClientAppId
|  where NumberOfMailPerDay > avg + STDThreshold * stev
| project ClientAppId,Timestamp,NumberOfMailPerDay,avg,stev 

Analytic Rule Definition

id: 5cb88a85-f9d9-48eb-a23a-55960f0f8ad4
name: Anomaly of MailItemAccess by GraphAPI [Nobelium]
description: |
  This query looks for anomalies in mail item access events made by Graph API. It uses standard deviation to determine if the number of events is anomalous. The query returns all clientIDs where the amount of mail sent per day was larger than value given by the formula, 'average + STDThreshold(2.5)*(standard deviation)'.
  See The MailItemsAccessed mailbox auditing action.
  Reference - https://docs.microsoft.com/microsoft-365/compliance/mailitemsaccessed-forensics-investigations?view=o365-worldwide#the-mailitemsaccessed-mailbox-auditing-action
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - CloudAppEvents
tactics:
- Exfiltration
tags:
- Nobelium
query: |
  let starttime = 30d;
  let STDThreshold = 2.5;
  let allMailAccsessByGraphAPI = CloudAppEvents
  | where   ActionType == "MailItemsAccessed"
  | where Timestamp between (startofday(ago(starttime))..now())
  | where isnotempty(RawEventData['ClientAppId'] ) and RawEventData['AppId'] has "00000003-0000-0000-c000-000000000000"
  | extend ClientAppId = tostring(RawEventData['ClientAppId'])
  | extend OperationCount = toint(RawEventData['OperationCount'])
  | project Timestamp,OperationCount , ClientAppId;
  let calculateNumberOfMailPerDay = allMailAccsessByGraphAPI
  | summarize NumberOfMailPerDay =sum(toint(OperationCount)) by ClientAppId,format_datetime(Timestamp, 'y-M-d');
  let calculteAvgAndStdev=calculateNumberOfMailPerDay
  | summarize avg=avg(NumberOfMailPerDay),stev=stdev(NumberOfMailPerDay) by ClientAppId;
  calculteAvgAndStdev  | join calculateNumberOfMailPerDay on ClientAppId
  | sort by ClientAppId
  |  where NumberOfMailPerDay > avg + STDThreshold * stev
  | project ClientAppId,Timestamp,NumberOfMailPerDay,avg,stev 

Required Data Sources

Sentinel TableNotes
CloudAppEventsEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/Microsoft 365 Defender/Exfiltration/Anomaly of MailItemAccess by GraphAPI [Nobelium].yaml