Hi Andris,
This is extremely helpful, thank you! Although some of these timestamps might be duplicated elsewhere, it is important to check all available timestamps during a forensic investigation to make sure they all agree with each other. Otherwise, there is a chance that the message was altered and some of the timestamps had been overlooked. So, this is awesome!
I would like to bring some clarity for anyone who is not familiar with the data points Andris mentioned above. These are actually the internal IDs (or service IDs)—not to be confused with Message-ID—and Thread IDs—not to be confused with Thread-Index or Conversation Index—of messages within Gmail. So, they are applicable regardless of the use of IMAP and they can be queried via Gmail API. Gmail also provides some IMAP protocol extensions that allow these values, among others, to be queried over IMAP as well—X-GM-MSGID and X-GM-THRID.
If you are familiar with FEC, you would see these values in our Gmail API Downloaded Items logs in the Service ID and Thread ID columns in hexadecimal form.
As Andris explained brilliantly, taking the first eleven digits of the hex values and converting them to decimal gives us an Epoch timestamp. Here is an example from a recent Downloaded Items log (I took out some columns for brevity):
|Service ID|MIME Hash |Gmail Labels|Thread ID|
|—|—|—|—|—|
|1732f1fc6ee3a193|8FA55CD0…|IMPORTANT;CATEGORY_PERSONAL;INBOX|1732f1fc6ee3a193|
|173106a253a37c64|06917114…|UNREAD;CATEGORY_UPDATES;INBOX|173106a253a37c64|
Let’s take the Service ID of the first message:
Service ID: 1732f1fc6ee3a193
First 11 digits converted to decimal: 1732f1fc6ee ➫ 1594223478510
Conversion from Epoch to Human Readable: 1594223478510 ➫ July 8, 2020 3:51:18.510 PM (UTC)
The July 8, 2020 3:51:18.510 PM (UTC) timestamp matches the time Google’s server received the message after it was submitted.
I didn’t remove the last three decimal digits; just treated them as the millisecond component of the Epoch timestamp.
As Andris mentioned, the Thread ID is even more valuable because it is carried over from previous messages in the same conversation thread!
Note that I also had a Thread-Index header field in this message as part of the message headers. This was created by Outlook and looked as follows:
Thread-Index: AdZVP5FZ1lMVdyWGSQmgf4yUt3eB7w==
Decoding this gives a header timestamp of July 8, 2020 3:50:56.3837952 PM (UTC)—moments before the timestamp we decoded from the message ID. This makes sense because the Thread-Index was created on the client-side before the message hit the server. We covered this before here:
Thanks to Andris, I think another update to the Dates in Hiding blog post is in order!