metasploit-framework/lib/msf/core/module/search.rb

109 lines
3.6 KiB
Ruby

module Msf::Module::Search
#
# This provides a standard set of search filters for every module.
# The search terms are in the form of:
# {
# "text" => [ [ "include_term1", "include_term2", ...], [ "exclude_term1", "exclude_term2"], ... ],
# "cve" => [ [ "include_term1", "include_term2", ...], [ "exclude_term1", "exclude_term2"], ... ]
# }
#
# Returns true on no match, false on match
#
def search_filter(search_string)
return false if not search_string
search_string += " "
# Split search terms by space, but allow quoted strings
terms = search_string.split(/\"/).collect{|t| t.strip==t ? t : t.split(' ')}.flatten
terms.delete('')
# All terms are either included or excluded
res = {}
terms.each do |t|
f,v = t.split(":", 2)
if not v
v = f
f = 'text'
end
next if v.length == 0
f.downcase!
v.downcase!
res[f] ||=[ [], [] ]
if v[0,1] == "-"
next if v.length == 1
res[f][1] << v[1,v.length-1]
else
res[f][0] << v
end
end
k = res
refs = self.references.map{|x| [x.ctx_id, x.ctx_val].join("-") }
is_server = (self.respond_to?(:stance) and self.stance == "aggressive")
is_client = (self.respond_to?(:stance) and self.stance == "passive")
[0,1].each do |mode|
match = false
k.keys.each do |t|
next if k[t][mode].length == 0
k[t][mode].each do |w|
# Reset the match flag for each keyword for inclusive search
match = false if mode == 0
# Convert into a case-insensitive regex
r = Regexp.new(Regexp.escape(w), true)
case t
when 'text'
terms = [self.name, self.fullname, self.description] + refs + self.author.map{|x| x.to_s}
if self.respond_to?(:targets) and self.targets
terms = terms + self.targets.map{|x| x.name}
end
match = [t,w] if terms.any? { |x| x =~ r }
when 'name'
match = [t,w] if self.name =~ r
when 'path'
match = [t,w] if self.fullname =~ r
when 'author'
match = [t,w] if self.author.map{|x| x.to_s}.any? { |a| a =~ r }
when 'os', 'platform'
match = [t,w] if self.platform_to_s =~ r or self.arch_to_s =~ r
if not match and self.respond_to?(:targets) and self.targets
match = [t,w] if self.targets.map{|x| x.name}.any? { |t| t =~ r }
end
when 'port'
match = [t,w] if self.datastore['RPORT'].to_s =~ r
when 'type'
match = [t,w] if Msf::MODULE_TYPES.any? { |modt| w == modt and self.type == modt }
when 'app'
match = [t,w] if (w == "server" and is_server)
match = [t,w] if (w == "client" and is_client)
when 'cve'
match = [t,w] if refs.any? { |ref| ref =~ /^cve\-/i and ref =~ r }
when 'bid'
match = [t,w] if refs.any? { |ref| ref =~ /^bid\-/i and ref =~ r }
when 'osvdb'
match = [t,w] if refs.any? { |ref| ref =~ /^osvdb\-/i and ref =~ r }
when 'edb'
match = [t,w] if refs.any? { |ref| ref =~ /^edb\-/i and ref =~ r }
end
break if match
end
# Filter this module if no matches for a given keyword type
if mode == 0 and not match
return true
end
end
# Filter this module if we matched an exclusion keyword (-value)
if mode == 1 and match
return true
end
end
false
end
end