Users accessing multiple other users’ mailboxes or folders may indicate lateral movement or data exfiltration by an adversary, such as Nobelium, seeking to escalate privileges or extract sensitive information. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential compromise and mitigate advanced persistent threats.
KQL Query
// Adjust this value to exclude historical activity as known good
let LookBack = 30d;
// Adjust this value to change hunting timeframe
let TimeFrame = 14d;
// Adjust this value to alter how many mailbox (other than their own) a user needs to access before being included in results
let UserThreshold = 1;
// Adjust this value to alter how many mailbox folders in other's email accounts a users needs to access before being included in results.
let FolderThreshold = 5;
let relevantMailItems = materialize (
CloudAppEvents
| where Timestamp > ago(LookBack)
| where ActionType == "MailItemsAccessed"
| where RawEventData['ResultStatus'] == "Succeeded"
| extend UserId = tostring(RawEventData['UserId'])
| extend MailboxOwnerUPN = tostring(RawEventData['MailboxOwnerUPN'])
| where tolower(UserId) != tolower(MailboxOwnerUPN)
| extend Folders = RawEventData['Folders']
| where isnotempty(Folders)
| mv-expand parse_json(Folders)
| extend foldersPath = tostring(Folders.Path)
| where isnotempty(foldersPath)
| extend ClientInfoString = RawEventData['ClientInfoString']
| extend MailBoxGuid = RawEventData['MailboxGuid']
| extend ClientIP = iif(IPAddress startswith "[", extract("\\[([^\\]]*)", 1, IPAddress), IPAddress)
| project Timestamp, ClientIP, UserId, MailboxOwnerUPN, tostring(ClientInfoString), foldersPath, tostring(MailBoxGuid)
);
let relevantMailItemsBaseLine =
relevantMailItems
| where Timestamp between(ago(LookBack) .. ago(TimeFrame))
| distinct MailboxOwnerUPN, UserId;
let relevantMailItemsHunting =
relevantMailItems
| where Timestamp between(ago(TimeFrame) .. now())
| distinct ClientIP, UserId, MailboxOwnerUPN, ClientInfoString, foldersPath, MailBoxGuid;
relevantMailItemsBaseLine
| join kind=rightanti relevantMailItemsHunting
on MailboxOwnerUPN, UserId
| summarize FolderCount = dcount(tostring(foldersPath)),
UserCount = dcount(MailBoxGuid),
foldersPathSet = make_set(foldersPath),
ClientInfoStringSet = make_set(ClientInfoString),
ClientIPSet = make_set(ClientIP),
MailBoxGuidSet = make_set(MailBoxGuid),
MailboxOwnerUPNSet = make_set(MailboxOwnerUPN)
by UserId
| where UserCount > UserThreshold or FolderCount > FolderThreshold
| extend Reason = case(
UserCount > UserThreshold and FolderCount > FolderThreshold, "Both User and Folder Threshold Exceeded",
FolderCount > FolderThreshold and UserCount < UserThreshold, "Folder Count Threshold Exceeded",
"User Threshold Exceeded"
)
| sort by UserCount desc
id: 6a927d9a-66c3-4491-815d-a31d4bbb2948
name: Anomaly of MailItemAccess by Other Users Mailbox [Nobelium]
description: |
This query looks for users accessing multiple other users' mailboxes, or accessing multiple folders in another user's mailbox.
This query is inspired by an Azure Sentinel detection.
Reference - https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/OfficeActivity/AnomolousUserAccessingOtherUsersMailbox.yaml
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- CloudAppEvents
tactics:
- Collection
tags:
- Nobelium
query: |
// Adjust this value to exclude historical activity as known good
let LookBack = 30d;
// Adjust this value to change hunting timeframe
let TimeFrame = 14d;
// Adjust this value to alter how many mailbox (other than their own) a user needs to access before being included in results
let UserThreshold = 1;
// Adjust this value to alter how many mailbox folders in other's email accounts a users needs to access before being included in results.
let FolderThreshold = 5;
let relevantMailItems = materialize (
CloudAppEvents
| where Timestamp > ago(LookBack)
| where ActionType == "MailItemsAccessed"
| where RawEventData['ResultStatus'] == "Succeeded"
| extend UserId = tostring(RawEventData['UserId'])
| extend MailboxOwnerUPN = tostring(RawEventData['MailboxOwnerUPN'])
| where tolower(UserId) != tolower(MailboxOwnerUPN)
| extend Folders = RawEventData['Folders']
| where isnotempty(Folders)
| mv-expand parse_json(Folders)
| extend foldersPath = tostring(Folders.Path)
| where isnotempty(foldersPath)
| extend ClientInfoString = RawEventData['ClientInfoString']
| extend MailBoxGuid = RawEventData['MailboxGuid']
| extend ClientIP = iif(IPAddress startswith "[", extract("\\[([^\\]]*)", 1, IPAddress), IPAddress)
| project Timestamp, ClientIP, UserId, MailboxOwnerUPN, tostring(ClientInfoString), foldersPath, tostring(MailBoxGuid)
);
let relevantMailItemsBaseLine =
relevantMailItems
| where Timestamp between(ago(LookBack) .. ago(TimeFrame))
| distinct MailboxOwnerUPN, UserId;
let relevantMailItemsHunting =
relevantMailItems
| where Timestamp between(ago(TimeFrame) .. now())
| distinct ClientIP, UserId, MailboxOwnerUPN, ClientInfoString, foldersPath, MailBoxGuid;
relevantMailItemsBaseLine
| join kind=rightanti relevantMailItemsHunting
on MailboxOwnerUPN, UserId
| summarize FolderCount = dcount(tostring(foldersPath)),
UserCount = dcount(MailBoxGuid),
foldersPathSet = make_set(foldersPath),
ClientInfoStringSet = make_set(ClientInfoString),
ClientIPSet = make_set(ClientIP),
MailBoxGuidSet = make_set(MailBoxGuid),
MailboxOwnerUPNSet = make_set(MailboxOwnerUPN)
by UserId
| Sentinel Table | Notes |
|---|---|
CloudAppEvents | Ensure this data connector is enabled |
Scenario: Systematic mailbox backups via scheduled job
Description: A scheduled job (e.g., Microsoft Exchange Online’s Mailbox Backup Job) is configured to access multiple mailboxes for archival purposes.
Filter/Exclusion: Exclude activity from known backup processes using the activity field with value Backup or filter by job name like BackupJob-Exchange.
Scenario: Admin task to review user mailbox access
Description: An administrator is performing a routine audit and accesses multiple user mailboxes to review access logs or investigate a security incident.
Filter/Exclusion: Exclude activity from admin accounts (e.g., [email protected]) or filter by user role such as Admin or SecurityAdmin.
Scenario: Automated folder synchronization between mailboxes
Description: A third-party tool like Microsoft 365 Sync Tool or Exchange Online Migration Wizard is synchronizing folders between user mailboxes.
Filter/Exclusion: Exclude activity from known synchronization tools using the tool field or filter by process name like SyncTool.exe or MigrationWizard.exe.
Scenario: User accessing shared folders in multiple mailboxes
Description: A user with access to shared folders (e.g., via Microsoft Teams or SharePoint) is accessing multiple shared folders across different mailboxes.
Filter/Exclusion: Exclude access to shared folders using the folderPath field with keywords like /Shared Documents/ or filter by folder type such as Shared.
Scenario: Email forwarding or distribution list activity
Description: A user is forwarding emails or sending to a distribution list, which results in access to multiple mailboxes through the email flow.
Filter/Exclusion: Exclude activity related to distribution lists using the to