Class: Nessus::ReportItem
- Inherits:
-
Object
- Object
- Nessus::ReportItem
- Defined in:
- lib/nessus/report_item.rb
Overview
This class represents each of the /NessusClientData_v2/Report/ReportHost/ReportItem elements in the Nessus XML document.
It provides a convenient way to access the information scattered all over the XML in attributes and nested tags.
Instead of providing separate methods for each supported property we rely on Ruby’s #method_missing to do most of the work.
Instance Method Summary collapse
-
#initialize(xml_node) ⇒ ReportItem
constructor
Accepts an XML node from Nokogiri::XML.
-
#method_missing(method, *args) ⇒ Object
This method is invoked by Ruby when a method that is not defined in this instance is called.
-
#respond_to?(method, include_private = false) ⇒ Boolean
This allows external callers (and specs) to check for implemented properties.
-
#supported_tags ⇒ Object
List of supported tags.
Constructor Details
#initialize(xml_node) ⇒ ReportItem
Accepts an XML node from Nokogiri::XML.
13 14 15 |
# File 'lib/nessus/report_item.rb', line 13 def initialize(xml_node) @xml = xml_node end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
This method is invoked by Ruby when a method that is not defined in this instance is called.
In our case we inspect the @method@ parameter and try to find the attribute, simple descendent or collection that it maps to in the XML tree.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/nessus/report_item.rb', line 55 def method_missing(method, *args) # We could remove this check and return nil for any non-recognized tag. # The problem would be that it would make tricky to debug problems with # typos. For instance: <>.potr would return nil instead of raising an # exception unless .include?(method) super return end # first we try the attributes: port, svc_name, protocol, severity, # plugin_id, plugin_name, plugin_family translations_table = { # @port = xml.attributes["port"] # @svc_name = xml.attributes["svc_name"] # @protocol = xml.attributes["protocol"] # @severity = xml.attributes["severity"] :cvss3_impact_score => 'cvssV3_impactScore', :plugin_id => 'pluginID', :plugin_name => 'pluginName', :plugin_family => 'pluginFamily' } method_name = translations_table.fetch(method, method.to_s) return @xml.attributes[method_name].value if @xml.attributes.key?(method_name) # then we try the children tags: solution, risk_factor, description, # plugin_publication_date, metasploit_name, cvss_vector, # cvss_temporal_vector, synopsis, exploit_available, # patch_publication_date, plugin_modification_date, cvss_temporal_score, # cvss_base_score, plugin_output, plugin_version, exploitability_ease, # vuln_publication_date, exploit_framework_canvas, # exploit_framework_metasploit, exploit_framework_core tag = @xml.xpath("./#{method_name}").first if tag text = tag.text return .include?(method) ? cleanup_html(text) : text end # then the custom XML tags (cm: namespace) if method_name.starts_with?('cm_') method_name = method_name.sub(/cm_/, 'cm:compliance-').gsub(/_/, '-') cm_value = @xml.at_xpath("./#{method_name}", { 'cm' => 'http://www.nessus.org/cm' }) if cm_value return cm_value.text else return nil end end # older versions of Nessus use <vpr_score> while newer versions of Nessus # use <vulnerability_priority_rating>. This allows either tag to be # pulled in to the vpr_score mapping if method_name == 'vpr_score' return @xml.at_xpath('./vulnerability_priority_rating | ./vpr_score')&.text end # finally the enumerations: bid_entries, cve_entries, xref_entries translations_table = { :bid_entries => 'bid', :cve_entries => 'cve', :cwe_entries => 'cwe', :see_also_entries => 'see_also', :xref_entries => 'xref' } method_name = translations_table.fetch(method, nil) if method_name @xml.xpath("./#{method_name}").collect(&:text) else # nothing found, the tag is valid but not present in this ReportItem return nil end end |
Instance Method Details
#respond_to?(method, include_private = false) ⇒ Boolean
This allows external callers (and specs) to check for implemented properties
44 45 46 47 |
# File 'lib/nessus/report_item.rb', line 44 def respond_to?(method, include_private=false) return true if .include?(method.to_sym) super end |
#supported_tags ⇒ Object
List of supported tags. They can be attributes, simple descendans or collections (e.g. <bid/>, <cve/>, <xref/>)
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/nessus/report_item.rb', line 19 def [ # attributes :plugin_family, :plugin_id, :plugin_name, :port, :protocol, :svc_name, :severity, # simple tags :age_of_vuln, :cvss3_base_score, :cvss3_temporal_score, :cvss3_temporal_vector, :cvss3_vector, :cvss_base_score, :cvss3_impact_score, :cvss_temporal_score, :cvss_temporal_vector, :cvss_vector, :description, :exploit_available, :exploit_code_maturity, :exploit_framework_canvas, :exploit_framework_core, :exploitability_ease, :exploit_framework_metasploit,:metasploit_name, :patch_publication_date, :plugin_modification_date, :plugin_output, :plugin_publication_date, :plugin_type, :plugin_version, :product_coverage, :risk_factor, :solution, :synopsis, :threat_intensity_last_28, :threat_recency, :threat_sources_last_28, :vpr_score, :vuln_publication_date, # multiple tags :bid_entries, :cve_entries, :cwe_entries, :see_also_entries, :xref_entries, # compliance tags :cm_actual_value, :cm_audit_file, :cm_check_id, :cm_check_name, :cm_info, :cm_output, :cm_policy_value, :cm_reference, :cm_result, :cm_see_also, :cm_solution ] end |