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
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
| Sentinel Table | Notes |
|---|---|
CloudAppEvents | Ensure this data connector is enabled |
Scenario: Scheduled Email Archiving Job
Description: A legitimate scheduled job runs daily to archive old emails using Microsoft Graph API. This can cause a high volume of MailItemAccess events.
Filter/Exclusion: Exclude events where the clientID corresponds to a known email archiving service or job (e.g., clientID = 'archive-service-123').
Scenario: User-Driven Email Search via Outlook Web Access (OWA)
Description: A user performs a search across their mailbox using OWA, which triggers multiple MailItemAccess events as the search processes each item.
Filter/Exclusion: Exclude events where the userPrincipalName is associated with a user who has a history of performing large searches (e.g., userPrincipalName LIKE '%search-admin%').
Scenario: Microsoft 365 Compliance Export Job
Description: A compliance export job runs to export mailbox data for legal or audit purposes, resulting in a spike in MailItemAccess events.
Filter/Exclusion: Exclude events where the clientID matches a known compliance export tool (e.g., clientID = 'compliance-export-tool-456').
Scenario: Admin Task: Mailbox Migration via Exchange Online
Description: An admin is migrating mailboxes using Exchange Online PowerShell, which can cause a large number of MailItemAccess events as the migration process reads and processes mail items.
Filter/Exclusion: Exclude events where the userPrincipalName is associated with an admin account (e.g., userPrincipalName LIKE '%admin%') or where the operation field indicates a migration (e.g., operation = 'mailbox-migration').
Scenario: Third-Party Email Integration Tool
Description: