Overview
I read a few blog posts and slide presentations discussing the forensic value of alias data within plists.
They typically consisted of running strings against the Data object to pull path data out.
Rather than relying on strings I decided to reverse engineer the Alias Version 3 format and provide a Pythonic means to parse it.
Alias Version 2 had been reversed and documented previously (I lost the link), but version 3 from what I could find had not. Version 3 has a different structure than Version 2. I got about 90% of it complete. There are still some bytes I am unsure about, but I believe I got most/all of the forensic relevant data reversed well enough to share and seek comments and allow for greater testing.
Tested on OS X 10.11.x
LoginItems Example
I will use LoginItems as an example, but from my testing it applies to any plist that contains alias version 3 data (sidebar items, etc.)
Assuming you have some loginitems you will have the following plist:
~/Library/Preferences/com.apple.loginitems.plist
Inside this particular plist there is an array of login items. We will look at Item 0, which in my case is Flux. You may have something different.
As you can see there is String called, Alias. The value of, which is a Data object.
The two common methods of reviewing this data is strings and hex dumps/editors. Let's look at those two options now.
Strings
Applications/Flux.app
Flux.app
OS X
Hex
With a hex editor we get:
Applications/Flux.app
OS X
Reference to H+
So with strings and a hex edited simply looking at the output doesn't give us that much really.
Better Way
The better way to obtain this information would be to reverse engineer the file type and figure out what is really inside.
Reversing Alias v3
Here is what the Alias v3 looks like after I reversed it and created a Synalyze It! template for parsing it. You can download the template in the, Play Time section below.
- VolumeCheckedDate- This matched up to the Volume Check Date timestamp in some testing. It was different in other testing. More testing needs to be done on this timestamp, but so far that's how it has matched up (see note below).
- Filesystem - Filesystem of the volume where the file/folder exists.
- Parent CNID - This points to the parent folder of the file/folder. In this example the parent CNID represents Applications
- Target CNID - This is the CNID of the target file/folder. In this case, it's the Flux.app
- File or Folder Creation Date - This is the creation date of the file (Flux.app). Keep in mind how timestamps are preserved across different/like filesystems.
- NameKey - The name of the file (Flux.app)
- VolName - Name of the volume where the file is (OSX)
- PathName - Path (Applications/Flux.app)
According to TN-1150 the volume header's checkedDate is, The date and time when the volume was last checked for consistency. Disk checking tools, such as Disk First Aid, must set this when they perform a disk check. A disk checking tool may use this date to perform periodic checking of a volume.
NOTE: The Volume Checked Date needs more testing. It can be inconsistent at times, so it shouldn't be relied upon 100%. I need more testing sample data, which is why I am releasing this 90% complete vs. 100%. I only have a couple Mac VMs for testing.
Automation
I wrote some Python code to parse this data from within a plist. You will need to run it on a Mac.
This is just proof of concept code. You can import aliasv3_struct.py as such:
from aliasv3_struct import AliasV3Parser
It will return the following that you can sift through and print however you want.
return(cTime, vol_cTime, vol_fs_type, target_type, target_name, target_path, parent_cnid, target_cnid, ' '.join(cnids))
You can run the code as such:
aliasv3.py -f ~/Library/Preferences/com.apple.loginitems.plist
And here is some simple output.
2016-07-04 02:09:28,2015-10-02 07:23:53,H+,Folder,Flux.app,/OSX/Applications/Flux.app,78,727882
Summary
Make sure to validate my findings. Like anything else, there is likely room for improvement or modifications of the interpreted data, etc. It would be helpful if you could extract your volume header and provide the plists I discussed here. That will help with testing as I have limited samples.
Aliases it seems are being replaced by bookmarks, but they are still on newer Mac systems so it's worth knowing the structure of them. I've also reverse engineered the file format for bookmark data, but I haven't gotten around to documenting it. It's still in my head. I will try doing that over the next couple weeks. It's much more robust/complex.
Play Time
If you want to play around with the sample files in this blog you can download:
You can also find Alias data within your array of sidebar items.
~/Library/Preferences/com.apple.sidebarlists.plist
I've attached a couple examples for my Mac VM here - Network and here - VMware.
Enjoy!