SANS Digital Forensics and Incident Response Blog

USB Device Parsing Logparser Scripts

By Guest Blogger Dave Kleiman:

Recently I had a need to check a network consisting of a few hundred systems in order to identify systems that had certain USB devices attached. There was not a need to check for "deleted" registry keys or unallocated space in the registry database. I needed to collect the standard USB keys, and compare them to a list of "Friendly Names" and "Serial Numbers" provided to me.

Standard keys I collected:

\HKLM\SYSTEM\ControlSet001\Enum\USBSTOR
\HKLM\SYSTEM\ControlSet001\Enum\USB
\HKLM\SYSTEM\MountedDevices
\HKLM\SYSTEM\ControlSet001\Control\DeviceClasses\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}

Additionally, I wanted to collect the times stamps for each respective registry entry. The challenge was to do this quickly without having to traverse a building to each office and collect them direct with a standard forensic tool.

My solution, Log Parser. That is right Log Parser(r), a free tool from Microsoft (http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07) that will parse the File System, Registry, and whole lot more.

Log Parser allows for variables in scripts. I created a script for each registry key I wanted to retrieve, and added a variable so I could enter the Host name for each.

First, I told Log Parser what I wanted values I wanted to retrieve from each registry key with a SELECT statement (Note I chose select 2000 for these scripts, you can change that number to as much or as little as you see fit, in this the top 2000 entries are retrieved):

SSELECT TOP 2000
ComputerName,
Path,
KeyName,
Valuename,
ValueType,
Value,
LastWriteTime

Then I indicated the output with the INTO statement and utilized an asterisk (*) to allow it to append the variable name to each file name

INTO *-USBSTOR.csv

Finally the FROM statement tells Log Parser what key to retrieve, and the variable %NAME% allows for entry of a Hostname at the command prompt.

FROM \%NAME%\HKLM\SYSTEM\ControlSet001\Enum\USBSTOR

You can download the easy to use scripts HERE.

Unzip the package into a directory.

Drop down to a command prompt and type:

logparser file:_DeviceClasses.sql?name=HostA

logparser file:_MountedDevice.sql?name=HostA

logparser file:_USBSTOR.sql?name=HostA

logparser file:_USB.sql?name=HostA

Continue to do this for each Host, and it will return and individual CSV for each script separated by Host Name as outlined below:

HostA.network.local-DeviceClass.csv

HostA.network.local-MountedDevices.csv

HostA.network.local-USBSTOR.csv

HostA.network.local-USB.csv

I have many Log Parser scripts made for Forensics and the instructions on how to use them available on my website: http://www.computerforensicexaminer.com/computer-forensics-expert-florida-miami-palm-beach-lauderdale-dave-kleiman-forensic-training-files/

Respectfully, Dave Kleiman - http://www.ComputerForensicExaminer.com - sans@davekleiman.com

1 Comments

Posted October 5, 2009 at 3:42 PM | Permalink | Reply

Dimitrios Kapsalis

I wrote a meterpreter script which can be used to pull the USB device information from a system.
[code]
#
# This is a Meterpreter script designed to be used by the Metasploit Framework
#
# Meterpreter script for pulling forensics data from registry for any USB device
# connected to system
#
# Provided by Dimitrios Kapsalis
# Verion: 0.1
require ''fileutils'
#Function for writing data to a file
def m_filewrt(file2wrt, data2wrt)
output = ::File.open(file2wrt, "a")
data2wrt.each_line do |d|
output.puts(d)
end
output.close
end
# ====================================================================================================================================
# Checking for UAC
# ====================================================================================================================================
def m_uaccheck(session)
uac = false
winversion = session.sys.config.sysinfo
if winversion[''OS']=~ /Windows Vista/ or winversion[''OS']=~ /Windows 7/
if session.sys.config.getuid != "NT AUTHORITY\\\\SYSTEM"
begin
print_status("Checking if UAC is enabled ''..")
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, ''HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System')
if key.query_value(''Identifier') == 1
print_status("UAC is Enabled")
uac = true
end
key.close
rescue::Exception => e
print_status("Error Checking UAC: #{e.class} #{e}")
end
end
end
return uac
end
# ====================================================================================================================================
# Print message to file on target
# ====================================================================================================================================
def m_writetofile(session,file,message)
cmd = "cmd /c echo #{message} >> #{file}"
m_exec(session, cmd)
end
# ====================================================================================================================================
# Delete a file (meterpreter has no unlink API yet)
# ====================================================================================================================================
def m_unlink(session, path)
r = session.sys.process.execute("cmd.exe /c del /F /S /Q " + path, nil, {''Hidden' => ''true'})
while(r.name)
select(nil, nil, nil, 0.10)
end
r.close
end
# ====================================================================================================================================
# Exec a command and return the results
# ====================================================================================================================================
def m_exec(session, cmd)
begin
r = session.sys.process.execute(cmd, nil, {''Hidden' => true, ''Channelized' => true})
b = ""
while(d = r.channel.read)
b < e
print_status("Error Running Command #{cmd}: #{e.class} #{e}")
end
end
# ====================================================================================================================================
# Function to upload files
# ====================================================================================================================================
def m_upload(session,file)
location = session.fs.file.expand_path("%temp%")
fileontrgt = "#{location}\\\\#{rand(100)}.exe"
print_status(" ''" Uploading #{file}''.")
session.fs.file.upload_file("#{fileontrgt}","#{file}")
print_status(" ''" #{file} uploaded!")
print_status(" ''" File on target #{fileontrgt}")
return fileontrgt
end
# ====================================================================================================================================
# Function to download files
# ====================================================================================================================================
def m_download(session,src,dst)
location = session.fs.file.expand_path("%temp%")
print_status(" ''" Downloading #{src}''.")
session.fs.file.download_file("#{dst}","#{src}")
print_status(" ''" #{dst} downloaded!")
end
# ====================================================================================================================================
# Script proper
# ====================================================================================================================================
# The ''client' object holds the Meterpreter session
# Aliasing here for plugin compatibility
session = client
script_name = "installedsoftware"
# Extract the host and port
host,port = session.tunnel_peer.split('':')
print_status("New session on #{host}:#{port}''")
# Create a directory for the logs
logs = ::File.join(Msf::Config.config_directory, ''logs',script_name , host + "_" + Time.now.strftime("%Y%m%d.%M%S")+sprintf("%.5d",rand(100000)) )
# Create the log directory
::FileUtils.mkdir_p(logs)
print_status("''" Files saved to #{logs}''")
location = session.fs.file.expand_path("%temp%")
filename = "#{rand(100)}.dat"
fileontrgt = "#{location}\\\\#{filename}"
print_status("''" Data logged to #{fileontrgt}''.")
begin
#===============================================================================================================================
#===============================================================================================================================
#===============================================================================================================================
# Pull USB history Pull USB history Pull USB history Pull USB history Pull USB history Pull USB history Pull USB history
#===============================================================================================================================
#===============================================================================================================================
#===============================================================================================================================
#===========================================================================================
# Dump USB device history
#===========================================================================================
key = "HKLM\\\\SYSTEM\\\\CurrentControlSet\\\\Enum\\\\USBSTOR"
root_key, base_key = session.sys.registry.splitkey(key)
log = "#{logs}\\\\installedusb.txt"
message = ""
message