Detect Additional Email Delegate Permissions in Microsoft Sentinel
Adversaries may grant additional permission levels to maintain persistent access to an adversary-controlled email account. Using cmdlets like Add-MailboxPermission in Exchange/Office 365, or assigning folder-level permissions, attackers can ensure continued access to target mailboxes. This technique is commonly used in BEC incidents and persistent threat campaigns (APT28, APT29, Magic Hound) to maintain covert email access, enable internal spearphishing, and evade detection by reading communications without triggering login alerts.
MITRE ATT&CK
- Tactic
- Persistence Privilege Escalation
- Technique
- T1098 Account Manipulation
- Sub-technique
- T1098.002 Additional Email Delegate Permissions
- Canonical reference
- https://attack.mitre.org/techniques/T1098/002/
KQL Detection Query
// T1098.002 — Additional Email Delegate Permissions
// Detects mailbox permission grants, folder permission changes, and ApplicationImpersonation role assignments
// Sources: OfficeActivity (Unified Audit Log) and AuditLogs (AAD)
let SuspiciousMailboxOps = dynamic([
"Add-MailboxPermission",
"Add-MailboxFolderPermission",
"Set-MailboxFolderPermission",
"Add-RecipientPermission",
"Set-Mailbox",
"New-ManagementRoleAssignment"
]);
let SuspiciousAccessRights = dynamic([
"FullAccess",
"SendAs",
"SendOnBehalf",
"ApplicationImpersonation",
"ChangePermission",
"ChangeOwner"
]);
let SuspiciousFolderPerms = dynamic([
"Owner",
"PublishingEditor",
"Editor",
"Reviewer"
]);
// Branch 1: OfficeActivity — Exchange Admin Audit Log and Mailbox Audit
let OfficeActivityAlerts = OfficeActivity
| where TimeGenerated > ago(24h)
| where RecordType in ("ExchangeAdmin", "ExchangeItemGroup", "ExchangeItem")
| where Operation has_any (SuspiciousMailboxOps)
| extend Parameters_s = tostring(Parameters)
| extend TargetUser = coalesce(
tostring(parse_json(Parameters_s)[0].Value),
UserId
)
| extend AccessRights = extract(@'AccessRights[^\]]*\[([^\]]+)\]|AccessRights":\s*"([^"]+)"', 1, Parameters_s)
| extend GrantedTo = extract(@'User":\s*"([^"]+)"', 1, Parameters_s)
| extend IsSuspiciousRight = AccessRights has_any (SuspiciousAccessRights) or Parameters_s has_any (SuspiciousAccessRights)
| extend IsFolderPermChange = Operation in ("Add-MailboxFolderPermission", "Set-MailboxFolderPermission")
| extend IsDefaultAnonymous = Parameters_s has "Default" or Parameters_s has "Anonymous"
| project
TimeGenerated,
Operation,
UserId,
TargetUser,
GrantedTo,
AccessRights,
IsSuspiciousRight,
IsFolderPermChange,
IsDefaultAnonymous,
ClientIP,
Parameters_s,
RecordType,
OfficeObjectId
| extend AlertSource = "OfficeActivity";
// Branch 2: AuditLogs — Azure AD role assignments (ApplicationImpersonation)
let AADAuditAlerts = AuditLogs
| where TimeGenerated > ago(24h)
| where OperationName in ("Add app role assignment to service principal", "Add delegated permission grant", "Add member to role", "Update application")
| extend InitiatedByUser = tostring(InitiatedBy.user.userPrincipalName)
| extend InitiatedByApp = tostring(InitiatedBy.app.displayName)
| extend TargetResource = tostring(TargetResources[0].displayName)
| extend ModifiedProps = tostring(TargetResources[0].modifiedProperties)
| extend IsImpersonation = ModifiedProps has "ApplicationImpersonation" or ModifiedProps has "Exchange.ManageAsApp"
| where IsImpersonation
| project
TimeGenerated,
OperationName,
InitiatedByUser,
InitiatedByApp,
TargetResource,
ModifiedProps,
IsImpersonation,
CorrelationId,
Result
| extend AlertSource = "AuditLogs";
// Combine results
OfficeActivityAlerts
| union (AADAuditAlerts
| project TimeGenerated,
Operation = OperationName,
UserId = InitiatedByUser,
TargetUser = TargetResource,
GrantedTo = "",
AccessRights = "ApplicationImpersonation",
IsSuspiciousRight = true,
IsFolderPermChange = false,
IsDefaultAnonymous = false,
ClientIP = "",
Parameters_s = ModifiedProps,
RecordType = "AADAudit",
OfficeObjectId = "",
AlertSource
)
| sort by TimeGenerated desc Detects mailbox delegation and permission changes in Office 365 and Azure AD that are consistent with adversary persistence (T1098.002). Covers Exchange admin operations (Add-MailboxPermission, Add-MailboxFolderPermission, Add-RecipientPermission, New-ManagementRoleAssignment), suspicious access rights (FullAccess, SendAs, ApplicationImpersonation), and Azure AD role assignments granting exchange impersonation. Also flags Default/Anonymous user permission grants to mailbox folders, a technique used by APT29/UNC2452 to maintain persistent folder-level access.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate IT helpdesk or mail administrators adding shared mailbox permissions for business continuity (e.g., shared support mailboxes, executive assistants)
- Automated provisioning systems (ServiceNow, Azure AD connectors) that programmatically grant SendAs or FullAccess to distribution groups
- Office 365 migration tools (Exchange Hybrid, third-party tools) that assign ApplicationImpersonation during mailbox migrations
- Legitimate delegation by end users granting calendar or inbox access to assistants via Outlook settings
- Security monitoring tools or compliance archiving solutions that require FullAccess or ApplicationImpersonation to index mailbox content
Other platforms for T1098.002
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Grant FullAccess Mailbox Permission via PowerShell
Expected signal: Office 365 Unified Audit Log: Operation='Add-MailboxPermission', RecordType='ExchangeAdmin', UserId=<admin UPN>, [email protected], Parameters containing 'FullAccess' and '[email protected]'. PowerShell Event ID 4104 (ScriptBlock) if logging is enabled on the workstation running the cmdlet.
- Test 2Grant ApplicationImpersonation Role for Tenant-Wide Mailbox Access
Expected signal: Office 365 Unified Audit Log: Operation='New-ManagementRoleAssignment', RecordType='ExchangeAdmin', Parameters containing 'ApplicationImpersonation' and '[email protected]'. Azure AD Audit Logs may also show a role assignment event. PowerShell ScriptBlock Log (Event ID 4104) captures the New-ManagementRoleAssignment cmdlet with parameters.
- Test 3Set Default User Reviewer Permission on Mailbox Inbox Folder
Expected signal: Office 365 Unified Audit Log: Operation='Set-MailboxFolderPermission' and 'Add-MailboxFolderPermission', Parameters containing 'Default' and 'Reviewer'. Two separate audit events expected — one for Inbox and one for root folder. RecordType='ExchangeAdmin'.
- Test 4Grant SendAs Permission to Attacker Account for BEC
Expected signal: Office 365 Unified Audit Log: Operation='Add-RecipientPermission', RecordType='ExchangeAdmin', [email protected], Parameters containing 'SendAs' and '[email protected]'. ClientIP of the admin session performing the grant.
References (10)
- https://attack.mitre.org/techniques/T1098/002/
- https://docs.microsoft.com/en-us/powershell/module/exchange/mailboxes/add-mailboxpermission
- https://www.mandiant.com/resources/blog/remediation-and-hardening-strategies-for-microsoft-365-to-defend-against-unc2452
- https://www.crowdstrike.com/blog/hiding-in-plain-sight-using-the-office-365-activities-api-to-investigate-business-email-compromises/
- https://static.carahsoft.com/concrete/files/1015/2779/3571/M-Trends-2018-Report.pdf
- https://www.slideshare.net/slideshow/shmoocon-2019-becs-and-beyond-investigating-and-defending-office-365/128744511
- https://support.google.com/a/answer/7223765?hl=en
- https://learn.microsoft.com/en-us/microsoft-365/compliance/mailbox-audit-logging
- https://learn.microsoft.com/en-us/exchange/permissions/role-assignments
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1098.002/T1098.002.md
Unlock Pro Content
Get the full detection package for T1098.002 including response playbook, investigation guide, and atomic red team tests.