Module: Msf::Post::Windows::ShadowCopy

Includes:
Services, WMIC
Defined in:
lib/msf/core/post/windows/shadowcopy.rb

Overview

Based on the research from Tim Tomes and Mark Baggett, at pauldotcom.com/2011/11/safely-dumping-hashes-from-liv.html

Instance Method Summary collapse

Methods included from WMIC

#parse_wmic_result, #wmic_command, #wmic_query, #wmic_user_pass_string

Methods included from ExtAPI

#load_extapi

Methods included from File

#append_file, #cd, #directory?, #exist?, #expand_path, #file?, #file_local_digestmd5, #file_local_digestsha1, #file_local_digestsha2, #file_local_write, #file_remote_digestmd5, #file_remote_digestsha1, #file_remote_digestsha2, #file_rm, #pwd, #read_file, #rename_file, #rm_f, #upload_file, #write_file

Methods included from Services

#close_sc_manager, #open_sc_manager, #service_change_startup, #service_create, #service_delete, #service_info, #service_list, #service_start, #service_status, #service_stop

Methods included from Registry

#registry_createkey, #registry_deletekey, #registry_deleteval, #registry_enumkeys, #registry_enumvals, #registry_getvaldata, #registry_getvalinfo, #registry_loadkey, #registry_setvaldata, #registry_unloadkey

Methods included from CliParse

#win_parse_error, #win_parse_results

Instance Method Details

#create_shadowcopy(volume) ⇒ Object

Create a new shadow copy of the volume specified by volume


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 130

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

#get_sc_details(id) ⇒ Object

Get detailed information about the volume shadow copy specified by id


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 68

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

#get_sc_param(id, param_name) ⇒ Object

Return the value of the param_name for the volume shadow copy specified by id


99
100
101
102
103
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 99

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

#get_vss_device(id) ⇒ Object

Get the device name for the shadow copy, which is used when accessing files on the volume.


28
29
30
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 28

def get_vss_device(id)
  result = get_sc_param(id,'DeviceObject')
end

#initialize(info = {}) ⇒ Object


16
17
18
19
20
21
22
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 16

def initialize(info = {})
  super

  register_options([
    OptInt.new("TIMEOUT", [ true, "Timeout for WMI command in seconds", 60 ])
  ], self.class)
end

#start_vssObject

Start the Volume Shadow Service


172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 172

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...")
    begin
      ss_result = service_start("VSS")
      case ss_result
      when 0
        print_status("Volume Shadow Copy started successfully.")
      when 1
        print_error("Volume Shadow Copy already running.")
      when 2
        print_error("Volume Shadow Copy is disabled.")
        print_status("Attempting to re-enable...")
        service_change_startup("VSS","manual")
        ss_result = service_start("VSS")
        if ss_result == 0
          return true
        else
          return false
        end
      end
    rescue
      print_error("Insufficient Privs to start service!")
      return false
    end
  end
  return true
end

#vss_get_idsObject

Use WMIC to get a list of volume shadow copy IDs.


48
49
50
51
52
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 48

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

#vss_get_storageObject

Get volume shadow storage parameters.


57
58
59
60
61
62
63
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 57

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

#vss_get_storage_param(param_name) ⇒ Object

Return the value of the shadowstorage parameter specified by param_name


109
110
111
112
113
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 109

def vss_get_storage_param(param_name)
  result = wmic_query("shadowstorage get #{param_name}")
  result.gsub!(param_name,'')
  result.gsub!(/\s/,'')
end

#vss_listObject

Returns a list of volume shadow copies.


35
36
37
38
39
40
41
42
43
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 35

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

#vss_set_storage(bytes) ⇒ Object

Set the shadowstorage MaxSpace parameter to bytes size


118
119
120
121
122
123
124
125
# File 'lib/msf/core/post/windows/shadowcopy.rb', line 118

def vss_set_storage(bytes)
  result = wmic_query("shadowstorage set MaxSpace=\"#{bytes}\"")
  if result.include?("success")
    return true
  else
    return false
  end
end