# -*- coding: binary -*- require 'msf/core/post/windows/services' module Msf class Post module Windows # Based on the research from Tim Tomes and Mark Baggett, at # http://pauldotcom.com/2011/11/safely-dumping-hashes-from-liv.html module ShadowCopy include Msf::Post::Windows::Services include Msf::Post::Windows::WMIC def initialize(info = {}) super register_options([ OptInt.new("TIMEOUT", [ true, "Timeout for WMI command in seconds", 60 ]) ], self.class) end # # Get the device name for the shadow copy, which is used when accessing # files on the volume. # def get_vss_device(id) result = get_sc_param(id,'DeviceObject') end # # Returns a list of volume shadow copies. # def vss_list ids = vss_get_ids shadow_copies = [] ids.each do |id| print_status "Getting data for Shadow Copy #{id} (This may take a minute)" shadow_copies << get_sc_details("\"#{id}\"") end return shadow_copies end # # Use WMIC to get a list of volume shadow copy IDs. # def vss_get_ids result = wmic_query('shadowcopy get id') ids = result.scan(/\{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\}/) return ids end # # Get volume shadow storage parameters. # def vss_get_storage storage={} storage['AllocatedSpace'] = vss_get_storage_param('AllocatedSpace') storage['MaxSpace'] = vss_get_storage_param('MaxSpace') storage['UsedSpace'] = vss_get_storage_param('UsedSpace') return storage end # # Get detailed information about the volume shadow copy specified by +id+ # def get_sc_details(id) shadowcopy={} shadowcopy['ID'] = id shadowcopy['ClientAccessible'] = get_sc_param(id,'ClientAccessible') shadowcopy['Count'] = get_sc_param(id,'Count') shadowcopy['DeviceObject'] = get_sc_param(id,'DeviceObject') shadowcopy['Differential'] = get_sc_param(id,'Differential') shadowcopy['ExposedLocally'] = get_sc_param(id,'ExposedLocally') shadowcopy['ExposedName'] = get_sc_param(id,'ExposedName') shadowcopy['ExposedRemotely'] = get_sc_param(id,'ExposedRemotely') shadowcopy['HardwareAssisted'] = get_sc_param(id,'HardwareAssisted') shadowcopy['Imported'] = get_sc_param(id,'Imported') shadowcopy['NoAutoRelease'] = get_sc_param(id,'NoAutoRelease') shadowcopy['NotSurfaced'] = get_sc_param(id,'Notsurfaced') shadowcopy['NoWriters'] = get_sc_param(id,'NoWriters') shadowcopy['OriginiatingMachine'] = get_sc_param(id,'OriginatingMachine') shadowcopy['Persistent'] = get_sc_param(id,'Persistent') shadowcopy['Plex'] = get_sc_param(id,'Plex') shadowcopy['ProviderID'] = get_sc_param(id,'ProviderID') shadowcopy['ServiceMachine'] = get_sc_param(id,'ServiceMachine') shadowcopy['SetID'] = get_sc_param(id,'SetID') shadowcopy['State'] = get_sc_param(id,'State') shadowcopy['Transportable'] = get_sc_param(id,'Transportable') shadowcopy['VolumeName'] = get_sc_param(id,'VolumeName') return shadowcopy end # # Return the value of the +param_name+ for the volume shadow copy # specified by +id+ # def get_sc_param(id,param_name) result = wmic_query("shadowcopy where(id=#{id}) get #{param_name}") result.gsub!(param_name,'') result.gsub!(/\s/,'') end # # Return the value of the shadowstorage parameter specified by # +param_name+ # def vss_get_storage_param(param_name) result = wmic_query("shadowstorage get #{param_name}") result.gsub!(param_name,'') result.gsub!(/\s/,'') end # # Set the shadowstorage MaxSpace parameter to +bytes+ size # def vss_set_storage(bytes) result = wmic_query("shadowstorage set MaxSpace=\"#{bytes}\"") if result.include?("success") return true else return false end end # # Create a new shadow copy of the volume specified by +volume+ # def create_shadowcopy(volume) result = wmic_query("shadowcopy call create \"ClientAccessible\", \"#{volume}\"") retval = result.match(/ReturnValue = (\d)/) case retval[1].to_i when 0 print_status("ShadowCopy created successfully") sc_id = result.match(/ShadowID = ("\{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\}")/) return sc_id[1] when 1 print_error("Access Denied") when 2 print_error("Invalid Argument") when 3 print_error("Specified volume not found") when 4 print_error("Specified volume not supported") when 5 print_error("Unsupported shadow copy context") when 6 print_error("Insufficient Storage") when 7 print_error("Volume is in use") when 8 print_error("Maximum number of shadow copies reached") when 9 print_error("Another shadow copy operation is already in progress") when 10 print_error("Shadow copy provider vetoed the operation") when 11 print_error("Shadow copy provider not registered") when 12 print_error("Shadow copy provider failure") else print_error("Unknown error") end return nil end # # Start the Volume Shadow Service # def start_vss vss_state = wmic_query('Service where(name="VSS") get state') if vss_state=~ /Running/ print_status("Volume Shadow Copy service is running.") else print_status("Volume Shadow Copy service not running. Starting it now...") if service_restart("VSS", START_TYPE_MANUAL) print_good("Volume Shadow Copy started successfully.") else print_error("Insufficient Privs to start service!") return false end end unless start_swprv return false end return true end def start_swprv vss_state = wmic_query('Service where(name="swprv") get state') if vss_state=~ /Running/ print_status("Software Shadow Copy service is running.") else print_status("Software Shadow Copy service not running. Starting it now...") if service_restart("swprv", START_TYPE_MANUAL) print_good("Software Shadow Copy started successfully.") else print_error("Insufficient Privs to start service!") return false end end return true end end end end end