Lucene search
K

Windows Gather USB Drive History

🗓️ 21 Mar 2011 01:23:32Reported by nebulusType 
metasploit
 metasploit
🔗 www.rapid7.com👁 42 Views

This module enumerates USB drive history on a target host

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Post
  include Msf::Post::Windows::Priv

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Gather USB Drive History',
        'Description' => %q{ This module will enumerate USB Drive history on a target host.},
        'License' => MSF_LICENSE,
        'Author' => [ 'nebulus'],
        'Platform' => [ 'win' ],
        'SessionTypes' => [ 'meterpreter' ],
        'Compat' => {
          'Meterpreter' => {
            'Commands' => %w[
              stdapi_railgun_api
              stdapi_registry_open_key
            ]
          }
        }
      )
    )
  end

  # Run Method for when run command is issued
  def run
    print_status("Running module against #{sysinfo['Computer']}")
    # Cache it so as to make it just a bit faster
    isadmin = is_admin?

    # enumerate disks for potentially tying to a drive letter later
    @drives = enum_disks
    out = "\n"

    @drives.each do |u, v|
      out << sprintf("%5s\t%75s\n", v, u.gsub("\x00", ''))
    end

    print_status(out)

    usb_drive_classes = enum_subkeys('HKLM\\SYSTEM\\CurrentControlSet\\Enum\\USBSTOR')
    usb_uids_to_info = {}
    if !usb_drive_classes.nil?
      usb_drive_classes.each do |x|
        enum_subkeys(x).each do |y|
          vals = enum_values(y)
          # enumerate each USB device used on the system
          usb_uids_to_info.store(x.match(/HKLM\\SYSTEM\\CurrentControlSet\\Enum\\USBSTOR\\(.*)$/)[1], vals)
        rescue StandardError
        end
      end

      usb_uids_to_info.each do |u, v|
        guid = '##?#USBSTOR#' << u << '#' << '{53f56307-b6bf-11d0-94f2-00a0c91efb8b}'
        out = "#{v['FriendlyName']}\n" << '=' * 85 << "\n"
        if isadmin
          mace = registry_getkeylastwritetime('HKLM\\SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{53f56307-b6bf-11d0-94f2-00a0c91efb8b}\\' << guid)
          if mace
            keytime = ::Time.at(mace)
          else
            keytime = 'Unknown'
          end
          out << sprintf("%25s\t%50s\n", 'Disk lpftLastWriteTime', keytime)
        end
        if !v.key?('ParentIdPrefix')
          print_status(info_hash_to_str(out, v))
          next
        end
        guid =	'##?#STORAGE#RemoveableMedia#' << v['ParentIdPrefix'] << '&RM#' << '{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}'
        if isadmin
          mace = registry_getkeylastwritetime('HKLM\\SYSTEM\\CurrentControlSet\\Control\\DeviceClasses\\{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}\\' << guid)
          if mace
            keytime = ::Time.at(mace)
          else
            keytime = 'Unknown'
          end
          out << sprintf("%25s\t%50s\n", 'Volume lpftLastWriteTime', keytime)
        end
        print_status(info_hash_to_str(out, v))
      end
    else
      print_error('No USB devices appear to have been connected to this host.')
    end
  end

  #-------------------------------------------------------------------------------
  # Function for querying the registry key for the last write time
  #    key_str		Full string representation of the key to be queried
  #    returns		unix timestamp in relation to epoch
  def registry_getkeylastwritetime(key_str = nil)
    return nil if !key_str

    # RegQueryInfoKey - http://msdn.microsoft.com/en-us/library/ms724902%28v=vs.85%29.aspx
    # last argument is PFILETIME lpftLastWriteTime, two DWORDS

    # PFILETIME - http://msdn.microsoft.com/en-us/library/ms724284%28v=vs.85%29.aspx, two DWORDS   DWORD dwLowDateTime; DWORD dwHighDateTime;
    #   can use Rex::Proto::SMB::Utils.time_smb_to_unix to convert to unix epoch
    begin
      r, b = session.sys.registry.splitkey(key_str)
      key = session.sys.registry.open_key(r, b.to_s, KEY_READ)
      mytime = session.railgun.advapi32.RegQueryInfoKeyA(key.hkey, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 8)['lpftLastWriteTime']
      key.close
      lo, hi = mytime.unpack('V2')
      return Rex::Proto::SMB::Utils.time_smb_to_unix(hi, lo)
    rescue StandardError
      return nil
    end
  end

  #-------------------------------------------------------------------------------
  # Function to enumerate the next level of keys from the given key
  #	key_str		Full string representation of the key for which subkeys should be enumerated
  #	returns		Array of string representations of subkeys
  def enum_subkeys(key_str = nil)
    return nil if !key_str

    r, b = session.sys.registry.splitkey(key_str)
    begin
      key = session.sys.registry.open_key(r, b.to_s, KEY_READ)

      full_keys = []
      key.enum_key.each do |x|
        full_keys.push(key_str.to_s << '\\' << x.to_s)
      end

      key.close
    rescue StandardError
      return nil
    end
    return full_keys
  end

  #-------------------------------------------------------------------------------
  # Function to enumerate the values in the given key
  #	key_str		Full string representation of the key from which values should be enumerated
  #	returns		Hash of string representations of: Value.name => Value
  def enum_values(key_str = nil)
    return nil if !key_str

    r, b = session.sys.registry.splitkey(key_str.to_s)
    key = session.sys.registry.open_key(r, b.to_s, KEY_READ)
    values = {}
    key.enum_value.each do |x|
      values.store(x.name, x.query)
    end
    key.close
    return values
  end

  #--------------------------------------------------------------------------------------------------
  # Function to enumerate the disks (not volumes) mounted as contained in HKLM\System\MountedDevices
  #	returns		Hash of string representations of: assigned drive letter => UID
  def enum_disks
    r, b = session.sys.registry.splitkey('HKLM\\SYSTEM\\MountedDevices')
    key = session.sys.registry.open_key(r, b.to_s, KEY_READ)

    ret = {}

    values = key.enum_value
    values.each do |x|
      next if x.name !~ /\\DosDevices\\/

      name = x.name
      name = name.gsub('\\DosDevices\\', '')
      value = x.query
      if (value[0..0] != '\\')
        str = ''
        tmp = value.unpack('V')
        tmp.each do |x|
          str << "Disk #{x.to_s(16)} "
        end
        ret.store(str, name)
      else
        tmp = x.query
        tmp.gsub!(/\\/, '')
        tmp.gsub!(/\?/, '')
        ret.store(tmp, name)
      end
    end
    key.close
    return ret
  end

  def info_hash_to_str(str, hash)
    out = str
    out << sprintf("%25s\t%50s\n", 'Manufacturer', hash['Mfg'])

    if hash.key?('ParentIdPrefix')
      mounted_as = nil

      @drives.each do |x, y|
        # go through mounted drives and see if this volume is mounted
        next if x !~ /\#/	# truncated disk volume that doesnt apply to removable media

        tmp = x.split(/\#/)[2].gsub!(/\x00/, '')	# ParentIdPrefix will be 3rd item, trip internal \x00
        tmp.gsub!(/&RM$/i, '')		# get rid of RM on end if its there
        mounted_as = y if (tmp.downcase == hash['ParentIdPrefix'].downcase)
      end

      if mounted_as
        out << sprintf("%25s\t%50s (%5s)\n", 'ParentIdPrefix', hash['ParentIdPrefix'], mounted_as)
      else
        out << sprintf("%25s\t%50s\n", 'ParentIdPrefix', hash['ParentIdPrefix'])
      end
    end

    out << sprintf("%25s\t%50s\n", 'Class', hash['Class'])
    out << sprintf("%25s\t%50s\n", 'Driver', hash['Driver'])
    return out
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

08 Feb 2023 13:47Current
7.3High risk
Vulners AI Score7.3
42