Skip to content
Permalink
Browse files

Land #11340, make SSH agent and other options configurable

  • Loading branch information...
busterb committed Jun 7, 2019
2 parents da6a225 + b020e32 commit 3f5f48a3fc102321938499f924670bb059a3dc05
@@ -1,18 +1,27 @@
module Msf::Exploit::Remote::SSH
# -*- coding: binary -*-

# Require most things so that modules using this will "just work"
require 'net/ssh'
require 'net/ssh/command_stream'
require 'rex/socket/ssh_factory'
require 'msf/core/exploit/ssh/auth_methods'
# Require most things so that modules using this will "just work"
require 'net/ssh'
require 'net/ssh/command_stream'
require 'rex/socket/ssh_factory'
require 'msf/core/exploit/ssh/options'
require 'msf/core/exploit/ssh/auth_methods'

def ssh_socket_factory
Rex::Socket::SSHFactory.new(framework, self, datastore['Proxies'])
end
module Msf::Exploit::Remote::SSH

# Finally patch in our custom auth methods:
# Register SSH datastore options:
# SSH_IDENT (TODO: Refactor to SSHIdent)
# SSH_TIMEOUT (TODO: Refactor to SSHTimeout)
# SSH_DEBUG (TODO: Refactor to SSHDebug)
include Msf::Exploit::Remote::SSH::Options

# Patch in our custom auth methods:
# malformed-packet
# fortinet-backdoor
include Msf::Exploit::Remote::SSH::AuthMethods

def ssh_socket_factory
Rex::Socket::SSHFactory.new(framework, self, datastore['Proxies'])
end

end
@@ -1,3 +1,5 @@
# -*- coding: binary -*-

module Msf::Exploit::Remote::SSH::AuthMethods

#
@@ -0,0 +1,56 @@
# -*- coding: binary -*-

require 'net/ssh'

# Include this mixin if you want just the SSH datastore options
# (e.g., when using Metasploit::Framework::LoginScanner::SSH)
module Msf::Exploit::Remote::SSH
module Options

def initialize(info = {})
# HACK: Suppress already initialized constant warning
verbose, $VERBOSE = $VERBOSE, nil

super

register_advanced_options([
# See Msf::Ui::Console::Driver#on_variable_set
Msf::OptString.new(
'SSH_IDENT',
[
true,
'SSH client identification string',
'SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3' # Ubuntu 18.04 LTS
]
),
# Ugh, why weren't these advanced options CamelCase?
Msf::OptInt.new(
'SSH_TIMEOUT',
[
false,
'Maximum SSH negotiation/authentication time in seconds',
10
]
),
Msf::OptBool.new(
'SSH_DEBUG',
[
false,
'Enable output of SSH protocol debugging information',
false
]
)
])

# HACK: Bypass dynamic constant assignment error
::Net::SSH::Transport::ServerVersion.const_set(
:PROTO_VERSION,
datastore['SSH_IDENT']
)
ensure
# Restore warning
$VERBOSE = verbose
end

end
end
@@ -404,23 +404,24 @@ def on_startup(opts = {})
#
def on_variable_set(glob, var, val)
case var.downcase
when "payload"

if (framework and framework.payloads.valid?(val) == false)
return false
elsif active_module && active_module.type == 'exploit' && !active_module.is_payload_compatible?(val)
return false
elsif (active_module)
active_module.datastore.clear_non_user_defined
elsif (framework)
framework.datastore.clear_non_user_defined
end
when "sessionlogging"
handle_session_logging(val) if (glob)
when "consolelogging"
handle_console_logging(val) if (glob)
when "loglevel"
handle_loglevel(val) if (glob)
when 'payload'
if framework && !framework.payloads.valid?(val)
return false
elsif active_module && active_module.type == 'exploit' && !active_module.is_payload_compatible?(val)
return false
elsif active_module
active_module.datastore.clear_non_user_defined
elsif framework
framework.datastore.clear_non_user_defined
end
when 'sessionlogging'
handle_session_logging(val) if glob
when 'consolelogging'
handle_console_logging(val) if glob
when 'loglevel'
handle_loglevel(val) if glob
when 'ssh_ident'
handle_ssh_ident(val)
end
end

@@ -430,12 +431,12 @@ def on_variable_set(glob, var, val)
#
def on_variable_unset(glob, var)
case var.downcase
when "sessionlogging"
handle_session_logging('0') if (glob)
when "consolelogging"
handle_console_logging('0') if (glob)
when "loglevel"
handle_loglevel(nil) if (glob)
when 'sessionlogging'
handle_session_logging('0') if glob
when 'consolelogging'
handle_console_logging('0') if glob
when 'loglevel'
handle_loglevel(nil) if glob
end
end

@@ -575,6 +576,34 @@ def handle_loglevel(val)
set_log_level(Msf::LogSource, val)
end

#
# This method monkeypatches Net::SSH's client identification string
#
# TODO: Move this out of the console driver!
#
def handle_ssh_ident(val)
# HACK: Suppress already initialized constant warning
verbose, $VERBOSE = $VERBOSE, nil

return false unless val.is_a?(String) && !val.empty?

require 'net/ssh'

# HACK: Bypass dynamic constant assignment error
::Net::SSH::Transport::ServerVersion.const_set(:PROTO_VERSION, val)

true
rescue LoadError
print_error('Net::SSH could not be loaded')
false
rescue NameError
print_error('Invalid constant Net::SSH::Transport::ServerVersion::PROTO_VERSION')
false
ensure
# Restore warning
$VERBOSE = verbose
end

# Require the appropriate readline library based on the user's preference.
#
# @return [void]
@@ -11,6 +11,7 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::SSH::Options

DEFAULT_USERNAME = 'karaf'
DEFAULT_PASSWORD = 'karaf'
@@ -12,8 +12,8 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Report
include Msf::Auxiliary::CommandShell

include Msf::Auxiliary::Scanner
include Msf::Exploit::Remote::SSH::Options

def initialize
super(
@@ -13,8 +13,8 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Report
include Msf::Auxiliary::CommandShell

include Msf::Auxiliary::Scanner
include Msf::Exploit::Remote::SSH::Options

attr_accessor :ssh_socket, :good_key

@@ -245,6 +245,5 @@ def read_key(filename)
@cache[filename] ||= Net::SSH::KeyFactory.load_data_private_key(File.read(key_path), password, false, key_path).to_s
@cache[filename]
end

end
end

0 comments on commit 3f5f48a

Please sign in to comment.
You can’t perform that action at this time.