Adds mixin and post modules to manipulate Volume shadowcopy Service(VSS)
This commit is contained in:
parent
29b6d0d1e3
commit
dd0b07b2cc
|
@ -0,0 +1,201 @@
|
|||
require 'msf/core/post/windows/services'
|
||||
|
||||
|
||||
module Msf
|
||||
class Post
|
||||
module Windows
|
||||
|
||||
module ShadowCopy
|
||||
include Msf::Post::Windows::WindowsServices
|
||||
|
||||
|
||||
def get_vss_device(id)
|
||||
result = get_sc_param(id,'DeviceObject')
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def vss_get_ids
|
||||
result = wmicexec('shadowcopy get id')
|
||||
ids = result.scan(/\{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\}/)
|
||||
return ids
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
def get_sc_param(id,param_name)
|
||||
result = wmicexec("shadowcopy where(id=#{id}) get #{param_name}")
|
||||
result.gsub!(param_name,'')
|
||||
result.gsub!(/\s/,'')
|
||||
end
|
||||
|
||||
def vss_get_storage_param(param_name)
|
||||
result = wmicexec("shadowstorage get #{param_name}")
|
||||
result.gsub!(param_name,'')
|
||||
result.gsub!(/\s/,'')
|
||||
end
|
||||
|
||||
def vss_set_storage(bytes)
|
||||
result = wmicexec("shadowstorage set MaxSpace=\"#{bytes}\"")
|
||||
if result.include?("success")
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def create_shadowcopy(volume)
|
||||
result = wmicexec("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
|
||||
|
||||
def start_vss
|
||||
vss_state = wmicexec('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
|
||||
|
||||
def wmicexec(wmiccmd)
|
||||
tmpout = ''
|
||||
session.response_timeout=120
|
||||
begin
|
||||
tmp = session.fs.file.expand_path("%TEMP%")
|
||||
wmicfl = tmp + "\\"+ sprintf("%.5d",rand(100000))
|
||||
r = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe /append:#{wmicfl} #{wmiccmd}", nil, {'Hidden' => true})
|
||||
sleep(2)
|
||||
#Making sure that wmic finishes before executing next wmic command
|
||||
prog2check = "wmic.exe"
|
||||
found = 0
|
||||
while found == 0
|
||||
session.sys.process.get_processes().each do |x|
|
||||
found =1
|
||||
if prog2check == (x['name'].downcase)
|
||||
sleep(0.5)
|
||||
found = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
r.close
|
||||
|
||||
# Read the output file of the wmic commands
|
||||
wmioutfile = session.fs.file.new(wmicfl, "rb")
|
||||
until wmioutfile.eof?
|
||||
tmpout << wmioutfile.read
|
||||
end
|
||||
wmioutfile.close
|
||||
rescue ::Exception => e
|
||||
print_error("Error running WMIC commands: #{e.class} #{e}")
|
||||
end
|
||||
# We delete the file with the wmic command output.
|
||||
c = session.sys.process.execute("cmd.exe /c del #{wmicfl}", nil, {'Hidden' => true})
|
||||
c.close
|
||||
tmpout.gsub!(/[^[:print:]]/,'') #scrub out garbage
|
||||
return tmpout
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/windows/shadowcopy'
|
||||
require 'msf/core/post/windows/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::ShadowCopy
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Windows Manage Create Shadow Copy",
|
||||
'Description' => %q{
|
||||
This module will attempt to create a new volume shadow copy.
|
||||
This is based on the VSSOwn Script originally posted by
|
||||
Tim Tomes and Mark Baggett.
|
||||
|
||||
Works on win2k3 and later.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['windows'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Author' => ['thelightcosine <thelightcosine[at]metasploit.com']
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
OptString.new('VOLUME', [ true, 'Volume to make a copy of.', 'C:\\'])
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
unless is_admin?
|
||||
print_error("This module requires admin privs to run")
|
||||
return
|
||||
end
|
||||
unless start_vss
|
||||
return
|
||||
end
|
||||
id = create_shadowcopy(datastore['VOLUME'])
|
||||
if id
|
||||
print_good "Shadow Copy #{id} created!"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
|
@ -0,0 +1,76 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/windows/shadowcopy'
|
||||
require 'msf/core/post/windows/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::ShadowCopy
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Windows Manage List Shadow Copies",
|
||||
'Description' => %q{
|
||||
This module will attempt to list any Volume Shadow Copies
|
||||
on the system. This is based on the VSSOwn Script
|
||||
originally posted by Tim Tomes and Mark Baggett.
|
||||
|
||||
Works on win2k3 and later.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['windows'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Author' => ['thelightcosine <thelightcosine[at]metasploit.com']
|
||||
))
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
unless is_admin?
|
||||
print_error("This module requires admin privs to run")
|
||||
return
|
||||
end
|
||||
unless start_vss
|
||||
return
|
||||
end
|
||||
|
||||
list = ""
|
||||
shadow_copies = vss_list
|
||||
unless shadow_copies.empty?
|
||||
shadow_copies.each do |copy|
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Header' => 'Shadow Copy Data',
|
||||
'Indent' => 1,
|
||||
'Columns' => ['Field', 'Value']
|
||||
)
|
||||
copy.each_pair{|k,v| tbl << [k,v]}
|
||||
list << " #{tbl.to_s} \n\n"
|
||||
print_good tbl.to_s
|
||||
end
|
||||
store_loot(
|
||||
'host.shadowcopies',
|
||||
'text/plain',
|
||||
session,
|
||||
list,
|
||||
'shadowcopies.txt',
|
||||
'Shadow Copy Info'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
|
@ -0,0 +1,63 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/windows/shadowcopy'
|
||||
require 'msf/core/post/windows/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::ShadowCopy
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Windows Manage Mount Shadow Copy",
|
||||
'Description' => %q{
|
||||
This module will attempt to mount a Volume Shadow Copy
|
||||
on the system. This is based on the VSSOwn Script
|
||||
originally posted by Tim Tomes and Mark Baggett.
|
||||
|
||||
Works on win2k3 and later.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['windows'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Author' => ['thelightcosine <thelightcosine[at]metasploit.com']
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
OptString.new('DEVICE', [ true, 'DeviceObject of Shadowcopy to mount.' ]),
|
||||
OptString.new('PATH', [ true, 'Path to mount it to.' ])
|
||||
], self.class)
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
unless is_admin?
|
||||
print_error("This module requires admin privs to run")
|
||||
return
|
||||
end
|
||||
unless start_vss
|
||||
return
|
||||
end
|
||||
|
||||
r = session.sys.process.execute("cmd.exe /C mklink /D #{datastore['DEVICE']} #{datastore['PATH']}", nil, {'Hidden' => true})
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/windows/shadowcopy'
|
||||
require 'msf/core/post/windows/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::ShadowCopy
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Windows Manage Set Shadow Copy Storage Space",
|
||||
'Description' => %q{
|
||||
This module will attempt to change the ammount of space
|
||||
for volume shadow copy storage. This is based on the
|
||||
VSSOwn Script originally posted by Tim Tomes and
|
||||
Mark Baggett.
|
||||
|
||||
Works on win2k3 and later.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['windows'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Author' => ['thelightcosine <thelightcosine[at]metasploit.com']
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('SIZE', [ true, 'Size in bytes to set for Max Storage'])
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
unless is_admin?
|
||||
print_error("This module requires admin privs to run")
|
||||
return
|
||||
end
|
||||
unless start_vss
|
||||
return
|
||||
end
|
||||
if vss_set_storage(datastore['SIZE'])
|
||||
print_good("Size upated successfully")
|
||||
else
|
||||
print_error("There was a problem updating the storage size")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
|
@ -0,0 +1,73 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/post/windows/shadowcopy'
|
||||
require 'msf/core/post/windows/priv'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::ShadowCopy
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Windows Manage Get Shadow Copy Storage Info",
|
||||
'Description' => %q{
|
||||
This module will attempt to get volume shadow copy storage info.
|
||||
This is based on the VSSOwn Script originally posted by
|
||||
Tim Tomes and Mark Baggett.
|
||||
|
||||
Works on win2k3 and later.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['windows'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Author' => ['thelightcosine <thelightcosine[at]metasploit.com']
|
||||
))
|
||||
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
unless is_admin?
|
||||
print_error("This module requires admin privs to run")
|
||||
return
|
||||
end
|
||||
unless start_vss
|
||||
return
|
||||
end
|
||||
|
||||
storage_data = vss_get_storage
|
||||
if storage_data
|
||||
tbl = Rex::Ui::Text::Table.new(
|
||||
'Header' => 'Shadow Copy Storage Data',
|
||||
'Indent' => 1,
|
||||
'Columns' => ['Field', 'Value']
|
||||
)
|
||||
storage_data.each_pair{|k,v| tbl << [k,v]}
|
||||
print_good(tbl.to_s)
|
||||
store_loot(
|
||||
'host.shadowstorage',
|
||||
'text/plain',
|
||||
session,
|
||||
tbl.to_s,
|
||||
'shadowstorage.txt',
|
||||
'Shadow Copy Storage Info'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
Loading…
Reference in New Issue