Comprehensive USB Trace Evidence - Understanding

Source

The advantage of knowing how this work is, in my opinion that under certain circumstances (System crash, lost, corrupt) we could get more data than using automated tools

USB History Dump - a tool to extract USB Trace Evidence
@ Articles -> Software Mar 18 2008, 03:05 (UTC+0)

nabiy writes: In this article I present a tool I wrote to extract trace evidence of USB thumb drive activity from the Windows Registry. This tool can be used to gather information such as the last time the thumb drive or mp3 player was connected to the machine as well as the last drive letter.
The windows Registry is the central nervous system to the windows operating system. Almost any activity that occurs on windows is going to involve the Registry and leave traces of that activity within the Registry. This is especially true when you work with aUSB Device.
Extracting trace evidence of this activity from the registry is not a new idea. Most of the method I employ is documented by Harlan Carvey in his book entitled, "Windows Forensic Analysis". As with his last book, this one is an excellent resource for anyone interested in Windows Forensics.
Let’s briefly review what happens when you plug your thumb drive into windows. First, the PnP Manager recognized the Device and installs it, probably usually using the generic windowsUSB Driver USBSTOR.SYS. Then the Windows mount manager (MountMgr.sys ) will be alerted to the device and will query the device (via IOCTL_MOUNTDEV_QUERY_UNIQUE_ID) directly to retrieve it’s unique identifying information. The mount manager then creates several registry keys that allow it to manage and map the storage volume and assign it a drive letter.
According to the USB specification, USB devices can store a serial number in the device descriptor of the device. Microsoft also requires that this serial number be unique. This serial number along with product and vendor information is part of the information that the mount manager retrieves in the process I described earlier. Using this serial number a device can be traced across machines. This data, with registry timestamps, MRU lists, AutoplayHandlers and .lnk files can all be used to build a clear timeline of events in regard toUSB activity.
Ok, that’s enough background information. Let’s move on to some actual code and the process involved in collecting this data.
The structure of USBSTOR (HKLM\SYSTEM\CurrentControlSet\Enum\USBSTOR) could be visualized as follows.

image 


USBSTOR----
|
--[ Device Key ----
| |
Each Key can have more than --[ Serial Sub Key ---
one serial subkey and each | |
serial subkey might have more | --[ Many Values
than ten values. |
--[ Serial Sub Key ---
| |
| --[ Many Values
| .
| .
| .
--[ Device Key ...
 

This registry key provides a convenient listing of all USB Storage devices that are used on the computer. Taking this visualization further I developed two structures:

struct usbInfo { /* usb structure info */
TCHAR cKeyName[MAX_KEY_LENGTH] ;
TCHAR cDeviceID[MAX_KEY_LENGTH] ;
SYSTEMTIME stStamp ; // should be creation time of first use
struct instanceInfo * instance;
} ;

struct instanceInfo { /* each instance record from registry */
TCHAR cInstanceID[MAX_KEY_LENGTH] ;
TCHAR cFriendlyName[MAX_VALUE] ;
TCHAR cDriver[MAX_VALUE] ; // Diver Key - this maches
TCHAR cParentIdPrefix[MAX_VALUE] ;
TCHAR cHardwareID[MAX_VALUE] ;
TCHAR cLastDriveLetter[MAX_VALUE_NAME] ;
SYSTEMTIME stDiskStamp ; // Last write time of instance entry
SYSTEMTIME stVolumeStamp ; // in Device Class Key {53f56307-b6bf-11d0-94f2-00a0c91efb8b}
struct instanceInfo * next ; // pointer to next instanceInfo if there is more than one
} ;

The first holds information regarding each device. cKeyName holds the Registry key of the device we are looking at.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\Disk&Ven_&Prod_USB_Flash_Memory&Rev_5.00

We use cDeviceID to hold the Device Identifier (the last part of the key: Disk&Ven_&Prod_USB_Flash_Memory&Rev_5.00) and the creation time of each DeviceID Registry key. We collect the creation times of each subkey by calling RegEnumKeyEx and converting the filetime to a usable time with FileTimeToSystemTime and SystemTimetoTzSpecificLocalTime.

if ( RegEnumKeyEx(hKey, i, cSubKeyName, &dwName, NULL, NULL, NULL, &ft ) == ERROR_SUCCESS) {
TCHAR deviceKeyName[MAX_KEY_LENGTH] = USBSTOR ;
_tcscat(deviceKeyName, TEXT("\\") ) ;
_tcscat(deviceKeyName, cSubKeyName) ;
_tcscpy( usbList[i].cDeviceID, cSubKeyName) ;
_tcsncpy( usbList[i].cKeyName, deviceKeyName, MAX_KEY_LENGTH - 1 ) ;
// collect the creation time of this key - should be when they first plugged it in
FileTimeToSystemTime( &ft, &stGMT) ;
SystemTimeToTzSpecificLocalTime(NULL, &stGMT, &stLocal);
usbList[i].stStamp.wMonth = stLocal.wMonth ;
usbList[i].stStamp.wDay = stLocal.wDay ;
usbList[i].stStamp.wYear = stLocal.wYear ;
usbList[i].stStamp.wHour = stLocal.wHour ;
usbList[i].stStamp.wMinute = stLocal.wMinute ;
usbList[i].instance = NULL ;
}

Now, every USB Device might have more than one set of instance information in the registry. This may happen due to a difference in the ParentIDPrefix of the device. The ParentIDPrefix correlates to the mountpoint that is assigned to the device. So let's say thumbdrive A was initially assigned as F:\ but then you remove it and insert thumbdrive B, which is also assigned as F:\. If you insert thumbdrive A while you still have thumbdrive B mounted as F:\ then it will be assigned another ParentIDPrefix and a new Registry Key will be created to hold that instance information.
In order to get the time that the thumb drive was last plugged into the machine we use the ParentIDPrefix and look under

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}

Here we find a list of subkeys for reach instance, similar to the one listed below:

\##?#USBSTOR#Disk&Ven_&Prod_USB_Flash_Memory&Rev_5.00#08B0877092601A5B&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}

This subkey contains the instanceID that we retrieved earlier (08B0877092601A5B&0). Using this id we know can now correlate the two registry entries. Each of these subkeys may further have a subkey named Control. If this subkey exists, then we query it in the same manner mentioned above to retrieve the time the thumbdrive was last used. If the Control Subkey does not exist we query the main subkey to retrieve an approximate time.

TCHAR cControlKeyName[MAX_PATH +1] ;
_tcscpy(cControlKeyName, cSubKeyName) ;
_tcscat(cControlKeyName, TEXT("\\Control") ) ;

if ( ( RegOpenKeyEx( hKey, cControlKeyName, 0, KEY_READ, &hControlKey) == ERROR_SUCCESS) &&
( RegQueryInfoKey(hControlKey, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, &ft ) == ERROR_SUCCESS) ) {

FileTimeToSystemTime( &ft, &stGMT) ;
SystemTimeToTzSpecificLocalTime(NULL, &stGMT, &stLocal);
current->stVolumeStamp.wMonth = stLocal.wMonth ;
current->stVolumeStamp.wDay = stLocal.wDay ;
current->stVolumeStamp.wYear = stLocal.wYear ;
current->stVolumeStamp.wHour = stLocal.wHour ;
current->stVolumeStamp.wMinute = stLocal.wMinute ;

RegCloseKey( hControlKey ) ;

} else {

FileTimeToSystemTime( &ft, &stGMT) ;
SystemTimeToTzSpecificLocalTime(NULL, &stGMT, &stLocal);
current->stVolumeStamp.wMonth = stLocal.wMonth ;
current->stVolumeStamp.wDay = stLocal.wDay ;
current->stVolumeStamp.wYear = stLocal.wYear ;
current->stVolumeStamp.wHour = stLocal.wHour ;
current->stVolumeStamp.wMinute = stLocal.wMinute ;

}

Next we want to see if we can find the last drive letter that was assigned to our thumbdrive. To do this we are going to compare our ParentIDPrefix with the Binary String that is stored in the mount manager database. If we find our ParentID listed under a mount point then we know that ourUSB Device was the last volume that was mounted at that location. With no real function to extract text from Binary data contained in the registry that i could find this code is just a little bit hackerish but it works.

// eleminate older volume's and only check for recent DosDevices
if (strncmp( (LPSTR)ValName, "\\DosDev", 7) == 0) {

// build a usable string out of the REG_BINARY data in the registry by
// skipping the white space in between each character.
if (ValType == REG_BINARY)
for (int i = 0; i < ValLen; i++, Val++)
valueString[i] = Val[i] ;

valueString[ValLen+1] = '\0' ; //append a null by to the end of our string
//as a null character isn't guaranteed

// We only want to look at removable media and ignore fixed devices
if (strncmp( valueString, "\\??\\STORAGE#RemovableMedia#", 27) == 0) {

// Now cycle through each and see if the ParentID is in valueString, if it is
// then copy ValName to lastDriveLetter
for (int i = 0; i < iSubKeyCount; i++) {

current = usbList[i].instance ;

if ( ( _tcsstr( valueString, current->cParentIdPrefix) != NULL)
&& (strlen(current->cParentIdPrefix) > 1 ) )
_tcscpy(current->cLastDriveLetter, (LPTSTR) ValName) ;
while (current->next != NULL) {
current = current->next ;
if ( ( _tcsstr( valueString, current->cParentIdPrefix) != NULL )
&& (strlen(current->cParentIdPrefix) > 1 ) )
_tcscpy(current->cLastDriveLetter, (LPTSTR)ValName) ;
}
}
// Done Cycling Through the list.
}
}

I think that pretty much explains the internals of the program. The program is run from the commandline.

PS C:\Documents and Settings\nabiy\src\usbHistory> .\usbHistory.exe

USB History Dump
by nabiy (c)2008

(1) --- USB Flash Memory USB Device

instanceID: 08B0877092601A5B&0
ParentIdPrefix: 8&2ecbeef1&0
Driver:{4D36E967-E325-11CE-BFC1-08002BE10318}\0007
Disk Stamp: 02/24/2008 16:24
Volume Stamp: 02/24/2008 16:24

(2) --- Apple iPod USB Device

instanceID: 000A2700130E6BB4&0
ParentIdPrefix: 7&1fc7763&0
Driver:{4D36E967-E325-11CE-BFC1-08002BE10318}\0009
Disk Stamp: 01/28/2008 19:37
Volume Stamp: 01/28/2008 19:37

instanceID: 000A270015C97A7A&0
ParentIdPrefix: 7&78dde2a&0
Driver: {4D36E967-E325-11CE-BFC1-08002BE10318}\0013
Disk Stamp: 02/15/2008 16:28
Volume Stamp: 02/15/2008 16:28

(3) --- Flash Drive SM_USB20 USB Device

instanceID: AA04012710221&0
ParentIdPrefix: 8&27cca69d&0
Last Mounted As: \DosDevices\H:
Driver:{4D36E967-E325-11CE-BFC1-08002BE10318}\0002
Disk Stamp: 03/02/2008 16:07
Volume Stamp: 03/02/2008 16:07


Everything is pretty self exclamatory. I've explained both the instanceID and ParentIdPrefix. If the ParentIdPrefix was found in the mount manager database the program displays most recent mount point for the thumb drive. It also pulls the time stamps from the registry for both the Disk and Volume deviceClass keys ({53f56307-b6bf-11d0-94f2-00a0c91efb8b} and {53F5630D-B6BF-11D0-94F2-00A0C91EFB8B} respectively).
Download the USB History Dump program from sourceforge.net.

Comentarios

Anónimo dijo…
Have you ever considered about including a little bit more than
just your articles? I mean, what you say is valuable and everything.
Nevertheless imagine if you added some great graphics
or videos to give your posts more, "pop"! Your content is excellent but with images and videos, this
website could certainly be one of the greatest in its niche.

Fantastic blog!

Here is my page; coffee shop
Anónimo dijo…
Thanks on your marvelous posting! I seriously
enjoyed reading it, you happen to be a great author.

I will ensure that I bookmark your blog and will come back at some point.
I want to encourage one to continue your great posts, have a nice morning!



my web site: simply click groupbuyingindia.com

Entradas más populares de este blog

Volkswagen Gol Trend 2014 - «Servicio Ahora»