Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/parser/openvas_document.rb
Views: 11778
# -*- coding: binary -*-1require "rex/parser/nokogiri_doc_mixin"23module Rex4module Parser56# If Nokogiri is available, define OpenVas document class.7load_nokogiri && class OpenVASDocument < Nokogiri::XML::SAX::Document89include NokogiriDocMixin1011# ourselves with the @state variable, turning things on when we12# get here (and turning things off when we exit in end_element()).13def start_element(name=nil,attrs=[])14attrs = normalize_attrs(attrs)15block = @block16@state[:current_tag][name] = true1718unless @text.nil?19@state[:text_backup] = @text20@text = nil21end2223case name24when "host"25@state[:has_text] = true26when 'ref'27ref_type = ''28ref_id = ''29if defined?(attrs) && attrs.kind_of?(Array)30attrs.each do |attr|31next if !defined?(attr) || !attr.kind_of?(Array) || attr.length != 232if defined?(attr[0]) && defined?(attr[1]) && attr[0] == 'type'33ref_type = attr[1]34end35if defined?(attr[0]) && defined?(attr[1]) && attr[0] == 'id'36ref_id = attr[1]37end38end39end40if in_tag('result') && in_tag('nvt') && in_tag('refs') &&41!ref_type.empty? && !ref_type.empty?42case ref_type.upcase43when 'CVE'44@state[:ref_cve] = [] if @state[:ref_cve].nil?45@state[:ref_cve].append(ref_id.strip)46when 'URL'47@state[:ref_url] = [] if @state[:ref_url].nil?48@state[:ref_url].append(ref_id.strip)49when 'DFN-CERT'50if defined?(@args[:options][:openvas_dfn]) && @args[:options][:openvas_dfn]51@state[:ref_dfn] = [] if @state[:ref_dfn].nil?52@state[:ref_dfn].append(ref_id.strip)53end54when 'CERT-BUND'55if defined?(@args[:options][:openvas_cert]) && @args[:options][:openvas_cert]56@state[:ref_cb] = [] if @state[:ref_cb].nil?57@state[:ref_cb].append(ref_id.strip)58end59end60end61end62end6364# When we exit a tag, this is triggered.65def end_element(name=nil)66block = @block67case name68when 'name'69if in_tag('result')70@state[:has_text] = true71@state[:vuln_name] = @text.strip if @text72end73when 'description'74if in_tag('result')75@state[:has_text] = true76@state[:vuln_desc] = @text.strip if @text77end78when 'bid'79if in_tag('result') && in_tag('nvt')80@state[:has_text] = true81@state[:bid] = @text.strip if @text82end83when 'cve'84if in_tag('result') && in_tag('nvt')85@state[:has_text] = true86@state[:cves] = @text.strip if @text87end88when 'risk_factor'89if in_tag('result') && in_tag('nvt')90#we do this to clean out the buffer so to speak91#if we don't set text to nil now, the text will show up later92@state[:has_text] = true93end94when 'cvss_base'95if in_tag('result') && in_tag('nvt')96@state[:has_text] = true97end98when 'subnet'99@state[:has_text] = true100when 'result'101record_vuln102when 'threat'103@state[:has_text] = true if in_tag('ports') && in_tag('port')104when 'host'105if in_tag('result')106@state[:has_text] = true107@state[:host] = @text.strip if @text108elsif in_tag('ports') && in_tag('port')109@state[:has_text] = true110@state[:host] = @text.strip if @text111end112when 'port'113if in_tag('result')114@state[:has_text] = true115if @text116if /^(?<p_num>\d{1,5})\/(?<p_proto>.+)\s\((?<p_name>.+)\)/ =~ @text117@state[:name] = p_name.gsub(/iana: /i, '')118@state[:port] = p_num119@state[:proto] = p_proto120elsif @text.index('(')121@state[:proto] = @text.split('(')[1].split('/')[1].gsub(/\)/, '')122@state[:port] = @text.split('(')[1].split('/')[0].gsub(/\)/, '')123elsif @text.index('/')124@state[:proto] = @text.split('/')[1].strip125@state[:port] = @text.split('/')[0].strip126else127@state[:proto] = nil128@state[:port] = nil129end130131if @state[:port] && @state[:port] == 'general'132@state[:proto] = nil133@state[:port] = nil134end135end136elsif in_tag('ports')137if @text138if /^(?<p_num>\d{1,5})\/(?<p_proto>.+)\s\((?<p_name>.+)\)/ =~ @text139@state[:name] = p_name.gsub(/iana: /i, '')140@state[:port] = p_num141@state[:proto] = p_proto142record_service if p_num143elsif @text.index('(')144@state[:name] = @text.split(' ')[0]145@state[:port] = @text.split('(')[1].split('/')[0]146@state[:proto] = @text.split('(')[1].split('/')[1].split(')')[0]147record_service unless @state[:name].nil?148elsif @text.index('/')149@state[:port] = @text.split('/')[0].strip150@state[:proto] = @text.split('/')[1].strip151record_service unless @state[:port] == 'general'152end153end154end155when 'name'156return if not in_tag('result')157@state[:has_text] = true158end159160if @state[:text_backup]161@text = @state[:text_backup]162@state[:text_backup] = nil163else164@text = nil165end166167@state[:current_tag].delete name168end169170def record_vuln171if (@state[:cves] and @state[:cves] == "NOCVE") and (@state[:bid] and @state[:bid] == "NOBID")172return173end174175references = []176if @state[:cves] and @state[:cves] != "NOCVE" and !@state[:cves].empty?177@state[:cves].split(',').each do |cve|178references.append({ :source => "CVE", :value => cve})179end180end181if @state[:bid] and @state[:bid] != "NOBID" and !@state[:bid].empty?182@state[:bid].split(',').each do |bid|183references.append({ :source => "BID", :value => bid})184end185end186if @state[:ref_cve] && @state[:ref_cve].kind_of?(Array)187@state[:ref_cve].each do |cve|188references.append({ :source => "CVE", :value => cve.dup}) if !cve.empty?189end190@state[:ref_cve].clear191end192if @state[:ref_url] && @state[:ref_url].kind_of?(Array)193@state[:ref_url].each do |url|194references.append({ :source => "URL", :value => url.dup}) if !url.empty?195end196@state[:ref_url].clear197end198if @state[:ref_cb] && @state[:ref_cb].kind_of?(Array)199@state[:ref_cb].each do |cb|200references.append({ :source => "CB", :value => cb.dup}) if !cb.empty?201end202@state[:ref_cb].clear203end204if @state[:ref_dfn] && @state[:ref_dfn].kind_of?(Array)205@state[:ref_dfn].each do |dfn|206references.append({ :source => "DFN-CERT", :value => dfn.dup}) if !dfn.empty?207end208@state[:ref_dfn].clear209end210211vuln_info = {}212vuln_info[:host] = @state[:host]213vuln_info[:refs] = normalize_references(references)214vuln_info[:name] = @state[:vuln_name]215vuln_info[:info] = @state[:vuln_desc]216vuln_info[:port] = @state[:port]217vuln_info[:proto] = @state[:proto]218vuln_info[:workspace] = @args[:workspace]219db_report(:vuln, vuln_info)220end221222def record_service223service_info = {}224service_info[:host] = @state[:host]225service_info[:name] = @state[:name]226service_info[:port] = @state[:port]227service_info[:proto] = @state[:proto]228service_info[:workspace] = @args[:workspace]229230db_report(:service, service_info)231232host_info = {}233host_info[:host] = @state[:host]234host_info[:workspace] = @args[:workspace]235236db_report(:host, host_info)237end238end239end240end241242243244