Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/msf/core/analyze/result.rb
Views: 11784
class Msf::Analyze::Result12attr_reader :datastore3attr_reader :host4attr_reader :invalid5attr_reader :missing6attr_reader :mod7attr_reader :required89def initialize(host:, mod:, framework:, available_creds: nil, payloads: nil, datastore: nil)10@host = host11@mod = mod12@required = []13@missing = []14@invalid = []15@datastore = datastore&.transform_keys(&:downcase) || Hash.new16@available_creds = available_creds17@wanted_payloads = payloads18@framework = framework1920determine_likely_compatibility21end2223def evaluate(with: @datastore, payloads: @wanted_payloads)24@datastore = with25@wanted_payloads = payloads2627determine_prerequisites28self29end3031# Returns state for module readiness.32#33# @return :sym the stateful result one of:34# * :READY_FOR_TEST, :REQUIRES_CRED, :REUSE_PREVIOUS_OPTIONS, :MISSING_REQUIRED_OPTION, :MISSING_PAYLOAD, :REQUIRES_SESSION, :NEEDS_TARGET_ACTION, :INVALID_OPTION, :NOT_APPLICABLE35#36# | State | Detailed Reason |37# |-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|38# | READY_FOR_TEST | Ready for Test - All required options have defaults |39# | REQUIRES_CRED | Requires DB Credentials - Required options have defaults except credential values - if db contains known credentials for required fields validation is possible |40# | REUSE_PREVIOUS_OPTIONS | Reuse Previous Options- Taken as an analysis option, process existing module runs to gather options set for same module on other hosts |41# | MISSING_REQUIRED_OPTION | Missing Required Options - Some options are not available requiring manual configuration |42# | MISSING_PAYLOAD | Missing Compatible Payload - Known host details and payload restrictions exclude all payloads |43# | REQUIRES_SESSION | Requires Session - Modules that require an existing session can cannot be executed as first entry point on targets |44# | NEEDS_TARGET_ACTION | Needs target action - Module that either start a service and need the target to respond in a way that may require user interaction. (Browser exploit, needs target reboot....) |45# | INVALID_OPTION | Options used in Result evaluation are invalid |46# | NOT_APPLICABLE | Module is not applicable to the host |47def state48if ready_for_test? || (@missing.empty? && @invalid.empty?)49:READY_FOR_TEST50# TODO: result eval can look for previous attempts to determine :REUSE_PREVIOUS_OPTIONS state51else52unless @missing.empty?53if @missing.include?(:credential)54:REQUIRES_CRED55elsif @missing.include?(:payload_match)56:MISSING_PAYLOAD57elsif @missing.include?(:session)58:REQUIRES_SESSION59elsif @missing.include?(:os_match)60:NOT_APPLICABLE61# TODO: result eval check for module stance to determine :NEEDS_TARGET_ACTION state?62else63:MISSING_REQUIRED_OPTION64end65else66:INVALID_OPTION67end68end69end7071# Returns state for module readiness.72# @return :String detailed sentence form description of result evaluation.73def description74if ready_for_test?75"ready for testing"76elsif @missing.empty? && @invalid.empty?77# TODO? confirm vuln match in this class78"has matching reference"79else80if missing_message.empty? || invalid_message.empty?81missing_message + invalid_message82else83[missing_message, invalid_message].join(', ')84end85end86end8788def match?89!@missing.include? :os_match90end9192def ready_for_test?93@prerequisites_evaluated && @missing.empty? && @invalid.empty?94end9596private9798def determine_likely_compatibility99if matches_host_os?100@datastore['rhost'] = @host.address101else102@missing << :os_match103end104105if @mod.post_auth?106unless @mod.default_cred? || has_service_cred? || has_datastore_cred?107@missing << :credential108end109end110end111112def determine_prerequisites113mod_detail = @framework.modules.create(@mod.fullname)114if mod_detail.nil?115@required << :module_not_loadable116return117end118@mod = mod_detail119120if @mod.respond_to?(:session_types) && @mod.session_types121@required << :session122123if s = @host.sessions.alive.detect { |sess| matches_session?(sess) }124@datastore['session'] = s.local_id.to_s125else126@missing << :session127end128end129130@mod.options.each_pair do |name, opt|131@required << name if opt.required? && !opt.default.nil?132end133134@datastore.each_pair do |k, v|135@mod.datastore[k] = v136end137138target_idx = @mod.respond_to?(:auto_targeted_index) ? @mod.auto_targeted_index(@host) : nil139if target_idx140@datastore['target'] = target_idx141@mod.datastore['target'] = target_idx142end143144# Must come after the target so we know we match the target we want.145# TODO: feed available payloads into target selection146if @wanted_payloads147if p = @wanted_payloads.find { |p| @mod.is_payload_compatible?(p) }148@datastore['payload'] = p149else150@missing << :payload_match151end152end153154@mod.validate155rescue Msf::OptionValidateError => e156unset_options = []157bad_options = []158159e.options.each do |opt|160if @mod.datastore[opt].nil?161unset_options << opt162else163bad_options << opt164end165end166167@missing.concat unset_options168@invalid.concat bad_options169ensure170@prerequisites_evaluated = true171end172173def matches_session?(session)174session.stype == 'meterpreter' || !!@mod.session_types&.include?(session.stype)175end176177def required_sessions_list178return "meterpreter" unless @mod.session_types&.any?179180@mod.session_types.join(' or ')181end182183def has_service_cred?184@available_creds&.any?185end186187def has_datastore_cred?188!!(@datastore['username'] && @datastore['password'])189end190191# Determines if an exploit (mod, an instantiated module) is suitable for the host (host)192# defined operating system. Returns true if the host.os isn't defined, if the module's target193# OS isn't defined, if the module's OS is "unix" and the host's OS is not "windows," or if194# the module's target is "php", "python", or "java." Or, of course, in the event the host.os195# actually matches. This is a fail-open gate; if there's a doubt, assume the module will work196# on this target.197def matches_host_os?198hos = @host.os_name&.downcase199return true if hos.nil? || hos.empty?200201set = @mod.platform.split(',').map{ |x| x.downcase }202return true if set.empty?203204# Special cases205if set.include?('unix')206# Skip archaic old HPUX bugs if we have a solid match against another OS207return false if set.include?("hpux") && mod.refname.include?("hpux") && !hos.include?("hpux")208# Skip AIX bugs if we have a solid match against another OS209return false if set.include?("aix") && mod.refname.include?("aix") && !hos.include?("aix")210# Skip IRIX bugs if we have a solid match against another OS211return false if set.include?("irix") && mod.refname.include?("irix") && !hos.include?("irix")212213return true if !hos.include?('windows')214end215216return true if set.include?("php")217return true if set.include?("python")218return true if set.include?("java")219220set.each do |mos|221return true if hos.include?(mos)222end223224false225end226227def missing_message228@missing.map do |m|229case m230when :module_not_loadable231"module not loadable"232when :os_match233"operating system does not match"234when :session, "SESSION"235"open #{required_sessions_list} session required"236when :credential237"credentials are required"238when :payload_match239"none of the requested payloads match"240when String241"option #{m.inspect} needs to be set"242end243end.uniq.join(', ')244end245246def invalid_message247@invalid.map do |o|248case o249when String250"option #{o.inspect} is currently invalid"251end252end.join(', ')253end254255=begin256# Tests for various service conditions by comparing the module's fullname (which257# is basically a pathname) to the intended target service record. The service.info258# column is tested against a regex in most/all cases and "false" is returned in the259# event of a match between an incompatible module and service fingerprint.260# TODO: fix and integrate261def exploit_filter_by_service(mod, serv)262263# Filter out Unix vs Windows exploits for SMB services264return true if (mod.fullname =~ /\/samba/ and serv.info.to_s =~ /windows/i)265return true if (mod.fullname =~ /\/windows/ and serv.info.to_s =~ /samba|unix|vxworks|qnx|netware/i)266return true if (mod.fullname =~ /\/netware/ and serv.info.to_s =~ /samba|unix|vxworks|qnx/i)267268# Filter out IIS exploits for non-Microsoft services269return true if (mod.fullname =~ /\/iis\/|\/isapi\// and (serv.info.to_s !~ /microsoft|asp/i))270271# Filter out Apache exploits for non-Apache services272return true if (mod.fullname =~ /\/apache/ and serv.info.to_s !~ /apache|ibm/i)273274false275end276=end277end278279280