Combine AWS SSM modules, autodetect platform

This commit is contained in:
Spencer McIntyre 2023-04-18 16:41:48 -04:00 committed by RageLtMan
parent 59b3c0e945
commit 2e3a2b6f6d
6 changed files with 31 additions and 91 deletions

View File

@ -23,6 +23,23 @@ module Msf::Sessions
#
include Msf::Session::Provider::SingleCommandShell
def initialize(conn, opts=nil)
super
if opts && (ssm_peer_info = opts.fetch(:aws_ssm_host_info))
case ssm_peer_info['PlatformType']
when 'Linux'
@platform = 'linux'
when 'MacOS'
@platform = 'osx'
when 'Windows'
@platform = 'win'
end
@info = "AWS SSM #{ssm_peer_info['ResourceType']} (#{ssm_peer_info['InstanceId']})"
end
end
##
#
# Returns the session description.
@ -30,19 +47,5 @@ module Msf::Sessions
def desc
'AWS SSM command shell'
end
##
# Intercept point from Msf::Sessions::CommandShell#shell_read
##
def shell_read(length=-1, timeout=1)
super(length, timeout)
end
##
# Intercept point from Msf::Sessions::CommandShell#shell_write
##
def shell_write(buf)
super(buf)
end
end
end

View File

@ -130,7 +130,7 @@ Shell Banner:
end
# Only populate +session.info+ with a captured banner if the shell is responsive and verified
session.info = session_info
session.info = session_info if session.info.blank?
session
else
# Encrypted shells need all information read before anything is written, so we read in the banner here. However we

View File

@ -238,7 +238,7 @@ module BindAwsSsm
end
break if ssm_client
# Wait a second before trying again
# Wait a half-second before trying again
Rex::ThreadSafe.sleep(0.5)
end
@ -284,7 +284,8 @@ module BindAwsSsm
elog('Exception raised from BindAwsSsm.handle_connection', error: e)
end
self.listener_pairs[datastore['EC2_ID']] = chan
handle_connection(chan.lsock, { datastore: datastore })
handle_connection(chan.lsock, { datastore: datastore, aws_ssm_host_info: peer_info })
end
else
wlog('No connection received before the handler completed')
@ -368,7 +369,6 @@ private
# notify any waiters we may have.
if s
register_session(s)
s.info = "AWS SSM #{datastore['ACCESS_KEY_ID']} (#{datastore['EC2_ID']})"
end
return s

View File

@ -110,13 +110,9 @@ class MetasploitModule < Msf::Auxiliary
next unless datastore['CreateSession']
socket = get_ssm_socket(client, ssm_host['InstanceId'])
if ssm_host['PlatformType'].casecmp?('Windows')
sess = Msf::Sessions::CommandShellWindows.new(socket.lsock)
else
sess = Msf::Sessions::CommandShellUnix.new(socket.lsock)
end
sess = Msf::Sessions::AwsSsmCommandShellBind.new(socket.lsock, { datastore: datastore, aws_ssm_host_info: ssm_host })
start_session(self, "AWS SSM #{datastore['ACCESS_KEY_ID']} (#{ssm_host['InstanceId']})", datastore, false, socket.lsock, sess)
start_session(self, sess.info, datastore, false, socket.lsock, sess)
end
rescue Seahorse::Client::NetworkingError => e
print_error e.message

View File

@ -1,48 +0,0 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
module MetasploitModule
CachedSize = 70
include Msf::Payload::Single
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
super(
merge_info(
info,
'Name' => 'Windows Command Shell, Bind SSM (via AWS API)',
'Description' => 'Creates an interactive shell using AWS SSM',
'Author' => 'RageLtMan <rageltman[at]sempervictus>',
'License' => MSF_LICENSE,
'Platform' => 'windows',
'Arch' => ARCH_CMD,
'Handler' => Msf::Handler::BindAwsSsm,
'Session' => Msf::Sessions::CommandShellWindows,
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic',
'Payload' => {
'Offsets' => {},
'Payload' => ''
}
)
)
end
#
# Constructs the payload
#
def generate(_opts = {})
vprint_good(command_string)
return super + command_string
end
#
# Returns the command string to use for execution
#
def command_string
''
end
end

View File

@ -4,7 +4,7 @@
##
module MetasploitModule
CachedSize = 70
CachedSize = 0
include Msf::Payload::Single
include Msf::Sessions::CommandShellOptions
@ -13,16 +13,14 @@ module MetasploitModule
super(
merge_info(
info,
'Name' => 'Unix Command Shell, Bind SSM (via AWS API)',
'Name' => 'Command Shell, Bind SSM (via AWS API)',
'Description' => 'Creates an interactive shell using AWS SSM',
'Author' => 'RageLtMan <rageltman[at]sempervictus>',
'License' => MSF_LICENSE,
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Platform' => '',
'Arch' => ARCH_ALL,
'Handler' => Msf::Handler::BindAwsSsm,
'Session' => Msf::Sessions::CommandShellUnix,
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic',
'Session' => Msf::Sessions::AwsSsmCommandShellBind,
'Payload' => {
'Offsets' => {},
'Payload' => ''
@ -31,18 +29,9 @@ module MetasploitModule
)
end
#
# Constructs the payload
#
def generate(_opts = {})
vprint_good(command_string)
return super + command_string
end
def on_session(session)
super
#
# Returns the command string to use for execution
#
def command_string
''
session.arch.clear # undo the ARCH_ALL amalgamation
end
end