exFAT Timestamp Behavior Associated with Different Operating Systems

Much like my recent post on ‘Using Extended MAPI Properties to determine email sent time’ this post is a response to David Cowen’s ‘Sunday Funday' challenge as detailed over at ‘Hacking Exposed - Computer Forensics Blog’.

The question posed by David was as follows:

ExFAT is documented to have a timezone field to document which timezone a timestamp was populated with. However most tools just see it as FAT and ignore it. For this challenge document for the following operating systems how they populate ExFAT timestamps and which utility will properly show the correct values.
  • Operating systems:
  • Windows 7
  • Windows 10
  • OSX High Sierra
  • Ubuntu Linux 16.04

This sort of question/ challenge is exactly the sort of thing I enjoy. I’m always keen to learn something new and find it interesting to test how artefacts behave under various circumstances and determine the implication(s) as they relate to forensic analysis.

With that said, I went decidedly off-piste and ended up down a whole range of rabbit holes exploring odd observations and working to better my understanding of exFAT. To that end, I will be following up with a much longer, possibly even a series of posts detailing my observations and methodology.

For the moment I wanted just to share a few of the high level observations.

In preparation I undertook a significant number of tests, performing different file operations using different Operating Systems, I also expanded the tests to include Windows 8.1 and Ubuntu 18.04. The results of all test were written to a spreadsheet where the date/time as recorded in my notes could be compared to the relevant fields as they appear on disk. I then furnished the same spreadsheet with details as to how each tool I analysed displayed the timestamps, and as I am sure any reader will agree nothing makes for quick and easy conclusions like a 1332 cell Excel monstrosity. 

Unsurprisingly this took a significant amount of time to review and in all honesty it has not yet been fully mined for its potential value, hence why a more detailed post will follow. On the basis of these tests the following observations are made as it relates to each OS’s handling of the exFAT file system:

How different operating systems use the three available Date/Time fields

The first observations relate to how the operating systems employ the different time fields, different Operating Systems implement and maintain different timestamps for files depending on a number of factors and as such they employ different terminology. For the purpose of this exercise we assume the knowledge that exFAT supports the recording of 3 distinct timestamps, refereed to in this post as Created, Accessed and Last Modified. We then examine the timestamps presented within the various operating systems and correlate them to the exFAT field they draw the data from.

Operating SystemOS NameexFAT Field
OSX 10.13.3CreatedCreated
OSX 10.13.3AccessedAccessed
OSX 10.13.3ModifiedModified
OSX 10.13.3ChangedModified
Windows 7/8/10Date CreatedCreated
Windows 7/8/10Date ModifiedModified
Windows 7/8/10Date AccessedAccessed
Ubuntu 16/18.04BirthN/A
Ubuntu 16/18.04AccessedAccessed
Ubuntu 16/18.04ModifiedModified
Ubuntu 16/18.04ChangedModified

A summary of how each of the tested operating systems utilitises the various timestamp, adjustment and timezone fields is outlined below. I hasten to add that these were the results from my initial testing, most will be repeated in preparation for the detailed posts so as to confirm the more notable findings.

Windows 10

Creation Time – Recorded with centisecond granularity, the default 2 second granularity associated with the MSDOS 32bit Timestamp is complemented with an additional field which permits addition of up to 199 centiseconds.

Last Modified Time – Recorded with 2 second granularity as the additional field appears to go unused and is consistently populated with a value of 0.

Accessed Time – Recorded with 2 second granularity due to lack of support in exFAT for greater granularity.

Timezone Fields – All timestamps are recorded as a direct representation of the local time of the system, the UTC offset (as configured on the system) is recorded in the associated timezone fields.

Windows 8 and Windows 7

Creation Time – Recorded with centisecond granularity.

Last Modified Time – Recorded with centisecond granularity when this timestamp is populated as a result of a new file being created (e.g. echo data into a file or right click, new file) however when the file is created as a result of a copy or move action then the centisecond granularity is dropped. The offset is consistently set at 0 and at this stage I have to assume that the timestamp is rounded down to the nearest even second.

Accessed Time – Recorded with 2 second granularity due to lack of support in exFAT for greater granularity.

Timezone Fields – All timestamps are recorded as a direct representation of the local time of the system, the UTC offset (as configured on the system) is recorded in the associated timezone fields.

Ubuntu 16.04 and Ubuntu 18.04

Creation Time – Recorded with nearest second granularity, while exFAT supports the recording of centisecond offsets the only observed offsets used are 0 and 1.

Last Modified Time – Recorded with nearest second granularity, while exFAT supports the recording of centisecond offsets the only observed offsets used are 0 and 1.

Accessed Time – Recorded with 2 second granularity due to lack of support in exFAT for greater granularity.

Timezone Fields – All timezones are recorded in UTCThe Timezone fields are consistently set to 00, indicating that they are not in use. A

OSX 10.13.3

Creation Time – Recorded with centisecond granularity.

Last Modified Time – Recorded with centisecond granularity

Accessed Time – Recorded with 2 second granularity due to lack of support in exFAT for greater granularity.

Timezone Fields – Consistently set to “FC” which is UTC-1 and I have no idea why...

Tool Interpretation of Timestamp date

For this half of the question David left it up to us to choose which tools/utilities to test to determine “which utility will properly show the correct values”. I felt it would be most useful to provide an overview of how the major forensics suites (or at least those I have access to) display the data and how they refer to the different timestamps. To that end I set out to test how different tools presented the timestamp information associated with the same filesystem I generated in Part 1, by creating files on a single USB device. 

The following tools have been tested so far:
  • EnCase 7.12.1
  • X-Ways Forensics 19.6
  • FTK 6.2
  • TSK Autopsy 4.7.0
  • Windows 10 Native
  • Ubuntu 18.04 Native

I intend to expand on this list and provide a detailed review of the performance limitations associated with each. But for the moment the summary result is that no tool will reliably display the exFAT timestamps associated with the various tested operating systems. The tools all failed to accurately display the date an action was performed in one way or another for at least one of the operating systems. Importantly this isn't always a failure of the tool, as above the the differences in implementation of exFAT cause inconsistencies which no tool could account for.

The tools which failed the worst are those which asked the examiner to specify the source timezone, commonly these ignored the provided timezone data altogether and then adjusted all the decoded MSDOS timestamps at the whim of the user. This scenario is most challenging when an item of removable storage media has been written to by multiple different operating systems or multiple instances of the same OS but with different timezone settings configured.

One key point to mention is that one type of tool will correctly inform the examiner of the timestamp data written to disk, that is to say that tools which do not attempt to perform any interpretation can't misinterpret that data. 

One example which worked flawlessly during this analysis was to use the third party WinHex exFAT Template by Scott Pancoast (https://www.x-ways.net/winhex/templates/index.html) to display the values of the Directory Records. Another interesting point to note here is that manual review of the timezone and timestamp data associated with files on an exFAT can provide additional forensic value, for instance the inconsistencies in how the filesystem is handled and what data gets written to different fields (as detailed above) can help you suppose what OS (and maybe version) was used to write the files to disk.

Thanks to David for inspiring some research that I thoroughly enjoyed, and watch this space for the fuller analysis and findings.


Office 365 Activities API - Example Output

Yesterday CrowdStrike published details of the 'Office 365 Activities API' which is an extremely useful source of evidence for investigations, especially in cases of Business Email Compromise. The detailed post can be read here. Included was a Python module which allows one to pull the discussed data from O365.

I also put out a recent blogpost commenting on how much research goes unshared and how I feel it is important that companies and individuals share resources, tools and research so as to further the whole field. In the mean time I had been working with a test O365 account to generate some Activity API output for colleagues and industry friends who may not have seen it before and who don't necessarily have access to an O365 account for testing, I would be a little hypocritical if I didn't share this with the wider community so here goes.

Incidentally if you want to jump to the output data without reading all my waffle, it can be found here.

The Setup

My Office365 test environment is a single user tenant at the time of testing so my only user is also an admin user. This poses some limitations but I will be expanding testing with the addition of a further account shortly. In the mean time I have used two Office365 accounts which I have access to, one where I am an admin and one where I am a user. In both cases a user is able to access the Activities API data as it relates to their own account. 

The Procedure

My testing procedure comprised of logging into an O365 mailbox and performing actions which I thought would generate some interesting log data for a sample output. I actually performed these actions across two accounts and then merged the log so there was only a single file to review. 

The accounts were both configured to be accessible from a mobile device (Android mail configured with exchange settings). No effort was made to generate traffic from a mobile device, all activity was performed via the browser, however it is possible that this may have impacted the resultant logs.

After downloading the python module from the CrowdStrike GitHub the first task was to generate some known account activity. The following steps were performed:

--Account 1--

2018-06-20T07:36:00 - Open Outlook.com (autologin)
2018-06-20T07:37:00 - Sign out
2018-06-20T07:37:30 - Sign in
2018-06-20T07:38:00 - Approve sign in request via android app
2018-06-20T07:38:30 - Opt to "stay signed in"
2018-06-20T07:39:10 - Open 'Outlook' web app
2018-06-20T07:39:40 - open email in viewing pane
2018-06-20T07:40:00 - open email in jump out window
2018-06-20T07:40:25 - select [new (+)] to compose new email
2018-06-20T07:41:07 - send email
2018-06-20T07:41:28 - open sent items
2018-06-20T07:42:00 - open sent email message in viewing pane
2018-06-20T07:42:30 - press delete on sent email
2018-06-20T07:42:55 - expand folders view
2018-06-20T07:43:25 - right click and select delete all from deleted items
2018-06-20T07:44:00 - open Junk email
2018-06-20T07:44:44 - press settings
2018-06-20T07:45:45 - close settings
2018-06-20T07:46:46 - right click message and 'create rule'
2018-06-20T07:47:37 - save rule
2018-06-20T07:48:00 - select 'OK'
2018-06-20T07:49:15 - search for and open 'inbox rules'
2018-06-20T07:49:48 - press new
2018-06-20T07:50:15 - receive alert and open it
2018-06-20T07:50:42 - select investigate and Security & Compliance center opens
2018-06-20T07:51:17 - return and cancel rule creation
2018-06-20T07:51:55 - Sign Out
2018-06-20T08:44:15 - Sign In

--Account 2--

2018-06-20T08:44:25 - Search for 'wire transfer'
2018-06-20T08:44:25 - Search for 'banking'
2018-06-20T08:44:25 - Search for 'bacs'

The next step was to acquire an OAuth Token, for the purposes of testing I employed the Outlook Dev Center - OAuth Sandbox to generate the appropriate OAuth token. For those who are not familiar the procedure is as follows:

1. Select 'Authorise using your own account:

2. Authenticate with the relevant account credentials:

3. Copy Out the Access token that appears in the 'Access Token' box:

Note that the Access Token is a long string including characters which may preclude the 'double click to select call' so 'Ctrl-A'ing while within the text box is your best bet.

The copied string can then be added to the --Token variable when using CrowdStrike's retriever.py in the below command to dump the full history of activities for a user:

python retriever.py --user test@address.com --output activities.csv --token [OAuth Access Token String]

The above command worked for me but I have limited activity on my test account, more targeted extracts may be needed for genuine accounts.

My test output should be reviewed in conjunction with the list of activities performed, as above. Note that the times are approximate on account of me being human. The logs have been modified to replace my Login IP with '' and the account addresses have been modified to 'test@address.com'.

Without further ado, the resulting csv output from my testing is available here.

Sharing is Caring - The Secret O365 API

The whole field of DFIR thrives and survives on shared research. Professionals who identify novel techniques or develop tools which they share outside their organisation help to drive progress, achieve better understanding and ultimately help the community in the arms race against bad actors.

A recent example which brought this to mind (and prompted this post) is the release of details regarding the Office 365 Activities API as detailed in this post by CrowdStrike.

What will likely follow is a rambling post about information sharing in DFIR so if you are here for technical details you are in the wrong place, check out the CrowdStrike writeup which is detailed and informative.

Business Email Compromise (BEC)

With the introduction of Outlook Web Access and even moreso since the increased adoption of Office 365 (and GSuite) for cloud email within businesses, Business Email Compromise (BEC) has been a growing issue. Over the last 6 years I have been involved in the investigation of many dozens of such incidents. Unsurprisingly, these cases have a tendency to merge into one in the memory but a few have stuck out over the years. 

The most significant was the first case I investigated, the customer suffered a compromise of a number of GSuite ('Google Apps for Business' at the time) email accounts, following which executive impersonation was used to defraud them of c1.25million Australian Dollars. The money  was wired out by a duped finance employee in a series of transactions as is a common theme in these kinds of compromise. This case was notable due to the certainty with which the customer insisted that it must be an inside job, sure that disgruntled IT staff must be behind it. The client's insistence that we investigate their hunch as a priority, coupled with the limited logging available in Google Apps for Business made for a difficult investigation.

Another especially notable case was in mid 2016 where a a large organisation had suffered a multi account compromise. During the incident the attacker(s) used compromised accounts to phish other internal accounts (another common MO in BEC) eventually resulting in the attacker gaining access to the accounts of senior staff. We were employed to conduct the investigation and the client had already engaged with Microsoft who as it turns out were in a particularly helpful mood that day. There was nothing to set this case apart for the multitude of O365 breaches I had investigated during that time, other than the additional visibility Microsoft were able to share into mailbox account activity.

The client had not enabled any of the available (but off by default) auditing within O365 and AzureAD however as their MS account rep put it, Microsoft may be able to assist but they would need to run queries in their big data system to get some logs. Don't judge too harshly, it was 2016, 'big data' was all the rage. Lo and behold a couple of days later they produced logs per impacted mailbox which contained unprecedented detail on what messages were accessed, searches run as well as login event information. This information is invaluable when investigating cases of BEC and in this case the motivation of the attacker was clear very quickly. Each mailbox was searched for a series of keywords (e.g. bacs, wire transfer, international payment etc) and no other information had been accessed where no hits were returned the account access ceased or the account was used to target other users. 

Since then I have encouraged clients to make similar requests to their Microsoft account rep in an effort to get these same logs, especially in cases where all other logging was not enabled. These requests have received inconsistent and commonly unsatisfactory responses especially where the customers were "small fry" tenants with users in the 1000's rather than 10000's. With that said, from time to time customers requests were met with the delivery of logs, and where provided the logs were generally of a consistent format. What I didn't know at the time was that the output we were being provided was associated with the 'Office 365 Activities API' and that it is available to all O365 users irrespective of enabled logging (at least for now) [edited 2018-07-08: The Activities API appears to have been locked down and is no longer available at this time].

The 'Secret API'

During DFIR conferences, at talks and on Twitter, the topic of the 'Secret API' has arisen from time to time. It was evident that access to this information was possible and that a number of individuals and organisation had decided to keep this to themselves in an effort to maintain some sort of competitive advantage. The existence and functionality of the API had been kept quiet by those in the know and  I have heard that some SIEM vendors and IR consulting firms have boasted to prospective customers that they had abilities that their competitors did not, as it relates to investigating or integrating with O365 logging.

In this case, and in other similar examples I feel this poses an interesting dilemma to anyone who identifies similar novel analysis methodologies. Personally I feel those who declined to share the information did so at the detriment of other victims. In coming to this conclusion I have considered the following:
  • DFIR survives on shared research. The reason I started this blog was in recognition of the fact that I have benefited from the research and efforts of others who have investigated artifacts and publicly disclosed their findings. We need to see beyond short term commercial gain in the shared battle against bad actors.
  • I can't imagine that the 'competitive advantage' these organisations benefited from could be all that significant. Clearly it was being touted enough that it was being used to try to win business but do prospective customers really buy into these claims when so often they are only marketing hype?
  • It is possible that this information becoming public may cause Microsoft to close down the API prematurely. This is the only defensible justification I can see, I appreciate that widespread disclosure may have (and still may) cause this to prematurely vanish. It isn't lost on me that the CrowdStrike post comes at a time when a number of firms had intimated that they may publish something and indeed a time when the findings have a limited shelf life, as it would appear the API is set to be EOL in 2019. 
  • There is also the risk of a "If other firms aren't sharing, why should I" mentality and I can appreciate this. I've worked in firms where research is seldom published and as such I was part of that problem. In 'listen only' mode some organisations will leech up the work of others while holding tight to their own original research. The answer however is not to close off but rather lead by example and lay rightful praise at the feet of our competitors when they do good research, share findings and further the DFIR/Infosec community as a whole.
To that end I think credit should be given to CrowdStrike for making the decision to share this information with the wider community while other organisations who were evidently 'in the know' did not. They are by no means unique and fantastic work is constantly being published by loads of firms in the field.

I would be interested to hear other peoples take on the topic of sharing research and findings which might otherwise offer a competitive advantage, clearly one size doesn't fit all but are there other considerations which I haven't detailed above?


Using Extended MAPI Properties to determine email sent time

Recently, David Cowen at 'Hacking Exposed - Computer Forensics Blog' has resumed the 'Zeltser Challenge' of daily blogging. In doing so, he has highlighted (at least to me) that after a short initial flourish this blog has been somewhat neglected, taking a back seat while regular work and other commitments have ramped up again.

Inspired by David's effort and with an eye on his 'Sunday Funday' challenge series I thought I would respond to the most recent challenge via blogpost. The challenge in question is detailed at this post and in essence asks the question:
'What within an email message sent from Outlook and connected to an Exchange server would allow an examiner to determine when an email was sent from the system they are examining presuming they found the message in the sent folder within the mailbox.'
In my day-to-day work I have limited need to analyse emails for the senders machine so this posed an interesting opportunity to look into Extended MAPI Properties for the first time in a long time.

The Setup

When performing this type of research I would normally aim to set up a number of test environments combining a mix of OS, client and configuration versions however for the purposes of this exercise I have limited my research to a single setup, as follows:

Windows 10 (10.0.17134.48)

Outlook 2016 (16.0.9330.2073)

Office365 Account
The test setup comprised:

  • Microsoft Windows 10 (10.0.17134.48)
  • Outlook 2016 (16.0.9330.2073)
  • An Office365 email account configured as an exchange mailbox using default settings within Outlook.

Examining MAPI Properties

There are a number of ways to view MAPI properties within various forensic suites and using plugins for Outlook. For the purposes of this analysis I used Kernel OST Viewer and will look to verify findings using a secondary tool, however have not done so at this stage.

Kernel OST Viewer 15

Viewing MAPI Properties in Kernel OST Viewer could not be simpler. After launching the application, press 'Select File'. 

Kernel OST Viewer 15

This will present you with the 'Source File Selection' dialog box.

Kernel OST Viewer 15

'Browse' to the location of your OST for analysis, within this configuration the OST is located in the default location of 'C:\Users\[UserName]\AppData\Local\Microsoft\Outlook'. Once selected, you will be presented with a further box, select 'Finish' and the OST will be parsed.

Select any message within the messages table and then select the 'Advanced Properties View' tab in the Viewing Pane. In the image below we have navigated to the Sent Items folder as this will be of note during testing.

Kernel OST Viewer 15

Now that we have a way to examine the MAPI Properties we can commence testing.

Date Fields in MAPI Properties

The first thing I examined was sending a test message and examining what MAPI Properties were associated with it and particularly those which contained date values. Immediately notable are 5 values which contain Windows Filetime data. In all test messages the following Properties were populated:

Principal MAPI Timestamps

As detailed in the image the identified Property name and Property Tag associated with these properties was:
PR_CREATION_TIME | 0x30070040
PidLidValidFlagStringProof | 0x85BF0040
0x00000F0A | 0x0F0A0040
0x00000F02 | 0x0F020040

In addition to these properties, certain other properties also contained dates within strings such as Property 0x0000844D and various others.
0x0000844D MAPI Property

While these other properties are of various forensic value and indeed may assist in corroborating dates and times observed elsewhere, they have been excluded from this testing for the moment.


In testing I chose to test three scenarios to examine the impact on the MAPI Properties on the items as they existed within sent items.

Scenario 1: A user presses compose, generates their message and sends it.
Scenario 2: A user presses compose, generates a message, closes it (saving a draft), reopens the message making modifications and then sends the message.
Scenario 3: A user presses compose, generates their message and sends it while the computer is disconnected from the network, causing the message to be held in the users outbox, the message is then later transmitted when the network reconnects.

Each test was repeated three times with no observed differences between the examined MAPI Property behavior within each repetition of a scenario. One example for each is detailed below in the Results section.


--Test 1--
Tested Scenario: 
Message composed and sent

Actions Performed:
20180611T22:30:22 – Pressed 'Compose' within Outlook and typed email message
20180611T22:31:03 – Pressed 'Send'.

MAPI Property values:
0x00000F0A = 20180611T22:31:03
0x00000F02 = 20180611T22:31:03
PR_CREATION_TIME = 20180611T22:31:03
PR_CLIENT_SUBMIT_TIME = 20180611T22:31:03
PidLidValidFlagStringProof = 20180611T22:31:03

Notably the property values all show a consistent date/time, the PR_CREATION_TIME and PR_CLIENT_SUBMIT_TIME show the same timestamp.

--Test 2--
Tested Scenario: 
Message Composed, Saved as Draft, Opened and Sent

Actions Performed:
20180611T22:40:50 – Pressed 'Compose' within Outlook and typed email message
20180611T22:41:25 – Closed email message
20180611T22:41:30 – Select 'Save; when prompted to save as draft
20180611T22:42:16 – Opened Draft and updated
20180611T22:43:09 – Pressed 'Send'.

MAPI Property values:
0x00000F0A = 20180611T22:43:09
0x00000F02 = 20180611T22:43:10
PR_CREATION_TIME = 20180611T22:43:09
PR_CLIENT_SUBMIT_TIME = 20180611T22:43:09
PidLidValidFlagStringProof = 20180611T22:43:10

Once again, despite the saving of a draft all timestamps associated with the examined MAPI Properties are within 1 second of the 'Send' button being pressed.

--Test 3--
Tested Scenario: 
Message Composed, Sent while system is offline and held in Outbox, Transmitted when system reconnected to network.

Actions Performed:
20180611T22:48:02 – Pressed 'Compose' within Outlook and typed email message
20180611T22:49:50 – Pressed 'Send'
20180611T22:50:30 – Reconnect Network
20180611T22:51:02 – Pressed 'Send/Receive'

MAPI Property values:
0x00000F0A = 20180611T22:51:04
0x00000F02 = 20180611T22:49:50
PR_CREATION_TIME = 20180611T22:51:04
PR_CLIENT_SUBMIT_TIME = 20180611T22:51:04
PidLidValidFlagStringProof = 20180611T22:49:50

Notably within this test we see groupings of timestamps. PidLidValidFlagStringProof and 0x00000F02 appear to reflect the time that the user pressed 'Send' while PR_CREATION_TIME, PR_CLIENT_SUBMIT_TIME and 0x00000F0A appear to reflect the time the message was actually sent from the computer once it had network connectivity restored.


In answer of the challenge the PR_CLIENT_SUBMIT_TIME and PR_CREATION_TIME most accurately reflect when a message was sent from a system. This is consistent with Microsoft documentation which indicates that "The store provider sets PR_CLIENT_SUBMIT_TIME to the time that the client application called IMessage::SubmitMessage." and that PR_CREATION_TIME is "set by message store providers on outgoing messages." as detailed here.

It should be noted however that in cases of a discrepancy between these timestamps and 0x00000F02  or PidLidValidFlagStringProof then it would appear that these may serve as an indication that while the message was transmitted at a particular time the user may have attempted to send (i.e. pressed 'Send') at a time prior to it's transmission.

Further testing

This analysis has been quick and dirty and leaves lots of unanswered questions. Some areas for possible further research may include:
  • Reviewing of other timestamps as they appear in other MAPI Properties.
  • Review of timestamp behavior when system time is tampered with
  • Review of MAPI Property fields when comparing messages which are sent using 'Send/Receive' vs automatic message synchronization following a disconnected network connection