Wednesday, August 24, 2011

Jump List Analysis, pt II

I recently posted regarding Jump List Analysis, and also updated the ForensicsWiki page that Jesse K created.  Mark McKinnon has added a great list of AppIDs to the ForensicsWiki, as well.  So why am I talking about Jump Lists again?  Over two and a half years ago, I said the following in this blog:

...from a forensic perspective, this "Jump List" thing is just going to be a gold mine for an analyst...

The more I look into Jump Lists, the more convinced I am of that statement.  However, there's still a great deal that needs to be addressed regarding Jump Lists; for example, none of the tools available at this point parse the DestList streams in the automaticDestinations files (I wrote a Perl script that does this).  Also, the available tools that do parse Jump Lists, including ProDiscover, do so in a format decided upon by the developer, not by analysts.  I've heard from several folks who have stated that the process that they have to go through to find relevant information in the Jump List files is very manual and very cumbersome, and we all know how repetitive processes like this can be prone to errors.  Even though I've developed code that quickly parses either a single Jump List file (or a whole directory full of them), I haven't yet settled on an output format (beyond TLN and CSV) and how to display or present relevant information derived from the Jump List files.  That brings to this to mind...there's the issue of what is relevant to the analyst...what I want to see as part of my analysis isn't necessarily the same thing someone else would want to see.

Another issue is the application identifiers for the Jump List files.  Thanks to Mark McKinnon, a nice list of AppIDs is publicly available, but I'm sure that anyone looking at it will recognize that it's far from complete.  This is going to be a community effort to keep building the list.

This page at the WindowsTeamBlog site discusses how AppIDs are created, and strongly suggests that they're very similar to the manner in which Prefetch file hashes are created.  For example, the hash that is part of a Prefetch file name is created using the path and command line for the application; it appears from this page that a similar approach is used for AppIDs, indicating that the AppIDs can vary based on the file location and the command line used.

This page at MS talks about AppUserModelIDs; this page doesn't explicitly discuss Jump Lists, but does reference exclusion lists for Taskbar pinning and recent/frequent lists.  The page also discusses Registry keys to use for exclusion lists, as well as provides a list of applications (including rundll32.exe and mmc.exe) that are excluded from the MFU list.  What this indicates is that the automaticDestination Jump Lists are, in fact, MRU/MFU lists.

With respect to the exclusion lists discussed at the MS site, the page mentions a "Registry entry" as one means of preventing inclusion in the Start Menu MFU list, but not what kind of entry; i.e., key or value.  Reading on, there is mention that the type of the entry can be "Reg_None" and that the data is ignored, indicating that the "entry" is a value.

These pages do provide some insight as to how Jump List analysis needs to incorporate more than just looking at the files themselves; we have to include the Registry, as well.  For example, let's say that there are indications of an application on a Windows 7 system, but no Jump List files; do we just assume that the application was never used by the user in question if there are no Jump List files in their profile?  I would suggest that, based on the pages linked to above, conclusions regarding usage and attribution could not be drawn without including Registry analysis.

Now, I'm a bit skeptical about all of this, as when parsing Jump Lists created by the Remote Desktop Client, the numbered streams include a command line entry within the LNK stream (i.e., /v:"").  However, all of the streams are contained in the same file rather than separate files.

What this means is that there's more we need to know about Jump Lists...

So, how would you use Jump Lists and the information they contain during an examination?  Well, whenever there is some question of the user's activities on the system, would be my number one thought.  I would think that attempting to determine if a user had used an application (or had not...remember, forensic analysis can be used to exonerate someone, as well) would be the primary use of Jump List analysis.  There are secondary uses, for example, such as determining when the user was active on the system, or when the system itself was active (i.e., booted and running).

I would also include parsing Jump Lists and sorting the LNK streams based on the DestList stream time stamps in a timeline; again, this might be of particular value when there was some question regarding the user's activities.

Also, limited testing has demonstrated Jump Lists persist on a system even after the application with which they are associated have been deleted and removed from the system.  I found this to be the case with iTunes 10, and others have observed similar behavior.  This behavior can prove to be invaluable during investigations, providing a significant amount of valuable information that persists long after a user has made attempts to hide their activity.

Something else to consider is this...what if the user connects a USB drive to the system, or inserts a DVD into the system, and the attached media includes files with a unique viewer application?  That viewer would not have to be installed on the system, but the user's use of the application to view the files (images, movies, etc.) would likely create a Jump List file that would persist long after the user removed the media.  This is definitely something that needs to be looked into and tested, and it also demonstrates how valuable Jump Lists could possibly be during an examination.

One of the things that many of us do during an examination is file carving.  For the most part, this is done through one of the commercial tools, or using a tool (foremost, scalpel) that looks for file headers and footers, or just the headers (and it grabs X bytes following the header).

I've taken a more targeted approach to carving.  For example, on Windows XP and 2003 systems, using blkls to extract the unallocated space from an image, I then searched for the event record magic number, and instead of grabbing X bytes from there, I followed the event record format specification and retrieved over 330 "deleted" albeit valid Event Log event records from unallocated space.  I was able to do this because I know that there's more to the record format than finding a header and grabbing X bytes following that.

I've started to take a similar look at carving Jump Lists from unallocated space, and getting anything that can be parsed is going to be a challenge.  Remember that the compound file format is referred to as a 'file system within a file', and that's exactly what it is.  The header of the file specifies the location of the directory table within the file, and for the most part, each of the streams is comprised of 64 byte sectors.  However, at a certain point, the file contains enough numbered stream entries that the DestList stream gets over 4Kb (4096 bytes) in size, and it's content is moved to 512 byte sectors.  Also, as numbered streams are added to the Jump List, the DestList stream becomes intermingled amongst the rest of the sectors in the of the things I had to do in writing my code was build lookup arrays/lists, and as the file becomes larger, the DestList stream becomes more dispersed throughout the file.

Now, consider the numbered streams.  A numbered stream that is 203 bytes in length, per the directory table, will consume four 64 byte sectors, with 53 bytes left over.  A numbered stream that is 456 bytes long will consume eight 64 byte sectors...and in neither case is there any requirement for these sectors to be contiguous.  This means that they could be dispersed within the Jump List file.  Reassembling those streams is enough of an issue without having to deal with hoping that you retrieved the correct sectors from unallocated space within the image.

Based on this, something does come to mind that would make an interesting honors or university project...carving within the Jump List file itself.  Locating deleted keys and values (as well as pulling out unallocated space) within Registry hive files has proved to be a very useful analysis technique, so maybe something of value could also be retrieved by locating and extracting unallocated space within Jump List files.  This would simply be a matter of reading the directory table and determining all of the 64- and 512-byte sectors used, and then extracting those that are currently not being used.

Alex Barnett's paper on Jump List Forensics
Mark Woan's JumpLister
Troy Larson's Forensic Examination of Windows 7 Jump Lists presentation
Mike Ahrendt's blog post on Jump Lists (3 Apr 2011)


Jimmy_Weg said...

As far as carving autodest files or streams is concerned, I'd be interested to see how and when they are deleted or purged. Troy pointed out that autodest files can contain numerous streams. I just happened to note that a stream is created even if the target file is not successfully opened. I found that when I was playing with SQLiteSpy. So, perhaps we should take care to state that a file was opened or the user attempted to open the file. That could come about, for example, in cases where the user employed the wrong app or accessed a corrupt file.

I also found that streams were created for files accessed on a USB stick within the same app. Since you mentioned portable apps, SQLiteSpy is a stand-alone. AppID=ecd26b68da14752b.

Keydet89 said...


Troy pointed out that autodest files can contain numerous streams.

The field that tracks the number of entries is 64-bits. The numbered streams don't need to be all that large (ie, length in bytes) but as you add more streams, the DestList stream gets larger.