From c45ae5d29123f2b0610e75e3b21423fa7aaed73b Mon Sep 17 00:00:00 2001 From: Dean Welch Date: Mon, 29 Jan 2024 13:37:23 +0000 Subject: [PATCH] Show session/rhost options separate from each other Add ability to group options for display --- lib/msf/core/opt.rb | 4 ++-- lib/msf/core/opt_base.rb | 6 +++++- lib/msf/core/opt_condition.rb | 9 ++++++--- lib/msf/core/option_group.rb | 13 +++++++++++++ lib/msf/core/optional_session.rb | 4 ++++ lib/msf/core/optional_session/smb.rb | 25 ++++++++++++++++++++----- 6 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 lib/msf/core/option_group.rb diff --git a/lib/msf/core/opt.rb b/lib/msf/core/opt.rb index 964e6dbcc5f57..bf3731721ea0c 100644 --- a/lib/msf/core/opt.rb +++ b/lib/msf/core/opt.rb @@ -44,8 +44,8 @@ def self.RHOSTS(default= nil, required=true, desc="The target host(s), see https Msf::OptRhosts.new('RHOSTS', [ required, desc, default ], aliases: [ 'RHOST' ]) end - def self.RHOST(default=nil, required=true, desc="The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html") - Msf::OptRhosts.new('RHOSTS', [ required, desc, default ], aliases: [ 'RHOST' ]) + def self.RHOST(default=nil, required=true, desc="The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html", **kwargs) + Msf::OptRhosts.new('RHOSTS', [ required, desc, default ], aliases: [ 'RHOST' ], **kwargs) end # @return [OptPort] diff --git a/lib/msf/core/opt_base.rb b/lib/msf/core/opt_base.rb index dccda5031d8bf..fb302a404c994 100644 --- a/lib/msf/core/opt_base.rb +++ b/lib/msf/core/opt_base.rb @@ -26,7 +26,7 @@ class OptBase # def initialize(in_name, attrs = [], required: false, desc: nil, default: nil, conditions: [], enums: [], regex: nil, aliases: [], max_length: nil, - fallbacks: []) + fallbacks: [], group: nil) self.name = in_name self.advanced = false self.evasion = false @@ -34,6 +34,7 @@ def initialize(in_name, attrs = [], self.max_length = max_length self.conditions = conditions self.fallbacks = fallbacks + self.group = group if attrs.is_a?(String) || attrs.length == 0 self.required = required @@ -230,6 +231,9 @@ def invalid_value_length?(value) # attr_accessor :max_length + # @return [Msf::OptionGroup, nil] The option group that this option belongs to if any + attr_accessor :group + protected attr_writer :required, :desc, :default # :nodoc: diff --git a/lib/msf/core/opt_condition.rb b/lib/msf/core/opt_condition.rb index fcfd2744a176a..bb189031b383a 100644 --- a/lib/msf/core/opt_condition.rb +++ b/lib/msf/core/opt_condition.rb @@ -3,9 +3,10 @@ module Msf module OptCondition # Check a condition's result - # @param [Msf::Module] mod The module module - # @param [Msf::OptBase] opt the option which has conditions present - # @return [String] + # @param [String] left_value The left hand side of the condition + # @param [String] operator The conditions comparison operator + # @param [String] right_value The right hand side of the condition + # @return [Boolean] def self.eval_condition(left_value, operator, right_value) case operator.to_sym when :== @@ -16,6 +17,8 @@ def self.eval_condition(left_value, operator, right_value) right_value.include?(left_value) when :nin !right_value.include?(left_value) + else + raise ArgumentError("Operator: #{operator} is invalid") end end diff --git a/lib/msf/core/option_group.rb b/lib/msf/core/option_group.rb new file mode 100644 index 0000000000000..9dd3628a26a5d --- /dev/null +++ b/lib/msf/core/option_group.rb @@ -0,0 +1,13 @@ +# -*- coding: binary -*- + +module Msf + class OptionGroup + + attr_accessor :name, :description + + def initialize(name:, description:) + self.name = name + self.description = description + end + end +end diff --git a/lib/msf/core/optional_session.rb b/lib/msf/core/optional_session.rb index 92080142fb6d7..93903b25fa58b 100644 --- a/lib/msf/core/optional_session.rb +++ b/lib/msf/core/optional_session.rb @@ -7,5 +7,9 @@ module Msf module OptionalSession include Msf::SessionCompatibility + + def session_enabled?(session_feature_name) + framework.features.enabled?(session_feature_name) + end end end diff --git a/lib/msf/core/optional_session/smb.rb b/lib/msf/core/optional_session/smb.rb index 9a1c7cc0fa97e..0b73e1f55d6cf 100644 --- a/lib/msf/core/optional_session/smb.rb +++ b/lib/msf/core/optional_session/smb.rb @@ -5,6 +5,9 @@ module OptionalSession module SMB include Msf::OptionalSession + FEATURE_NAME = Msf::FeatureManager::SMB_SESSION_TYPE + RHOST_GROUP_OPTIONS = %w[RHOSTS RPORT SMBDomain SMBUser SMBPass THREADS] + def initialize(info = {}) super( update_info( @@ -13,24 +16,36 @@ def initialize(info = {}) ) ) - - if framework.features.enabled?(Msf::FeatureManager::SMB_SESSION_TYPE) + if session_enabled? + session_group = Msf::OptionGroup.new(name: 'SESSION', description: 'Used when connecting via an existing SESSION') + rhost_group = Msf::OptionGroup.new(name: 'RHOST', description: 'Used when making a new connection via RHOSTS') register_options( [ - Msf::OptInt.new('SESSION', [ false, 'The session to run this module on' ]), + Msf::OptInt.new('SESSION', [ false, 'The session to run this module on' ], group: session_group), Msf::Opt::RHOST(nil, false), - Msf::Opt::RPORT(443, false) + Msf::Opt::RPORT(445, false), ] ) + + RHOST_GROUP_OPTIONS.each do |option_name| + if options[option_name] + options[option_name].group = rhost_group + end + end + add_info('New in Metasploit 6.4 - This module can target a %grnSESSION%clr or an %grnRHOST%clr') end end def session - return nil unless framework.features.enabled?(Msf::FeatureManager::SMB_SESSION_TYPE) + return nil unless session_enabled? super end + + def session_enabled? + super(FEATURE_NAME) + end end end end