Interpreting the Office 365 MailItemsAccessed Audit Event

Crucial Office 365 Forensics Events

The MailItemsAccessed event is the first crucial (sometimes called high-value) audit event introduced as part of Microsoft 365 Advanced Audit (or auditing). Its introduction was neither smooth nor uncomplicated and contributed to some of the issues around Exchange Online mailbox auditing experienced over the last year. MailItemsAccessed audit events are now showing in tenants, and I wanted to find out how useful these events are when investigating compromised accounts.

E5 Licenses Needed

The MailItemsAccessed event is generated when licensed users access items in Exchange Online mailboxes using any connectivity protocol from any client, but only if your account has an Office 365 E5 or Microsoft 365 E5 Compliance add-on. In my case, I have an Office 365 E5 license, and Advanced Auditing shows up as one of the apps in the plan (Figure 1). After capture, events are uploaded by Exchange Online to the Office 365 audit log along with other mailbox audit events.

Image 1 Expand
Advanced Auditing License
Figure 1: Microsoft 365 Advanced Auditing is part of Office 365 E5 (image credit: Tony Redmond)

Two Kinds of MailItemsAccessed Event

MailItemsAccessed events come in two kinds: Sync (synchronization) and Bind (access to a message).

Sync events are captured when an Outlook desktop client synchronizes messages from the mailbox to its local cache (the OST for Windows or OLM for Mac). During synchronization, the client downloads copies of all new or changed items from the mailbox and notes any deletions to apply in its local copy. The sync event records that synchronization occurred for a folder. In the normal course of events, you’d expect to see many events recording synchronization for folders like Inbox, Sent Items, Deleted Items, and the Calendar, plus any other folder where messages are moved to. In terms of investigation, the assumption is that if a breach occurs and someone can use Outlook to synchronize a folder to a local cache, potentially all items in that folder are copied.

Bind events record access to an individual message. To reduce the number of audit records, Exchange Online generates a single bind event covering access to messages within a two-minute period. Thus, a bind event might cover access to a single message or ten messages.

To give an idea of the volume of events a user might produce, over a two-day period my account generated 443 MailItemsAccessed events. The majority were Bind events (394), and of these 312 were in the Inbox and 32 in Sent Items.

Interestingly, 25 events were captured for the Outbox, which is a transient folder where items exist while awaiting processing by the Exchange transport service. It’s also used when Outlook posts to a conversation in an Outlook group, which is why the events for the Outbox folder appeared in audit records.

The Potential for Throttling

I don’t use email as heavily as I once did when I was a corporate VP, so expect heavier volumes for other mailboxes. The transfer of some communications to Teams has also reduced email volume in some tenants. However, I do use multiple clients (OWA, Outlook, and Outlook mobile), all of which are usually signed in and active, which increases the number of Bind events. In the case of very active mailboxes, if more than a thousand events are generated for a mailbox in less than 24 hours, Exchange Online stops generating MailItemsAccessed events for that mailbox for 24 hours. Microsoft says that less than 1% of Exchange Online mailboxes are throttled.

Searching for Events

Now we know about what events to expect, how do we access events during an investigation? Using the audit log search in the Microsoft 365 compliance center is not feasible because it’s impossible to correlate events there. Instead, we need to extract relevant events from the audit log and process them into a form that facilitates further analysis.

To do this, I use a PowerShell script to:

  • Use the Search-UnifiedAuditLog cmdlet to find MailItemsAccessed events. The search can be tailored for different date ranges and users.
  • Process each record to extract information from the JSON-formatted AuditData property.
  • Do further processing to make the AuditData information clearer. For example, write out the logon type as text (User, Delegate, or Admin) instead of a numeric code.
  • If possible, perform a message trace to retrieve the subject for messages (see below).
  • Generate a CSV file containing the processed records.

The script transforms an audit record which looks like this:

RunspaceId   : bb26bb84-41fe-4d3f-85dd-e800a4352e3d
RecordType   : ExchangeItemAggregated
CreationDate : 7 Apr 2020 23:47:30
UserIds      : [email protected]
Operations   : MailItemsAccessed
AuditData    : {"CreationTime":"2020-04-07T23:47:30","Id":"f5493f9a-57ce-4859-94bd-fd2ad38d5680","Operation":
               "MailItemsAccessed","OrganizationId":"b662313f-14fc-43a2-9a7a-d2e27f4f3478","RecordType":50,"ResultStatus":"Succeeded","UserKey":"1003BFFD805C87B0","UserType":0,"Version":1,"Workload":"Exchange","UserId":"[email protected]","ClientIPAddress":"2001:bb6:5f4f:f058:4163:e14a:1332:27c7","ClientInfoString":"Client=OutlookService;Outlook-iOS\/2.0;","ExternalAccess ":false,"InternalLogonType":0,"LogonType":0,"LogonUserSid":"S-1-5-21-458367025-2064581115-2950179075-392557","MailboxGuid":"0370f354-2752-4437-878d-cf0e5310a8d4","MailboxOwnerSid":"S-1-5-21-458367025-2064581115-2950179075-392557", "MailboxOwnerUPN":"[email protected]","OperationProperties":[{"Name":"MailAccessType","Value":"Bind"},{"Name":"IsThrottled","Value":"False"}],"OrganizationName":"office365itpros.onmicrosoft.com","OriginatingServer":"DB7PR04MB4346 (15.20.2878.014)\u000d\u000a","SessionId":"1f99e672-8141-4a22-9aa0-96357297e843","Folders":[{"FolderItems":[{"InternetMessageId":"<71ceaeec-6dc3-4452-839f-6db34dd95f95@DB5EUR01BG102.eop-EUR01.prod.protection.outlook.com>"}], "Id":"LgAAAAB+7ILpFNx8TrktaK8VYWerAQBe9CuwLc2fTK7W46L1SAp9AAAA2lHHAAAB","Path":"\\Inbox"}],"OperationCount":1}
ResultIndex  : 1
ResultCount  : 443
Identity     : f5493f9a-57ce-4859-94bd-fd2ad38d5680
IsValid      : True
ObjectState  : Unchanged

To an item looking like this:

TimeStamp  : 7 Apr 2020 23:47
Mailbox    : [email protected]
User       : [email protected]
LogonType  : User
FolderId   : LgAAAAB+7ILpFNx8TrktaK8VYWerAQBe9CuwLc2fTK7W46L1SAp9AAAA2lHHAAAB
Folder     : Inbox
Access     : Bind
Operation  : MailAccessType
Throttled  : False
ClientIP   : 2001:bb6:5f4f:f058:4163:e14a:1332:27c7
ClientInfo : Client=OutlookService;Outlook-iOS/2.0;
SessionId  : 1f99e672-8141-4a22-9aa0-96357297e843
Messages   : (1) 71ceaeec-6dc3-4452-839f-6db34dd95f95@DB5EUR01BG102.eop-EUR01.prod.protection.outlook.com (Spam Notification: 3 New Messages)

The parsed and cleaned-up audit record is much easier to work with.

No Email Subjects

MailItemsAccessed events don’t tell you anything about message subjects. All references to messages in audit events are by their internet message identifier, a unique value generated by the sending mail server. For example:

[email protected]

Microsoft might not include message subjects in the MailItemsAccessed events because they could reveal personal information to an investigator. This is understandable, but the position is undermined by the fact that SharePoint Online is quite happy to reveal document titles in its audit records and message subjects are revealed to investigators in Office 365 content searches.

Given that the audit events only contain internet message identifiers, investigators face the problem of how to connect audit events to real messages. This is important because if an attacker has penetrated a mailbox, you need to understand if any important, confidential, or sensitive information exists in the messages that they accessed.

Message Tracing Helps

The easiest way to match a message identifier with a message is to use a message trace. However, the interactive message trace (available in the Microsoft 365 compliance center) or the Get-MessageTrace cmdlet only supports tracing messages less than ten days old. For this reason, when it processes audit events, the script only calls the Get-MessageTrace cmdlet to retrieve subjects for messages less than 10 days old. The call isn’t made for older messages and some explanatory text is inserted for the subject instead. The output for a set of messages found in a MailItemsAccessed Bind event looks something like this. The presence of the subject makes it much easier to understand if any important messages were compromised.

(1) CH2PR00MB0763CF5D33C5C47B0E0700B6A1C30@CH2PR00MB0763.namprd00.prod.outlook.com (Re: Counting Distribution list members);
(2) [email protected] (TechSmith Influencer News – Camtasia 2020 sneak peek, help for organizations transitioning to remote work and learning, and more!);
(3) 20200407140628.27860.640645555.swift@theirishtimes.activehosted.com (Coronavirus: Ireland’s infection peak may have passed, toll could hit 400 by August, report forecasts);
(4) DM6PR00MB07650C27AC4B4FA1245BA27BC4C30@DM6PR00MB0765.namprd00.prod.outlook.com (Presentation on ‘Inclusive Meetings’ today)

Tracing Older Messages

For older messages, it’s possible to run an historic search to retrieve details of messages between 11 and 90 days old, but you can’t do this interactively as the cmdlet sets up a background search. Exchange Online doesn’t hold message tracing data for longer than 90 days, which creates a problem if an attacker accesses older email. On the upside, older email might not be quite as sensitive as newer messages.

You can link message identifiers found in audit events to old email, but it’s a tedious business if the data isn’t in some searchable repository. The manual approach is to use Outlook or OWA to examine messages in the user’s mailbox around the date of the audit event. For each message, use the Message Header Analysis add-in to report message headers, among which is the internet message identifier (Figure 2).

Image 2 Expand
MHA retrieves Internet Message Identifier
Figure 2: Using the Message Header Analysis add-in to check an email’s internet message identifier (image credit: Tony Redmond)

Interpreting the Audit Events

My script (which you can download from GitHub) outputs results to a PowerShell list, which makes it easy to generate statistics like the number of bind events per folder. The list is also piped to PowerShell’s Out-GridView window for initial analysis (Figure 3) and to a CSV file for consideration over the longer term.

Image 3 Expand

MailItemsAudit Records

Figure 3: Browsing MailItemsAccessed audit records with Out-GridView (image credit: Tony Redmond)

Out-GridView is a great way to get an initial handle on what might have happened because you can quickly sort events by SessionId or Client IP Address. Microsoft’s documentation explains how to use these fields to link events together to highlight actions that might have been performed by an attacker.

Helpful Insight into What Happens in a Mailbox

MailItemsAccessed audit events provide a helpful insight into what goes on when users access mailbox items. I’d like to see the information published in the events be more accessible and complete (message subject is an important piece of data), but what we have now is better than what we had before.

Generating and storing audit events costs money, especially when the events are prolific. I understand why Microsoft regards MailItemsAccessed as a crucial event and look forward to seeing what other events matching the criteria they deliver in the future. It’s just a pity that these audit events are an E5 feature. E3 tenants are attacked too!