Tag Archives: plug and play

USB Device Tracking with WLS and Splunk


WLS provides the option to monitor plug and play devices. When enabled, a log will be generated for each state change containing the current state and detailed device information.

Enabling Device Monitoring

If WLS is already installed, device monitoring can be enabled by changing the registry value at HKLM\Software\KCP\WLS\Config\DeviceMonitor\Enabled from 0 to 1.

EnableDeviceMonitoring

If WLS hasn’t been installed, adding (or changing) the DeviceMonitor section and setting Enabled to 1 in the initial.xml will enable this feature when WLS is installed.

<WLS>
 <Config>
  <DeviceMonitor>
   <Enabled>1</Enabled>
  </DeviceMonitor>
 </Config>
</WLS>

Reading the logs

Once device monitoring is enabled, when a device state changes, entries like the following will appear in your logs. Each entry should include at least one key/value pair that contains a product id (PID), a vendor id (VID), and a serial number as well as another key/value pair that contains the Class, SubClass, and Protocol.

Device added

Sep 18 15:15:46 [host] WLS_DeviceMonitor: LogType=”WindowsEventLog”, Caption=”USB Mass Storage Device”, ChangeType=”Added”, ClassGuid=”{36fc9e60-c465-11cf-8056-444553540000}”, CompatibleID=”USB\Class_08&SubClass_06&Prot_50″, CompatibleID1=”USB\Class_08&SubClass_06″, CompatibleID2=”USB\Class_08″, ConfigManagerErrorCode=”0″, ConfigManagerUserConfig=”False”, CreationClassName=”Win32_PnPEntity”, Description=”USB Mass Storage Device”, DeviceID=”USB\VID_1043&PID_8012604261021070038″, HardwareID=”USB\VID_1043&PID_8012&REV_0100″, HardwareID1=”USB\VID_1043&PID_8012″, Manufacturer=”Compatible USB storage device”, Name=”USB Mass Storage Device”, PNPDeviceID=”USB\VID_1043&PID_8012604261021070038″, Service=”USBSTOR”, Status=”OK”, SystemCreationClassName=”Win32_ComputerSystem”, SystemName=”[host]”, TIME_CREATED=”130240089461584098″, WLSKey=”23559″

Device removed

Sep 18 15:16:01 [host] WLS_DeviceMonitor: LogType=”WindowsEventLog”, Caption=”USB Mass Storage Device”, ChangeType=”Removed”, ClassGuid=”{36fc9e60-c465-11cf-8056-444553540000}”, CompatibleID=”USB\Class_08&SubClass_06&Prot_50″, CompatibleID1=”USB\Class_08&SubClass_06″, CompatibleID2=”USB\Class_08″, ConfigManagerErrorCode=”0″, ConfigManagerUserConfig=”False”, CreationClassName=”Win32_PnPEntity”, Description=”USB Mass Storage Device”, DeviceID=”USB\VID_1043&PID_8012604261021070038″, HardwareID=”USB\VID_1043&PID_8012&REV_0100″, HardwareID1=”USB\VID_1043&PID_8012″, Manufacturer=”Compatible USB storage device”, Name=”USB Mass Storage Device”, PNPDeviceID=”USB\VID_1043&PID_8012604261021070038″, Service=”USBSTOR”, Status=”OK”, SystemCreationClassName=”Win32_ComputerSystem”, SystemName=”[host]”, TIME_CREATED=”130240089617443014″, WLSKey=”23569″

Device error

If the device fails to load properly, the Status field will be set to Error instead of OK.

Sep 18 15:15:45 [host] WLS_DeviceMonitor: LogType=”WindowsEventLog”, Caption=”USB Mass Storage Device”, ChangeType=”Added”, ClassGuid=”{36fc9e60-c465-11cf-8056-444553540000}”, CompatibleID=”USB\Class_08&SubClass_06&Prot_50″, CompatibleID1=”USB\Class_08&SubClass_06″, CompatibleID2=”USB\Class_08″, ConfigManagerErrorCode=”0″, ConfigManagerUserConfig=”False”, CreationClassName=”Win32_PnPEntity”, Description=”USB Mass Storage Device”, DeviceID=”USB\VID_1043&PID_8012604261021070038″, HardwareID=”USB\VID_1043&PID_8012&REV_0100″, HardwareID1=”USB\VID_1043&PID_8012″, Manufacturer=”Compatible USB storage device”, Name=”USB Mass Storage Device”, PNPDeviceID=”USB\VID_1043&PID_8012604261021070038″, Service=”USBSTOR”, Status=”Error”, SystemCreationClassName=”Win32_ComputerSystem”, SystemName=”[host]”, TIME_CREATED=”130240089461584098″, WLSKey=”23558″

Add more data!

Splunk is great for combining data from multiple sources, and in this case, data will be added to decode VID, PID, Class, SubClass, and Protocol.

The best place (I’m aware of) to get VID and PID information is http://www.linux-usb.org/usb-ids.html. Download the usb.ids file, work some spreadsheet magic, and you have a nice csv file for a Splunk lookup table.

Getting the Class, SubClass, and Protocol information isn’t quite as straightforward; I started here: http://www.usb.org/developers/defined_class and generated a csv file for another Splunk lookup table. Luckily these don’t change as often as VID and PID information.

Add these csv files to Splunk by going to “Lookups” in the Splunk Manager page, then choosing “Add new” on the “Lookup table files” line.

Both lookup tables are available to download at the end of this post.

Extracting lookup data

Now that lookup tables exist, the information to lookup needs to be extracted from the source logs. I created two macros, one to extract and lookup the hardware manufacturer and model, another to extract and lookup the class, subclass, and protocol. Both macros split a single field into parts, and lookup the individual parts. I assumed that a new PID may exist for an existing VID, and that the new PID may not be in the lookup table; so a double lookup is performed and the first non-null value is returned.

Extract and lookup VID and PID

eval DeviceModelData=split(HardwareID,”\\”)
| eval USBModelData=split(mvindex(DeviceModelData,1),”&”)
| eval USBMfr=mvindex(USBModelData,0) | eval USBModel=mvindex(USBModelData,1)
| eval USBInterfaces=mvindex(USBModelData,2)
| lookup USBIDS Mfr as USBMfr Model as USBModel OUTPUT MfrName as USBMfrName ModelName as USBModelName
| lookup USBIDS Mfr as USBMfr OUTPUT MfrName as USBMfrName1
| eval USBMfrName=mvindex(coalesce(USBMfrName,USBMfrName1),0)
| eval USBMfrName=coalesce(USBMfrName,USBMfr)
| eval USBModelName=coalesce(USBModelName,USBModel)

Extract and lookup Class, SubClass, and Protocol

eval DeviceData=split(CompatibleID,”\\”)
| eval USBData=split(mvindex(DeviceData,1),”&”)
| eval USBClass=mvindex(split(mvindex(USBData,0),”_”),1)
| strcat “Class_” USBClass USBClass
| eval USBSubClass=mvindex(USBData,1)
| eval USBProtocol=mvindex(USBData,2)
| lookup USBSpec Class as USBClass SubClass as USBSubClass Protocol as USBProtocol OUTPUT ProtocolDescription as ProtocolDescription2
| lookup USBSpec Class as USBClass SubClass as USBSubClass OUTPUT SubClassDescription as SubClassDescription1,ProtocolDescription as ProtocolDescription1
| lookup USBSpec Class as USBClass OUTPUT ClassDescription,SubClassDescription,ProtocolDescription
| eval ClassDescription=mvindex(ClassDescription,0)
| eval SubClassDescription=mvindex(coalesce(SubClassDescription1,SubClassDescription),0)
| eval ProtocolDescription=coalesce(ProtocolDescription2,ProtocolDescription1,ProtocolDescription)
| strcat ClassDescription ” ” SubClassDescription ” ” ProtocolDescription FullUSBDescription

Combined Result

With all the information combined, it’s time to make a dashboard. I created one that displays each class in it’s own titled section for readability. If the lookups are able to decode the VID, PID, SubClass, and Protocol, the decode is shown, otherwise the original undecoded value is shown.

Devices

When deployed enterprise-wide, logs now exist to uniquely track any plug and play hardware across all systems and users. The PID, VID, and serial number can be used to identify new and potentially unwanted devices. Combined with a process to issue hardware from a central location, the issuer can register the device and the end-user. This reduces the noise and false positive alerts, and provides user accountability to a specific device. A word of caution, I have seen serial numbers reused, in mass.

Here are the lookup tables I’m currently using, they may be out of date. They are renamed to .xls files so WordPress would let me upload them; rename to .csv after downloading.

USBIDS
USBSpec

Have other ideas for using the data WLS provides, or data you’d like to have logged? Let me know in the comments below or via the contact form.

For more information on WLS, click “WLS Information” at the top, or here: WLS Information

If you’d like additional information about WLS, send me a note via the contact form. WLS is currently available to US entities, but does require a signed license agreement.