require 'rexml/document' require 'rex/ui' module Rex module Parser class NessusXMLStreamParser attr_accessor :on_found_host def initialize(&block) reset_state on_found_host = block if block end def reset_state @host = {'hname' => nil, 'addr' => nil, 'mac' => nil, 'os' => nil, 'ports' => [ 'port' => {'port' => nil, 'svc_name' => nil, 'proto' => nil, 'severity' => nil, 'nasl' => nil, 'description' => nil, 'cve' => [], 'bid' => [], 'xref' => [], 'msf' => nil } ] } @state = :generic_state end def tag_start(name, attributes) case name when "tag" if attributes['name'] == "mac-address" @state = :is_mac end if attributes['name'] == "host-fqdn" @state = :is_fqdn end if attributes['name'] == "ip-addr" @state = :is_ip end if attributes['name'] == "host-ip" @state = :is_ip end if attributes['name'] == "operating-system" @state = :is_os end when "ReportHost" @host['hname'] = attributes['name'] when "ReportItem" @cve = Array.new @bid = Array.new @xref = Array.new @x = Hash.new @x['nasl'] = attributes['pluginID'] @x['port'] = attributes['port'] @x['proto'] = attributes['protocol'] @x['svc_name'] = attributes['svc_name'] @x['severity'] = attributes['severity'] when "description" @state = :is_desc when "cve" @state = :is_cve when "bid" @state = :is_bid when "xref" @state = :is_xref when "solution" @state = :is_solution when "metasploit_name" @state = :msf end end def text(str) case @state when :is_fqdn @host['hname'] = str when :is_ip @host['addr'] = str when :is_os @host['os'] = str when :is_mac @host['mac'] = str when :is_desc @x['description'] = str when :is_cve @cve.push str when :is_bid @bid.push str when :is_xref @xref.push str when :msf #p str @x['msf'] = str end end def tag_end(name) case name when "ReportHost" on_found_host.call(@host) if on_found_host reset_state when "ReportItem" @x['cve'] = @cve @x['bid'] = @bid @x['xref'] = @xref @host['ports'].push @x end @state = :generic_state end # We don't need these methods, but they're necessary to keep REXML happy # def xmldecl(version, encoding, standalone); end def cdata; end def comment(str); end def instruction(name, instruction); end def attlist; end end end end