Overhaul the nexpose vuln importer to be a little more friendly to all the XML data we can gather about vulns, beyond just their ID and references.

git-svn-id: file:///home/svn/framework3/trunk@12182 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Tod Beardsley 2011-03-29 22:22:58 +00:00
parent 9594829357
commit e1499657c9
1 changed files with 28 additions and 20 deletions

View File

@ -924,7 +924,7 @@ class DBManager
host = get_host(:workspace => wspace, :address => addr)
end
if info
if info and name !~ /^NEXPOSE-/
vuln = host.vulns.find_or_initialize_by_name_and_info(name, info, :include => :refs)
else
vuln = host.vulns.find_or_initialize_by_name(name, :include => :refs)
@ -3058,14 +3058,14 @@ class DBManager
REXML::Document.parse_stream(data, parser)
vuln_refs = nexpose_refs_to_hash(vulns)
vuln_refs = nexpose_refs_to_struct(vulns)
hosts.each do |host|
if bl.include? host["addr"]
next
else
yield(:address,host["addr"]) if block
end
nexpose_host(host, vuln_refs, wspace)
nexpose_host_from_rawxml(host, vuln_refs, wspace)
end
end
@ -3076,35 +3076,40 @@ class DBManager
# {"id"=>"winreg-notes-protocol-handler", severity="8", "refs"=>[{"source"=>"BID", "value"=>"10600"}, ...]}
# {"id"=>"windows-zotob-c", severity="8", "refs"=>[{"source"=>"BID", "value"=>"14513"}, ...]}
# ]
# and transforms it into a hash of vuln references keyed on vuln id, like:
# { "windows-zotob-c" => [{"source"=>"BID", "value"=>"14513"}, ...] }
# and transforms it into a struct, containing :id, :refs, :title, and :severity
#
# This method ignores all attributes other than the vuln's NeXpose ID and
# references (including title, severity, et cetera).
#
def nexpose_refs_to_hash(vulns)
refs = {}
# Other attributes can be added later, as needed.
def nexpose_refs_to_struct(vulns)
ret = []
vulns.each do |vuln|
next if ret.map {|v| v.id}.include? vuln["id"]
vstruct = Struct.new(:id, :refs, :title, :severity).new
vstruct.id = vuln["id"]
vstruct.title = vuln["title"]
vstruct.severity = vuln["severity"]
vstruct.refs = []
vuln["refs"].each do |ref|
refs[vuln['id']] ||= []
if ref['source'] == 'BID'
refs[vuln['id']].push('BID-' + ref["value"])
vstruct.refs.push('BID-' + ref["value"])
elsif ref['source'] == 'CVE'
# value is CVE-$ID
refs[vuln['id']].push(ref["value"])
vstruct.refs.push(ref["value"])
elsif ref['source'] == 'MS'
refs[vuln['id']].push('MSB-' + ref["value"])
vstruct.refs.push('MSB-' + ref["value"])
elsif ref['source'] == 'URL'
refs[vuln['id']].push('URL-' + ref["value"])
vstruct.refs.push('URL-' + ref["value"])
#else
# $stdout.puts("Unknown source: #{ref["source"]}")
end
end
ret.push vstruct
end
refs
return ret
end
def nexpose_host(h, vuln_refs, wspace)
# Takes a Host object, an array of vuln structs (generated by nexpose_refs_to_struct()),
# and a workspace, and reports the vulns on that host.
def nexpose_host_from_rawxml(h, vstructs, wspace)
data = {:workspace => wspace}
if h["addr"]
addr = h["addr"]
@ -3171,14 +3176,17 @@ class DBManager
}
h["vulns"].each_pair { |k,v|
next if v["status"] !~ /^vulnerable/
vstruct = vstructs.select {|vs| vs.id.to_s.downcase == v["id"].to_s.downcase}.first
data = {}
data[:workspace] = wspace
data[:host] = addr
data[:proto] = v["protocol"].downcase if v["protocol"]
data[:port] = v["port"].to_i if v["port"]
data[:name] = "NEXPOSE-" + v["id"]
data[:refs] = vuln_refs[v["id"].to_s.downcase]
data[:info] = vstruct.title
data[:refs] = vstruct.refs
report_vuln(data)
}
end