diff --git a/lib/msf/base/serializer/readable_text.rb b/lib/msf/base/serializer/readable_text.rb index 77009aceb1..9ffb55edc1 100644 --- a/lib/msf/base/serializer/readable_text.rb +++ b/lib/msf/base/serializer/readable_text.rb @@ -1,4 +1,7 @@ # -*- coding: binary -*- + +require 'msf/core/opt_condition' + module Msf module Serializer @@ -555,6 +558,7 @@ class ReadableText mod.options.sorted.each do |name, opt| val = mod.datastore[name].nil? ? opt.default : mod.datastore[name] + next unless Msf::OptCondition.show_option(mod, opt) next if (opt.advanced?) next if (opt.evasion?) next if (missing && opt.valid?(val)) @@ -599,6 +603,7 @@ class ReadableText mod.options.sorted.each do |name, opt| next unless opt.advanced? + next unless Msf::OptCondition.show_option(mod, opt) val = mod.datastore[name].nil? ? opt.default : mod.datastore[name] tbl << [ name, opt.display_value(val), opt.required? ? "yes" : "no", opt.desc ] end diff --git a/lib/msf/core/exploit/cmdstager.rb b/lib/msf/core/exploit/cmdstager.rb index 9399a9809b..f770691e57 100644 --- a/lib/msf/core/exploit/cmdstager.rb +++ b/lib/msf/core/exploit/cmdstager.rb @@ -55,6 +55,13 @@ module Exploit::CmdStager flavors = STAGERS.keys if flavors.empty? flavors.unshift('auto') + server_conditions = ['CMDSTAGER::FLAVOR', 'in', %w{certutil tftp wget curl fetch lwprequest psh_invokewebrequest}] + register_options( + [ + OptAddressLocal.new('SRVHOST', [true, 'The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.', '0.0.0.0' ], conditions: server_conditions), + OptPort.new('SRVPORT', [true, "The local port to listen on.", 8080], conditions: server_conditions) + ]) + register_advanced_options( [ OptEnum.new('CMDSTAGER::FLAVOR', [false, 'The CMD Stager to use.', 'auto', flavors]), diff --git a/lib/msf/core/opt_base.rb b/lib/msf/core/opt_base.rb index 063b0c6bf0..075996b651 100644 --- a/lib/msf/core/opt_base.rb +++ b/lib/msf/core/opt_base.rb @@ -26,12 +26,13 @@ module Msf # also be a string as standin for the required description field. # def initialize(in_name, attrs = [], - required: false, desc: nil, default: nil, enums: [], regex: nil, aliases: [], max_length: nil) + required: false, desc: nil, default: nil, conditions: [], enums: [], regex: nil, aliases: [], max_length: nil) self.name = in_name self.advanced = false self.evasion = false self.aliases = aliases self.max_length = max_length + self.conditions = conditions if attrs.is_a?(String) || attrs.length == 0 self.required = required @@ -59,7 +60,7 @@ module Msf unless max_length.nil? self.desc += " Max parameter length: #{max_length} characters" end - + if regex_temp # convert to string regex_temp = regex_temp.to_s if regex_temp.is_a? Regexp @@ -190,6 +191,10 @@ module Msf # attr_accessor :owner # + # The list of potential conditions + # + attr_accessor :conditions + # # The list of potential valid values # attr_accessor :enums @@ -201,11 +206,11 @@ module Msf # Aliases for this option for backward compatibility # attr_accessor :aliases - # + # # The max length of the input value # attr_accessor :max_length - + protected attr_writer :required, :desc, :default # :nodoc: diff --git a/lib/msf/core/opt_bool.rb b/lib/msf/core/opt_bool.rb index cdee151f2e..bbe8241bfd 100644 --- a/lib/msf/core/opt_bool.rb +++ b/lib/msf/core/opt_bool.rb @@ -8,7 +8,7 @@ module Msf # This overrides default from 'nil' to 'false' def initialize(in_name, attrs = [], - required: true, desc: nil, default: false, aliases: []) + default: false, **kwargs) super end diff --git a/lib/msf/core/opt_condition.rb b/lib/msf/core/opt_condition.rb new file mode 100644 index 0000000000..2dbbaca3f7 --- /dev/null +++ b/lib/msf/core/opt_condition.rb @@ -0,0 +1,39 @@ +# -*- coding: binary -*- +module Msf + module OptCondition + + # Check a condition's result + def self.eval_condition(left_value, operator, right_value) + case operator.to_sym + when :== + right_value == left_value + when :!= + right_value != left_value + when :in + right_value.include?(left_value) + when :nin + !right_value.include?(left_value) + end + end + + # Check an OPTION conditions. This function supports + # dump_options() + def self.show_option(mod, opt) + return true if opt.conditions.empty? + + left_source = opt.conditions[0] + operator = opt.conditions[1] + right_value = opt.conditions[2] + if left_source == 'ACTION' + left_value = mod.action.name.to_s + elsif left_source == 'TARGET' + left_value = mod.target.name.to_s + else + left_value = mod.datastore[left_source] || opt.default + end + + eval_condition(left_value, operator, right_value) + end + + end +end diff --git a/lib/msf/core/opt_enum.rb b/lib/msf/core/opt_enum.rb index 4f830ee411..dc0ca0347c 100644 --- a/lib/msf/core/opt_enum.rb +++ b/lib/msf/core/opt_enum.rb @@ -13,7 +13,7 @@ module Msf # This overrides required default from 'false' to 'true' def initialize(in_name, attrs = [], - required: true, desc: nil, default: nil, enums: [], aliases: []) + required: true, **kwargs) super end