Archive for USB Device Forensics

Amcache and USB Device Tracking

Eric Zimmerman recently posted about updates to the amcache in Windows 10.  There are numerous additions to the new amcache format, including information about application shortcuts, device containers, and more.  This post is focused on the new information concerning storage devices tracked in the amcache, specifically in the Root\InventoryDevicePnp key.

Some of the useful bits of data that can be found through analysis of the amcache include device serial numbers, descriptions (e.g. FriendlyName-like values), volume names, VID/PID data, and more.  When a USB storage device is connected to a system, multiple subkeys in the amcache are created under Root\InventoryDevicePnp.  The following four keys have been observed to be associated with a device connection:

  1. swd/wpdbusenum/_??_usbstor#disk&ven_{manufacturer}&prod_{model}&rev_{rev}#{S/N or UID}#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} (WPD class subkey)
  2. usbstor/disk&ven_{manufacturer}&prod_{model}&rev_{rev}/{S/N or UID} (diskdrive class subkey)
  3. storage/volume/_??_usbstor#disk&ven_{manufacturer}&prod_{model}&rev_{rev}#{S/N or UID}#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} (volume class subkey)
  4.  usb/vid_{VID}&pid_{PID}/{S/N or UID} (USB class subkey)

Each of these four subkeys is created under Root\InventoryDevicePnp and will hold information about a connected device, with some information duplicated across two or more of the subkeys.  The Container ID of the device is present in each of the subkeys and can be used to easily link the information from each subkey.  The Container ID is helpful in tracking a device across other artifacts on a system as well since it is present in the USBSTOR subkey, the DeviceContainers subkey, and more.  Of the four subkeys listed above, the WPD class and diskdrive class subkey appear to contain the most useful information for identifying and profiling a USB device.

WPD Class Subkey

The WPD class subkey contains information such as the manufacturer, model/description, and the volume name/label of the device. Interestingly, I’ve seen instances in my testing where the volume name of a device is populated in the WPD class subkey when it is not available in other locations that it often exists (e.g. Windows Portable Devices key in the SOFTWARE hive).  This alone makes the WPD class subkey worth checking in order to help build a more complete profile of a USB device.

WPD Class Subkey

Diskdrive Class Subkey

The diskdrive class subkey contains information such as a description of the device (e.g. TOSHIBA External 3.0 USB Device) and the device serial number. The device serial number, along with VID/PID data, can be obtained from the ParentId value as well as the name of the subkey itself.  An example of a diskdrive class subkey name is: “usbstor/disk&ven_kingston&prod_dt_101_g2&rev_1.00/001372995dddcb6185180cdb&0”.

diskdrive Class Subkey

In my testing, the LastWrite time of all four class subkeys in the InventoryDevicePnp key is the same and is updated when a device is first connected, but it also appears to be updated through events outside of device connection/disconnection.  As such, the LastWrite time of these subkeys does not appear to be a reliable indicator of a connection or disconnection event.  I’ve also found that the subkeys related to some USB devices are quickly rolled out of the InventoryDevicePnp key.  In some instances, the most recently connected USB device was deleted after a system restart.  In other cases, the subkeys remained in the InventoryDevicePnp for some time.

The amcache doesn’t store the depth of USB device information found in the SYSTEM hive or other well-known locations, but it provides an additional data point that helps to corroborate and/or supplement data harvested from other areas.  For example, the Description value of the WPD class subkey can be used to gather the volume name/label of a device that was discovered through analysis of the SYSTEM hive by using the device serial or Container ID to correlate the two data points.  This method of analysis – using multiple data points across a system – will help to build a more complete profile of connected devices as well as increase your overall confidence in your findings.

USB Device Tracking Batch Script

Last month, I wrote about utilizing the Windows 7 Event Log in USB device tracking.  In my previous post, I mentioned automating the process using Microsoft’s Log Parser, but didn’t go into much detail regarding how to do so other than a couple of Log Parser queries.  This post introduces a batch script that can be used to quickly identify USB storage devices that have been connected to and disconnected from a Windows 7 system based on information available from the Windows Event Log, specifically the Microsoft-Windows-DriverFrameworks-UserMode/Operational event log.

The Log Parser query described in my previous post identifies the connection and disconnection events associated with a given device identifier, but is limited in that it requires the user to have knowledge of the USB device identifier and must be executed for each device identifier of interest.  In many cases, an examiner will not have knowledge of the device identifier(s) that should be targeted or may be interested in a listing of connection and disconnection events within a particular time period (regardless of the device connected).  This batch script accepts a Microsoft-Windows-DriverFrameworks-UserMode/Operational event log as input and parses the connection and disconnection events associated with each unique USB device identifier, based on the connection and disconnection Event IDs described in my previous post (i.e. 2003 for connect, 2100 for disconnect).

The batch script performs three main steps:

  1. Scans the event log and generates a list of device identifiers
  2. Removes duplicate device identifiers from the list compiled in Step 1
  3. Queries the event log for connection and disconnection events associated with each unique device identifier

It may seem odd at first to remove duplicate device identifiers in Step 2, but this important step eliminates the duplicate entries that would otherwise be found in the script output and allows for quicker execution of the script (as each device identifier will be queried only once within the event log).

Example usage of evtx-usb.bat

The script output is in CSV format and may look something similar to the screenshot below.  The output includes the type of event (connect or disconnect), the device identifier, the time of the event, and the LifetimeID associated with the USB device connection session.

Sample output of evtx-usb batch script

As you can see, the screenshot above details three separate connection sessions for two different USB devices.  We know there are two separate devices because of the different device identifiers and we know there are three separate connection sessions by comparing the LifetimeID values.  For a refresher on the LifetimeID value, see my previous post.

The output of the batch script allows an examiner to easily pair connection and disconnection events using the LifetimeID value as well as quickly determine which devices may have been connected to the system at the same time by identifying different devices with the same LifetimeID.  Since the script output is in CSV format, filtering and sorting is easily accomplished using a spreadsheet editor.

Since the batch script relies on Microsoft Log Parser, you will need to download Log Parser here and ensure LogParser.exe and LogParser.dll are both in the same directory as the batch file.

The script is available for download here.

The Windows 7 Event Log and USB Device Tracking

Recently, there have been a few blog posts discussing evidence found on a system when USB devices are connected and removed (Yogesh Khatri’s blog series and Nicole Ibrahim’s blog).  I’ve been meaning to release this post for a while and Yogesh and Nicole’s posts have motivated me to do so.  Much of the conversation regarding USB device activity on a Windows system often surrounds the registry, but the Windows 7 Event Log can provide a wealth of information in addition to the registry. Utilizing the Event Log during USB device investigations has been mentioned in various other locations, including chapter 5 of Harlan Carvey’s Windows Forensics Analysis 3/E (and recently in Yogesh Khatri’s blog).  This post discusses both USB device connection and disconnection artifacts found in the Windows 7 Event Log, specifically the Microsoft-Windows-DriverFrameworks-UserMode/Operational log, and explores an interesting value that can be used to pair a device’s connection event with its associated disconnection event.

Connection Event IDs

When a USB removable storage device is connected to a Windows 7 system, a number of event records should be generated in the Microsoft-Windows-DriverFrameworks-UserMode/Operational event log.  The records include those with Event ID 2003, 2004, 2005, 2010, 2100, 2105, and more.  Some of the generated event records contain identifying information about the USB device that was connected.  For example, when viewing an event record with Event ID 2003 using the Windows Event Viewer, the event information below is displayed.

Connection Event Record

A portion of the text formatting in the screenshot above above should look familiar to most, as it contains some of the same information about a USB device that can be found in the SYSTEM hive. Importantly, the device serial number (“000ECC0100087054”) is stored in last portion of the event record’s strings section. Combined with the record’s TimeGenerated field, an examiner can derive the date and time that a USB device was connected to the machine.

Disconnection Event IDs

When a USB thumb drive is disconnected from a Windows 7 system, a few event records should be generated in the same event log as the connection events.  Records with Event ID 2100, 2102, and potentially more may be generated when a USB device is disconnected.  Variables such as whether there is another USB removable storage device still connected to the system at the time a USB device is disconnected can dictate which event records are generated and which are not.  Some records, however, appear to be more consistent.  For example, it appears that an event record with Event ID 2100 and the text “Received a Pnp or Power operation (27, 23) for device <deviceInfo>” is consistently generated when a USB removable storage device is disconnected from a system.  In addition, the same event record should contain the device’s serial number/Windows unique identifier that can be mapped to a device.  An example of some of the information available from a disconnection event record with Event ID 2100 can be seen in the screenshot below.

Disconnection Event Record

LifetimeID Value

The LifetimeID value associated with a USB device’s connection session is an interesting piece of information.  This GUID value is assigned to a UMDF (User Mode Driver Framework) host when a USB device is connected and should remain the same throughout the connection “lifetime” of the device.  In other words, an examiner should be able to match the LifetimeID written to a device’s connection event records with the LifetimeID written to the device’s disconnection event records in order to tie a particular disconnection event with its associated connection event.

This is simple enough when a single USB device is used, however, when multiple USB devices are used at once, they appear to all use the same UMDF host and are all assigned the same LifetimeID.  This means that a LifetimeID value cannot be tied to a single USB device, but it appears that it can be used to correlate device connections and disconnections on a per-session basis.

LifetimeID from Disconnection Event Record

Utilizing the LifetimeID associated with a device connection session can help in developing a timeline that, among other things, indicates the length of time a particular device was connected to the system.  In addition, the LifetimeID is useful in pairing a device’s connection event with its corresponding disconnection event.  Since there may not be the same number of connection and disconnection events (e.g. a device is removed after the system has been powered down so no disconnection events are generated), the LifetimeID can help to make sense of various connections and disconnections and correctly pair the two together for a particular device.

In addition to being used to determine the length of a USB device’s connection session via the Windows Event Log, the LifetimeID value may play an interesting and useful role in determining the time a USB device was last disconnected from the system, based on the LastWrite time of a registry subkey.  I’ll forego this discussion for now since this post is focused on event records, but will revisit this topic later.


Automating the process of identifying connection and disconnection event records can really allow the power of utilizing the Windows Event Log in USB analysis to shine. While entirely possible, it would be a tedious process to manually analyze the Windows Event Log for USB connection/disconnection events.  Microsoft Log Parser is a great tool for processing the Event Log in this manner.  Given that event records associated with a device’s connection and disconnection will contain identifying information as well as a timestamp, it’s just a matter of isolating the event records associated with connection and disconnection and parsing portions of the strings section of the record.  For example, the Log Parser query below returns all event records with Event ID 2003 (connect) or 2100 (disconnect) as long as the device serial number/Windows unique identifier (“1372995DDDCB6185180CDB&0” in this case) is contained in the Strings portion of the event record and, in the case of a disconnection event, the text “27|23” is also in the Strings portion.

logparser -i EVT -o datagrid “SELECT EventID, TimeGenerated FROM Microsoft-Windows-DriverFrameworks-UserMode-Operational.evtx WHERE (EventID=2003 AND STRINGS Like ‘%1372995DDDCB6185180CDB&0%’) OR (EventID=2100 AND STRINGS LIKE ‘%1372995DDDCB6185180CDB&0%27|23%’)”

Output of Log Parser query above

If you want to clean up the output and add a bit more information, you can use the Log Parser query below (replacing “1372995DDDCB6185180CDB&0” with the USB serial number/Windows unique identifier you’re interested in).

logparser -i EVT -o datagrid “SELECT CASE EventID WHEN 2003 THEN ‘Connect’ WHEN 2100 THEN ‘Disconnect’ END As Event, TimeGenerated as Time, ‘1372995DDDCB6185180CDB&0′ as DeviceIdentifier, EXTRACT_TOKEN(Strings,0,’|’) as LifetimeID FROM Microsoft-Windows-DriverFrameworks-UserMode-Operational.evtx WHERE (EventID=2003 AND STRINGS Like ‘%1372995DDDCB6185180CDB&0%’) OR (EventID=2100 AND STRINGS LIKE ‘%1372995DDDCB6185180CDB&0%27|23%’)”

Output of Log Parser query above

As you can see, Log Parser dramatically reduces the leg work involved in analyzing event records for USB connection and disconnection events.  Moreover, Log Parser queries can easily be incorporated into a batch script that allows the examiner to input the device serial number he or she is interested in to quickly identify the connection and disconnection events associated with the device.  The LifetimeID value can then be used match associated connection and disconnection events.

As with other event logs, event records in the Microsoft-Windows-DriverFrameworks-UserMode/Operational event log eventually roll over, leaving the examiner with a limit on how far back in time he or she can go.  However, utilizing VSCs can allow an examiner to squeeze a bit more out of this approach and ultimately build a very telling history of USB device connection and disconnection events.

Automating USB Device Identification on Mac OS X

One of the common methods examiners may use during USB analysis on Mac OS X machines (running Snow Leopard or above) is to search the kernel log for “USBMSC” entries to identify USB devices that have been connected to the machine.  BlackBag Technologies has a couple of excellent blog posts here and here describing the logging of USB device information in the kernel log.  The “USBMSC” entries appear to have been moved to the system log in Mac OS X 10.8 (as discussed in this blog post), but the information contained within each entry looks to be unchanged.  An example of the approach an examiner may take in attempting to identify USB devices that have been connected to a Macintosh computer is:

  1. Extract the kernel logs from the file system.
  2. Search the kernel logs for “USBMSC Identifier”.
  3. Extract all entries containing “USBMSC Identifier”.
  4. Format the entries to make them easier to read/sort (e.g. Excel format).
  5. Search the USB ID public repository for the vendor and product ID associated with each device.
  6. Update each extracted log entry for which the associated vendor and product ID was found within the USB ID public repository.

Correlating the vendor and product IDs with the USB ID public repository can help to associate a name with the type of device that was connected (e.g. Amazon Kindle, PNY flash drive, etc.).  This process can quickly become tiresome though, especially if there are many log entries for which you must search the USB ID repository.  An examiner performing the same small task over and over again is a good argument for automating that task.  With that in mind, I decided to write a script that would do as much of this for me as possible.  Perl seemed to be a good option to use since it’s cross-platform and great with parsing.  And after a bit of coding, testing, and tweaking, I now have a script that takes care of steps 2-6 listed above in a matter of seconds.The script is capable of parsing either a single kernel log or a directory full of kernel logs, outputting the “USBMSC” log entries in csv format. After using a regular expression to locate the “USBMSC” log entries, the script queries the USB ID public repository and attempts to correlate the vendor and product ID of each entry parsed from the kernel log(s) with a particular device listed in the repository.  The script defaults to checking the online version of the repository, but if you don’t have a network connection or want to be able to run the script without querying the online database, you can optionally pass in the path to a local copy of the online database using the “-u” parameter (the text of the file must be in the same format as the online repository).

When you’re importing the script’s csv file into Excel (or your choice of spreadsheet application), you’ll want to be sure and set the formatting of the USBMSC ID, Vendor ID, Product ID, and Device Release columns to text values in order to avoid the application interpreting the values as numbers and removing leading zeroes, etc..

I’ve only been able to test this script on kernel logs, but it should also work on the system logs from Mountain Lion as the relevant entries appear to be in the same format.  As always, feedback, suggestions, and bug reports are welcome and appreciated.

The script is available for download here.

Console view of
Snippet of output file after correlation