metasploit-framework/lib/msf/core/analyze.rb

90 lines
3.3 KiB
Ruby

class Msf::Analyze
def initialize(framework)
@framework = framework
end
def host(eval_host)
suggested_modules = {}
mrefs, _mports, _mservs = Msf::Modules::Metadata::Cache.instance.all_remote_exploit_maps
unless eval_host.vulns
return {}
end
vuln_refs = []
eval_host.vulns.each do |vuln|
next if vuln.service.nil?
vuln_refs.push(*vuln.refs)
end
# finds all modules that have references matching those found on host vulns with service data
found_modules = mrefs.values_at(*(vuln_refs.map { |x| x.name.upcase } & mrefs.keys)).map { |x| x.values }.flatten.uniq
found_modules.each do |fnd_mod|
# next if exploit_filter_by_service(fnd_mod, vuln.service)
next unless exploit_matches_host_os(fnd_mod, eval_host)
end
suggested_modules[:modules] = found_modules
suggested_modules
end
private
# Tests for various service conditions by comparing the module's full_name (which
# is basically a pathname) to the intended target service record. The service.info
# column is tested against a regex in most/all cases and "false" is returned in the
# event of a match between an incompatible module and service fingerprint.
def exploit_filter_by_service(mod, serv)
# Filter out Unix vs Windows exploits for SMB services
return true if (mod.full_name =~ /\/samba/ and serv.info.to_s =~ /windows/i)
return true if (mod.full_name =~ /\/windows/ and serv.info.to_s =~ /samba|unix|vxworks|qnx|netware/i)
return true if (mod.full_name =~ /\/netware/ and serv.info.to_s =~ /samba|unix|vxworks|qnx/i)
# Filter out IIS exploits for non-Microsoft services
return true if (mod.full_name =~ /\/iis\/|\/isapi\// and (serv.info.to_s !~ /microsoft|asp/i))
# Filter out Apache exploits for non-Apache services
return true if (mod.full_name =~ /\/apache/ and serv.info.to_s !~ /apache|ibm/i)
false
end
# Determines if an exploit (mod, an instantiated module) is suitable for the host (host)
# defined operating system. Returns true if the host.os isn't defined, if the module's target
# OS isn't defined, if the module's OS is "unix" and the host's OS is not "windows," or
# if the module's target is "php." Or, of course, in the event the host.os actually matches.
# This is a fail-open gate; if there's a doubt, assume the module will work on this target.
def exploit_matches_host_os(mod, host)
hos = host.os_name
return true if hos.nil? || hos.empty?
set = mod.platform.split(',').map{ |x| x.downcase }
return true if set.empty?
# Special cases
return true if set.include?("unix") and hos !~ /windows/i
if set.include?("unix")
# Skip archaic old HPUX bugs if we have a solid match against another OS
return false if set.include?("hpux") and mod.refname.index("hpux") and hos =~ /linux|irix|solaris|aix|bsd/i
# Skip AIX bugs if we have a solid match against another OS
return false if set.include?("aix") and mod.refname.index("aix") and hos =~ /linux|irix|solaris|hpux|bsd/i
# Skip IRIX bugs if we have a solid match against another OS
return false if set.include?("irix") and mod.refname.index("irix") and hos =~ /linux|solaris|hpux|aix|bsd/i
end
return true if set.include?("php")
set.each do |mos|
return true if hos.downcase.index(mos)
end
false
end
end