Hello Reader,
In the prior post with the help of an Outlook plugin we examine the value of a single Extended MAPI property. Now that's great for my testing but what if in your work you need to prove that value exists within the structure and validate the tools output? I thought before we continued on our journey into Outlook/Exchange message interactions we should see how to work with the raw data.
The first thing you should know about the underlying message structure is that it is not just a text file like a RFC82 email message. This would be obvious if you opened up the message in a text editor and saw something like this
The message structure is actually a Compound File Binary Format, meaning a little file system exists within this message and the data we see loaded within the mail client is retrieved from streams of data stored within it. Viewing the same file with a tool that support CFBF like Structure Storage Viewer would show us this
Now we can see the streams of data as its stored. In future posts I am going to go more into the structure of these streams in future posts as it relates to our DFIR work, if you want to jump ahead to that go here https://blogs.msdn.microsoft.com/openspecification/2009/11/06/msg-file-format-part-1/.
The Extended MAPI data we were locating at yesterday is stored within the stream named __properties_version1.0. I saved this stream to my disk with a structured storage viewer and then loaded the stream with 010 hex editor.
What you are seeing in 16 byte entries is all of the named properties we saw within the message and the extended MAPI data. Within this structure is our PR_CREATION_TIME and our PR_LAST_MODIFICATION_TIME values we looked at yesterday. To find them we need to lookup their tag as defined in the MSDN reference. Each extended MAPI property has a fixed tag value that lets use find the value in the structure but while its shown in big endian in the MSDN documentation its stored in little endian within the data structure itself.
So looking at PR_CREATION_TIME (https://docs.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagcreationtime-canonical-property) we can see that the tag is 0x3007. When you apply the last 4 bytes of the access mask 0040 for the property and the tag you are looking for is 0x30070040 which in little endian is 40007030 and serching for that will find that the third record down is our value.
The timestamp is in the next 8 bytes and is in windows 64 bit little endian filetime format.
Which if we copy out and put into a tool like DCODE. The timestamp we retrieved is not the same as we saw yesterday within the mailbox as I exported the message onto my desktop to get it loaded into structure storage viewer. The action of saving the message to my disk reset the PR_CREATION_TIME to when I saved it to my disk. I need to do more testing on this going forward to see what this really means for us.
In the prior post with the help of an Outlook plugin we examine the value of a single Extended MAPI property. Now that's great for my testing but what if in your work you need to prove that value exists within the structure and validate the tools output? I thought before we continued on our journey into Outlook/Exchange message interactions we should see how to work with the raw data.
The first thing you should know about the underlying message structure is that it is not just a text file like a RFC82 email message. This would be obvious if you opened up the message in a text editor and saw something like this
The message structure is actually a Compound File Binary Format, meaning a little file system exists within this message and the data we see loaded within the mail client is retrieved from streams of data stored within it. Viewing the same file with a tool that support CFBF like Structure Storage Viewer would show us this
Now we can see the streams of data as its stored. In future posts I am going to go more into the structure of these streams in future posts as it relates to our DFIR work, if you want to jump ahead to that go here https://blogs.msdn.microsoft.com/openspecification/2009/11/06/msg-file-format-part-1/.
The Extended MAPI data we were locating at yesterday is stored within the stream named __properties_version1.0. I saved this stream to my disk with a structured storage viewer and then loaded the stream with 010 hex editor.
What you are seeing in 16 byte entries is all of the named properties we saw within the message and the extended MAPI data. Within this structure is our PR_CREATION_TIME and our PR_LAST_MODIFICATION_TIME values we looked at yesterday. To find them we need to lookup their tag as defined in the MSDN reference. Each extended MAPI property has a fixed tag value that lets use find the value in the structure but while its shown in big endian in the MSDN documentation its stored in little endian within the data structure itself.
So looking at PR_CREATION_TIME (https://docs.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtagcreationtime-canonical-property) we can see that the tag is 0x3007. When you apply the last 4 bytes of the access mask 0040 for the property and the tag you are looking for is 0x30070040 which in little endian is 40007030 and serching for that will find that the third record down is our value.
The timestamp is in the next 8 bytes and is in windows 64 bit little endian filetime format.
Which if we copy out and put into a tool like DCODE. The timestamp we retrieved is not the same as we saw yesterday within the mailbox as I exported the message onto my desktop to get it loaded into structure storage viewer. The action of saving the message to my disk reset the PR_CREATION_TIME to when I saved it to my disk. I need to do more testing on this going forward to see what this really means for us.
We can do the same for the PR_LAST_MODIFICATION_TIME which we can see in the MSDN documentation for PR_LAST_MODIFICATION_TIME is tag 0x3008 which with the access bit is 0x30080040 and in little endian is 0x40008030.
Searching within the stream we can see the 4th entry within the structure is in fact the PR_LAST_MODIFICATION_TIME
Which when decoded will match the creation as the structure was modified when I exported it to disk.
Now that we can locate these tags within the data itself that means we should be able to write some Python code with libolecf to parse this data out at scale once we've defined the use cases we want to analyze.
Much more to come so please keep reading with me as we journey together into the depths of Outlook/Exchange message interactions.
Continue Reading: Daily Blog #385: Exploring Extended MAPI Part 2
Post a Comment