Skip to content

Commit

Permalink
OpenVAS import functionality. See qa/sample_data for two openvas repo…
Browse files Browse the repository at this point in the history
…rts.
  • Loading branch information
Brandon Perry committed May 14, 2012
1 parent 06b12bc commit 1beaeb8
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/msf/core/db.rb
Expand Up @@ -9,6 +9,7 @@
require 'rex/parser/burp_session_nokogiri'
require 'rex/parser/ci_nokogiri'
require 'rex/parser/wapiti_nokogiri'
require 'rex/parser/openvas_nokogiri'

# Legacy XML parsers -- these will be converted some day

Expand Down Expand Up @@ -2430,6 +2431,12 @@ def import_filetype_detect(data)
elsif (firstline.index("<scanJob>"))
@import_filedata[:type] = "Retina XML"
return :retina_xml
elsif (firstline.index("<get_reports_response status=\"200\" status_text=\"OK\">"))
@import_filedata[:type] = "OpenVAS XML"
return :openvas_new_xml
elsif (firstline.index("<report id=\""))
@import_filedata[:type] = "OpenVAS XML"
return :openvas_new_xml
elsif (firstline.index("<NessusClientData>"))
@import_filedata[:type] = "Nessus XML (v1)"
return :nessus_xml
Expand Down
167 changes: 167 additions & 0 deletions lib/rex/parser/openvas_nokogiri.rb
@@ -0,0 +1,167 @@
require "rex/parser/nokogiri_doc_mixin"

module Rex
module Parser

# If Nokogiri is available, define OpenVAS document class.
load_nokogiri && class OpenVASDocument < Nokogiri::XML::SAX::Document

include NokogiriDocMixin

# ourselves with the @state variable, turning things on when we
# get here (and turning things off when we exit in end_element()).
def start_element(name=nil,attrs=[])
attrs = normalize_attrs(attrs)
block = @block
@state[:current_tag][name] = true
case name
when "host"
@state[:has_text] = true
end
end

# When we exit a tag, this is triggered.
def end_element(name=nil)
block = @block
case name
when "name"
return if not in_tag("result")
@state[:has_text] = true
@state[:vuln_name] = @text.strip
@text = nil
when "description"
@state[:has_text] = true
@state[:vuln_desc] = @text.strip
@text = nil
when "bid"
return if not in_tag("result")
return if not in_tag("nvt")
@state[:has_text] = true
@state[:bid] = @text.strip
@text = nil
when "cve"
return if not in_tag("result")
return if not in_tag("nvt")
@state[:has_text] = true
@state[:cves] = @text.strip
@text = nil
when "risk_factor"
return if not in_tag("result")
return if not in_tag("nvt")
@state[:has_text] = true
@text = nil
when "cvss_base"
return if not in_tag("result")
return if not in_tag("nvt")
@state[:has_text] = true
@text = nil
when "subnet"
@state[:has_text] = true
@text = nil
when "result"
return if not in_tag("results")
record_vuln
when "threat"
return if not in_tag("ports")
return if not in_tag("port")
@state[:has_text] = true

if not @text.index('(')
@state[:name] = nil
@state[:port] = nil
@state[:proto] = nil
@text = nil
return
end

@state[:name] = @text.split(' ')[0]
@state[:port] = @text.split('(')[1].split('/')[0]
@state[:proto] = @text.split('(')[1].split('/')[1].split(')')[0]
@text = nil
when "host"
if in_tag('result')
@state[:has_text] = true
@state[:host] = @text.strip
@text = nil
elsif in_tag('ports')
return if not in_tag('port')
@state[:has_text] = true
@state[:host] = @text.strip
@text = nil
end
when "port"
if in_tag('result')
@state[:has_text] = true
if not @text.index('(')
@state[:proto] = nil
@state[:port] = nil
@text = nil
return
end
@state[:proto] = @text.split('(')[0].strip
@state[:port] = @text.split('(')[1].split('/')[0].gsub(/\)/, '')
@text = nil
elsif in_tag('ports')
record_service
end
when "name"
return if not in_tag("result")
@state[:has_text] = true
@text = nil
end
@state[:current_tag].delete name
end

def record_vuln
if @state[:cves] == "NOCVE" and @state[:bid] == "NOBID"
return
end

if @state[:cves] != "NOCVE" and !@state[:cves].empty?
@state[:cves].split(',').each do |cve|
vuln_info = {}
vuln_info[:host] = @state[:host]
vuln_info[:refs] = normalize_references([{ :source => "CVE", :value => cve}])
vuln_info[:name] = @state[:vuln_name]
vuln_info[:info] = @state[:vuln_desc]
vuln_info[:port] = @state[:port]
vuln_info[:proto] = @state[:proto]

db_report(:vuln, vuln_info)
end
end
if @state[:bid] != "NOBID" and !@state[:bid].empty?
@state[:bid].split(',').each do |bid|
vuln_info = {}
vuln_info[:host] = @state[:host]
vuln_info[:refs] = normalize_references([{ :source => "BID", :value => bid}])
vuln_info[:name] = @state[:vuln_name]
vuln_info[:info] = @state[:vuln_desc]
vuln_info[:port] = @state[:port]
vuln_info[:proto] = @state[:proto]

db_report(:vuln, vuln_info)
end
end
end

def record_service
return if not @state[:name]

service_info = {}
service_info[:host] = @state[:host]
service_info[:name] = @state[:name]
service_info[:port] = @state[:port]
service_info[:proto] = @state[:proto]

db_report(:service, service_info)

host_info = {}
host_info[:host] = @state[:host]

db_report(:host, host_info)
end
end
end
end

0 comments on commit 1beaeb8

Please sign in to comment.