From e1499657c981bd2f1a9d3ab0e07f647b5cceaced Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Tue, 29 Mar 2011 22:22:58 +0000 Subject: [PATCH] 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 --- lib/msf/core/db.rb | 48 +++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/lib/msf/core/db.rb b/lib/msf/core/db.rb index 7610fddcf5..2610a39bce 100644 --- a/lib/msf/core/db.rb +++ b/lib/msf/core/db.rb @@ -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"]) - #else - # $stdout.puts("Unknown source: #{ref["source"]}") + 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