MS Excel and BIFF Metadata: Last Opened By

In my last post, I discussed using an OLE timestamp to determine the last time an Excel spreadsheet was opened and closed without being saved.  The last opened time can be very helpful, but wouldn’t it be nice to know more about who may have opened the file? The Last Saved By metadata field will help if the file was saved after it was opened, but it may not provide additional information if the file was not saved.  However, the file’s Workbook stream, comprised of a Binary Interchange File Format (BIFF) data structure, includes a field that records the user name associated with the account that last opened the Excel spreadsheet.  This data is recorded regardless of whether the file is saved and can provide information regarding the last user that opened the file.

The Details

Microsoft Excel spreadsheets saved in the OLE compound file format utilize the Binary Interchange File Format (BIFF) for saving data in the Workbook stream of the spreadsheet.  I’m not going to cover the intricacies of the BIFF here; for more information, refer to the Microsoft specification.  There is more than one version of BIFF as well; version 8 is the specific version addressed in this post.
According to this Microsoft KB article, “when you open an Excel workbook, Excel writes the name of the current user to the header of the file” (the article later states that this does not apply to .xlsx files).  The “header” of the file, as it’s described, is actually the “Write Access User Name” record within the BIFF data structure that comprises the file’s Workbook stream.  It’s important to note that the user name is referenced from the UserInfo subkey in the user’s NTUSER.DAT, which may not be the same as the user name of the Windows account.  Regardless of whether the file is saved, the user name is written to the Write Access User Name record.  As such, data stored in this record may be different from the Last Saved By metadata field located in the Summary Information stream.
When the “Protected View” warning bar appears (requiring the user to click “Enable Editing” to edit the spreadsheet), it appears that updates to the Write Access User Name record will depend on the volume from which the file was opened.  Opening a file that was downloaded from the Internet but stored on the local hard disk results in an update to user name in the record (regardless of whether the “Enable Editing” button is clicked by the user).  Opening a file from a network resource will not update the record unless the user clicks the “Enable Editing” button.  It should be noted though that my testing has been limited with regard to the Protected View functionality.
Interestingly, it appears that as different users open the same spreadsheet, the Write Access User Name record is simply overwritten as opposed to the previous user name being cleared first.  This means that you may find residual data following the end of the most recent user name.  The screenshot below depicts this scenario.  The most recent user name is “Jason”, while “e 2010” is still stored in the record (the previous user name was “Office 2010”).  This remained consistent in my testing of Excel 2000, 2007, and 2010 (I did not have Excel 2003 or 2013 available to me at the time of testing).
Write Access User Name record

Finding the Record

The Write Access User Name record should be stored near the beginning of the Workbook stream.  You can easily view this stream using a tool such as SSView, although the user name may not be parsed out automatically.  Once you’ve identified the Workbook stream, the user name should be visible in a hex editor.  The only tool I’ve currently tested that parses the user name is X-Ways Forensics, so it may be necessary to manually parse this record if you don’t have a tool that will do it for you (or if you want to verify the results of your tool or just enjoy manually parsing data structures).
An easy way to find the Write Access User Name record within the Workbook stream is to search for a block of 0x20.  According to the MS documentation, this record should be exactly 112 bytes in size and is padded with spaces (0x20) after the end of the user name.  Since most user names will likely only be a few characters in length, a block of 0x20 after the end of the name will be necessary for padding the record to 112 bytes. This method should work for identifying the Write Access User Name record, but I would recommend following along using the binary specification referenced earlier to develop a better understanding of the data structure.  If there is residual data after the current user name in the record, familiarity with the data structure will allow you to easily distinguish between current and previous data.

Forensic Implications

Parsing the data from the Write Access User Name record within an Excel spreadsheet saved in the OLE compound file format can provide an examiner with a metadata field that may be equated to the “Last Opened By” user.  This can be particularly helpful when a limited set of data is provided for analysis or otherwise any time information regarding the last time a spreadsheet was opened is significant.  By combining this data with the OLE Root Entry last modified time, it is possible for an examiner to determine the last time an Excel spreadsheet was opened as well as the user name associated with the account that opened the spreadsheet, even if the file was not saved and nothing other than the file itself is available for analysis.

Microsoft Excel (xls) Binary File Format Specification 


Leave a Reply