Files, folders, zip files, installers that existed at one point on the system (even if deleted).

Network Shares and folders within the shares

Metadata associated with any of the above types which may include timestamps and absolute paths

True crypt volumes

There has been a lot of research done on extracting Shellbag information from registries on disk, determining the data types used for decoding certain binary registry values, and figuring out how registry values indicate relationships between other registry keys. Here are some references we used, in no particular order:

HKEY_CURRENT_USER\Software\Classes\Wow6432Node\Local Settings\Software\Microsoft\Windows\Shell\BagsHKEY_CURRENT_USER\Software\Classes\Wow6432Node\Local Settings\Software\Microsoft\Windows\Shell\BagMRU
As indicated above these keys are found in the NTUSER.DAT and UsrClass.dat hives depending on the system involved. In testing this plugin against several samples from production 64 bit systems, there were no shellbag entries recovered from the last two key entries. It is not yet apparent how to produce entries under "Wow6432Node" keys, even when conducting experiments on virtual machines invoking a 32 bit explorer on a 64 bit system. Regardless, these keys are supported in the current plugin.

Methodology
The methodology for finding Shellbag data is simple. The plugin uses the RegistryApi to find the user hives and gather the binary values from the appropriate keys and then it parses that data using Shellbag data types and outputs the data. All open user hives are processed by the plugin.

[1] The RegistryApi object is created, registries are searched for and populated.

[2] The current hive of interest is reset (this is in case this plugin is inherited by another).

[3] We set our current registry of interest to "ntuser.dat". This ensures that current actions will take place using all user's "NTUSER" registries.

[4] Since we need to parse through all entries in order to build the folder tree, we save all metadata for later processing in this array.

[5-12] Traverse through the registry keys and subkeys for NTUSER.DAT defined above.

[13] Parse each of these keys and collect the Shellbag objects.

[14-15] If Shellbag objects are collected, save the key path, registry path, key object and list of Shellbag objects for output processing. The same kind of methodology occurs for each of the UsrClass.dat registries as well, if applicable.

Data Structures
Some structures are variable length so they do not have concrete size definitions until runtime. Also some data structures vary depending on operating system. There are two main categories of Shellbag items: ITEMPOS entries and SHELLITEM entries. The ITEMPOS entries "specify locations for icons for a given desktop resolution". The SHELLITEM entries are used to describe files, folders, volumes, network shares and more. We can see the basic types for ITEMPOS and FILE_ENTRY, a SHELLITEM entry below:

Both ITEMPOS and FILE_ENTRY entries contain an ATTRIBUTES section, which contains metadata about the file. The total size is unknown until runtime, since it is dependent on the length of the filename. A definition for XP is shown below:

Example Raw Data: ITEMPOS Entries
We have seen the definitions for ITEMPOS entries, but we have not seen them in the raw. Below is a raw output of one of the Shellbag keys from one of the Honeynet Forensic Challenge samples. The "ItemPos*" values are highlighted in red and the start of ITEMPOS entries are highlighted in blue below. The data for "ItemPos*" values consists of an array of ITEMPOS entries. Each entry contains a field for the size for its data and there is also a padding section of 8 bytes in between each entry.

The parse_key() function of the Volatility plugin is where most of the hard work takes place. It has to obtain the binary Shellbag data, determine which type of data it is in order to choose the correct data type. A dictionary of all Shellbag items is yielded later in the function after all items have been processed (not shown). Here's how the function looks:

[2] Create a dictionary for storing the key value name and a list of shell items that are parsed.

[3] Collect all binary registry values from the current key.

[4-5] If there is no data collected for that value or the value is not binary skip this value. Also skip any values if the key is "Local
Settings\Software\Microsoft\Windows\Shell\Bags\<SID>_Classes" because it appears that this key may link back to itself in memory. We also want to avoid binary values associated with the value of "LastKnownState".

[6-16] If the value is an "ItemPos" value, process the Shellbag items.

Example Plugin Output
Here we can see example output from the shellbags plugin of these ITEMPOS entries. The ARC file attribute stands for "archive" and denotes files that the archive bit is set. Included in the output is the Registry from which these values were parsed, the Key from which the values came as well as its LastWrite time, the Value name of the key from which the entry came, the 8.3 File Name, MAC times and the full Unicode Name of the file. Notice how the LastWrite time of the registry is after the MAC times of the LNK files. This is because the key is updated after any changes to preferences are made or after any files/folders/etc are accessed. Therefore in normal user activities the LastWrite time should fall after the MAC times of the SHELLITEM entry:

A full list of file attributes can be seen below. They were abbreviated because there can be more than one attribute set on a file and the output can become very cluttered if the attribute names are too long.

FILE_ATTRS = {
0x00000001:"RO", #Is read-Only
0x00000002:"HID", #Is hidden
0x00000004:"SYS", #Is a system file or directory
0x00000008:"VOL", #Is a volume label
0x00000010:"DIR", #Is a directory
0x00000020:"ARC", #Should be archived
0x00000040:"DEV", #Is a device
0x00000080:"NORM", #Is normal None of the other flags should be set
0x00000100:"TEMP", #Is temporary
0x00000200:"SPARSE", #Is a sparse file
0x00000400:"RP", #Is a reparse point or symbolic link
0x00000800:"COM", #Is compressed
0x00001000:"OFFLINE", #Is offline The data of the file is stored on an offline storage.
0x00002000:"NI", #Do not index content The content of the file or directory should not be indexed by the indexing service.
0x00004000:"ENC", #Is encrypted
0x00010000:"VIR", #Is virtual
}

Example Raw Data: SHELLITEM Entries
There are other Shellbag types that must be parsed, however. These can be found in any of the previously mentioned keys. An example can be seen below. The registry value names are highlighted in red and the first part of the SHELLITEM entries (Size and Type) are highlighted in blue. We can see that the Types are all FILE_ENTRY (0x31) and more specifically, folders.

In addition to the SHELLITEM entries, another value of interest is the MRUListEx value. This shows the order in which these folders were used. This value is also parsed out by the plugin and shown in the output.

Below is part of the parse_key() function discussed earlier, which parses these SHELLITEM entries:

[20-22] Figure out what type of SHELLITEM entry it is, it if is invalid, continue.

[23] Create the appropriate SHELLITEM entry.

[24-25] If the SHELLITEM entry has a DataSize member, make sure it is large enough to be valid, if not continue.

[26] Make sure the type is in our supported types (since some SHELLITEM entry are not yet supported as of this writing).

[27-31] Get the SHELLITEM entry's full name.

[32] Save the SHELLITEM entry's full name in a dictionary indexed by registry, key and value. This ensures that we do not mix up full paths from other users and registries when we build the absolute path to the file.

[33-35] Save the SHELLITEM entry in a dictionary indexed by value and return all SHELLITEM entries found for this registry key. One thing to note: it is possible to have several different types of Shellbag entries in one registry key.

Example Output
Below we can see some output from the shellbags plugin that shows these parsed SHELLITEM entries.

We can see different types of Shellbag entries that are parsed by the plugin. Notice that for some SHELLITEM entries we can see when it was last used, since the MRUListEx value is placed in the output. We also have other attributes shown, such as MAC times for some items and absolute paths. The registry and key paths are given in the output to allow the investigator to further investigate or verify on his/her own as needed. Notice in the output, that sometimes the MAC times are not populated correctly, this may be due to corrupt or paged data in memory.

Looking at the output from the stuxnet.vmem sample we can tell from the various software listed that this is an analysis machine. We have several debuggers and malware analysis software installed. There are also different versions of Python installed. Also we can tell that this is a virtual machine, since we see that there are link files to VMWware Shared Folders which also appears as a network share.

SetRegTime
Some experiments with SetRegTime were carried out on a virtual machine to see if the LastWrite timestamps of a registry key would change on a running machine. A Shellbag key of interest was chosen and the SetRegTime application was run against the chosen registry key. The machine ran for another two minutes and then was suspended. The shellbags plugin was run. Below we can see that the SetRegTime application successfully changed the LastWrite timestamp (shown in red):

The timestamp chosen for this experiment was, of course, ludicrous so that it would stand out enough as having been changed. One thing to note is that the timestamps of the Shellbag entries should date slightly before the LastWrite timestamp of the registry key from which they came. There may be some exceptions however, where the Shellbag entry's access timestamps are not updated in the registry. For SHELLITEM entries it seems that embedded entry timestamps are not updated upon later accesses, however ITEMPOS entries do appear to update.

Regardless, the embedded timestamps should still date prior to the LastWrite timestamp. We can see an example of SHELLITEM entry timestamps not changing in the output of the stuxnet.vmem sample above for the Software\Microsoft\Windows\ShellNoRoam\BagMRU\0\0 registry key (above). An example of timestamp changes for ITEMPOS entries can be seen below:

If Shellbag entries are later added to a key whose LastWrite timestamp was stomped, the timestamp will be updated after the new Shellbag entry is added. If the Shellbag key hosts heavily used entries, like a system volume (C:\ for example), it would be difficult to ensure that the stomped LastWrite timestamp would endure regular system use. Also changes to the MruListEx or any other settings (some not covered in this post) under a Shellbag key will update the LastWrite timestamp.

Also, since we know that Shellbag entry timestamps have a somewhat predictable relationship with the LastWrite time, we may be able to use these different timestamps in order to find stomped timestamps. For example, if the LastWrite timestamp occurs prior to the Shellbag entry timestamps. In order to more correctly timestomp registry values, a tool would also have to change the timestamps of the Shellbag entries themselves or delete them. Missing common Shellbag entries would of course be suspicious and changed Shellbag entry MAC times could be checked against the file system itself or backup registry files.

Another thing to note is that changes to a Shellbag key's children can have an indirect effect on the Shellbag key itself, since accessing a child may update the MruListEx entry causing the Shellbag key's LastWrite timestamp to change as well.

We can see that the LastWrite timestamp of Software\Microsoft\Windows\ShellNoRoam\BagMRU\0\1 changed because the Temp directory was the last directory used and the MruListEx was updated. Also notice how close in proximity the highlighted timestamps are. First the C:\Temp folder is opened at 2012-09-25 15:30:15. Second the folder C:\Temp\blah is created and accessed at 2012-09-25 15:30:26. Third the key that contains the Shellbag entry for C:\Temp\blah is updated to show that this is the last folder opened (MruListEx) at 2012-09-25 15:30:38.

Another experiment was conducted to see if the child folder would have an affect on the parent folder's key if it was browsed directly. For this experiment, the C:\WINDOWS folder was browsed first to make it first on the MruListEx list. Then the run command was used to open C:\Temp\blah directly. The final result shows that navigating directly to a child folder updates the parent folder's MruListEx value and thus LastWrite time of its registry key. The child folder's LastWrite timestamp on the registry key was not modified, however, since there was no change in the MruListEx value and its MAC timestamps are not updated.

TrueCrypt Volumes
TrueCrypt volumes also appear in Shellbag entries. Aside from the actual volume name (drive letter where the volume was mounted) the volumes themselves and their contents are often found in ITEMPOS entries, for example below are entries for a TrueCrypt volume (highlighted in red and a few of its files/folders which were opened:

Since ITEMPOS entries can be updated in the registry, the TrueCrypt volume name may disappear from entries if it is deleted or moved. Experiments showed that when the TrueCrypt volume was deleted and the machine restarted, the TrueCrypt volume disappeared from the ITEMPOS entry above, but the filenames for its accessed contents remained intact:

Conclusion
Shellbags are used widely in forensic investigations and until now Shellbag information was only easily extracted from registries on disk. This plugin will now empower investigators to conduct these types of investigations on memory samples and we've shown how it may be possible to heuristically determine time-stomped registry keys based on known/expected changes to the Shellbags keys during normal activity.

Notes
There are still some types that are not yet supported, however most data is represented at this time. This plugin was created due to a discussion on the vol-users listserv. Also the associations between Shell\Bags keys and Shell\BagMRU is left on the TODO list. The plugin might take a little while to run if there are several Shellbag keys; this is because the plugin has to iterate through all keys in order to build the path tree for the full path names.

Obtaining the Plugin
Since the shellbags plugin is scheduled for the Volatility 2.3 release, it is not in the main trunk yet, nor will it be in the 2.2 release. You can, however, obtain it from the 2.3-devel branch. Instructions are here: http://code.google.com/p/volatility/wiki/VolatilityBranches.