Add cmd_vulns search and delete operations
parent
22752518ea
commit
ecad74cf99
|
@ -242,9 +242,14 @@ module Msf::DBManager::Vuln
|
|||
end
|
||||
|
||||
::ActiveRecord::Base.connection_pool.with_connection {
|
||||
|
||||
search_term = opts.delete(:search_term)
|
||||
if search_term && !search_term.empty?
|
||||
column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Vuln, search_term)
|
||||
wspace.vulns.includes(:host).where(opts).where(column_search_conditions)
|
||||
else
|
||||
wspace.vulns.includes(:host).where(opts)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -760,7 +760,7 @@ module Msf
|
|||
print_line " -s <svc names> List vulns matching these service names"
|
||||
print_line " -R,--rhosts Set RHOSTS from the results of the search"
|
||||
print_line " -S,--search Search string to filter by"
|
||||
print_line " -i,--info Display Vuln Info"
|
||||
print_line " -i,--info Display vuln information"
|
||||
print_line
|
||||
print_line "Examples:"
|
||||
print_line " vulns -p 1-65536 # only vulns with associated services"
|
||||
|
@ -780,6 +780,7 @@ module Msf
|
|||
show_info = false
|
||||
set_rhosts = false
|
||||
output_file = nil
|
||||
delete_count = 0
|
||||
|
||||
# Short-circuit help
|
||||
if args.delete "-h"
|
||||
|
@ -791,8 +792,8 @@ module Msf
|
|||
case arg
|
||||
#when "-a","--add"
|
||||
# mode = :add
|
||||
#when "-d"
|
||||
# mode = :delete
|
||||
when '-d','--delete' # TODO: This is currently undocumented because it's not officially supported.
|
||||
mode = :delete
|
||||
when "-h","--help"
|
||||
cmd_vulns_help
|
||||
return
|
||||
|
@ -818,7 +819,7 @@ module Msf
|
|||
when '-R', '--rhosts'
|
||||
set_rhosts = true
|
||||
when '-S', '--search'
|
||||
search_term = /#{args.shift}/nmi
|
||||
search_term = args.shift
|
||||
when '-i', '--info'
|
||||
show_info = true
|
||||
else
|
||||
|
@ -829,8 +830,9 @@ module Msf
|
|||
end
|
||||
end
|
||||
|
||||
# normalize
|
||||
# add sentinel value meaning all if empty
|
||||
host_ranges.push(nil) if host_ranges.empty?
|
||||
# normalize
|
||||
ports = port_ranges.flatten.uniq
|
||||
svcs.flatten!
|
||||
tbl = Rex::Text::Table.new(
|
||||
|
@ -838,15 +840,19 @@ module Msf
|
|||
'Columns' => ['Timestamp', 'Host', 'Name', 'References', 'Information']
|
||||
)
|
||||
|
||||
matched_vuln_ids = []
|
||||
vulns = []
|
||||
if host_ranges.compact.empty?
|
||||
vulns = framework.db.vulns({:search_term => search_term})
|
||||
else
|
||||
each_host_range_chunk(host_ranges) do |host_search|
|
||||
framework.db.hosts(framework.db.workspace, false, host_search).each do |host|
|
||||
host.vulns.each do |vuln|
|
||||
if search_term
|
||||
next unless(
|
||||
vuln.host.attribute_names.any? { |a| vuln.host[a.intern].to_s.match(search_term) } or
|
||||
vuln.attribute_names.any? { |a| vuln[a.intern].to_s.match(search_term) }
|
||||
)
|
||||
break if !host_search.nil? && host_search.empty?
|
||||
|
||||
vulns.concat(framework.db.vulns({:hosts => { :address => host_search }, :search_term => search_term }))
|
||||
end
|
||||
end
|
||||
|
||||
vulns.each do |vuln|
|
||||
reflist = vuln.refs.map {|r| r.name}
|
||||
if (vuln.service)
|
||||
# Skip this one if the user specified a port and it
|
||||
|
@ -854,44 +860,49 @@ module Msf
|
|||
next unless ports.empty? or ports.include? vuln.service.port
|
||||
# Same for service names
|
||||
next unless svcs.empty? or svcs.include?(vuln.service.name)
|
||||
|
||||
else
|
||||
# This vuln has no service, so it can't match
|
||||
next unless ports.empty? and svcs.empty?
|
||||
end
|
||||
|
||||
print_status("Time: #{vuln.created_at} Vuln: host=#{host.address} name=#{vuln.name} refs=#{reflist.join(',')} #{(show_info && vuln.info) ? "info=#{vuln.info}" : ""}")
|
||||
matched_vuln_ids << vuln.id
|
||||
|
||||
if output_file
|
||||
row = []
|
||||
row << vuln.created_at
|
||||
row << host.address
|
||||
row << vuln.host.address
|
||||
row << vuln.name
|
||||
row << reflist * ","
|
||||
if show_info && vuln.info
|
||||
row << "info=#{vuln.info}"
|
||||
row << vuln.info
|
||||
else
|
||||
row << ''
|
||||
end
|
||||
tbl << row
|
||||
end
|
||||
|
||||
if set_rhosts
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address)
|
||||
addr = (vuln.host.scope ? vuln.host.address + '%' + vuln.host.scope : vuln.host.address)
|
||||
rhosts << addr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if mode == :delete
|
||||
result = framework.db.delete_vuln(ids: matched_vuln_ids)
|
||||
delete_count = result.size
|
||||
end
|
||||
|
||||
if output_file
|
||||
File.write(output_file, tbl.to_csv)
|
||||
print_status("Wrote vulnerability information to #{output_file}")
|
||||
else
|
||||
print_line
|
||||
print_line(tbl.to_s)
|
||||
end
|
||||
|
||||
# Finally, handle the case where the user wants the resulting list
|
||||
# of hosts to go into RHOSTS.
|
||||
set_rhosts_from_addrs(rhosts.uniq) if set_rhosts
|
||||
|
||||
print_status("Deleted #{delete_count} vulnerabilities") if delete_count > 0
|
||||
end
|
||||
|
||||
def cmd_notes_help
|
||||
|
|
Loading…
Reference in New Issue