Class: Rex::Parser::NexposeXMLStreamParser

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/parser/nexpose_xml.rb

Overview

XXX doesn't tie services to vulns

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(callback = nil) ⇒ NexposeXMLStreamParser


10
11
12
13
# File 'lib/rex/parser/nexpose_xml.rb', line 10

def initialize(callback = nil)
  reset_state
  self.callback = callback if callback
end

Instance Attribute Details

#callbackObject

Returns the value of attribute callback


8
9
10
# File 'lib/rex/parser/nexpose_xml.rb', line 8

def callback
  @callback
end

Instance Method Details

#attlistObject

:nodoc:


129
130
# File 'lib/rex/parser/nexpose_xml.rb', line 129

def attlist # :nodoc:
end

#cdataObject

:nodoc:


123
124
# File 'lib/rex/parser/nexpose_xml.rb', line 123

def cdata # :nodoc:
end

#comment(str) ⇒ Object

:nodoc:


125
126
# File 'lib/rex/parser/nexpose_xml.rb', line 125

def comment(str) # :nodoc:
end

#instruction(name, instruction) ⇒ Object

:nodoc:


127
128
# File 'lib/rex/parser/nexpose_xml.rb', line 127

def instruction(name, instruction) # :nodoc:
end

#parse_vulnerable_states_only(only_vuln_states_needed) ⇒ Object

If all vuln states are required set this to false


25
26
27
# File 'lib/rex/parser/nexpose_xml.rb', line 25

def parse_vulnerable_states_only only_vuln_states_needed
  @only_vuln_states_needed = only_vuln_states_needed
end

#reset_stateObject


15
16
17
18
19
20
21
22
# File 'lib/rex/parser/nexpose_xml.rb', line 15

def reset_state
  @state = :generic_state
  @only_vuln_states_needed = true
  @current_vuln_id = nil
  @vulnerable_markers = ['vulnerable-exploited', 'vulnerable-version', 'potential']
  @host = {"status" => nil, "endpoints" => [], "names" => [], "vulns" => {}}
  @vuln = {"refs" => [], "description" => [], "solution" => []}
end

#tag_end(name) ⇒ Object


107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rex/parser/nexpose_xml.rb', line 107

def tag_end(name)
  case name
  when "node"
    callback.call(:host, @host) if callback
    reset_state
  when "vulnerability"
    callback.call(:vuln, @vuln) if callback
    reset_state
  when "service","reference","names"
    @state = :generic_state
  end
end

#tag_start(name, attributes) ⇒ Object


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
# File 'lib/rex/parser/nexpose_xml.rb', line 29

def tag_start(name, attributes)
  case name
  when "node"
    @host["hardware-address"] = attributes["hardware-address"]
    @host["addr"] = attributes["address"]
    @host["status"] = attributes["status"]
  when "os"
    # Take only the highest certainty
    if not @host["os_certainty"] or (@host["os_certainty"].to_f < attributes["certainty"].to_f)
      @host["os_vendor"]    = attributes["vendor"]
      @host["os_family"]    = attributes["family"]
      @host["os_product"]   = attributes["product"]
      @host["os_version"]   = attributes["version"]
      @host["arch"]         = attributes["arch"]
      @host["os_certainty"] = attributes["certainty"]
    end
  when "name"
    #@host["names"].push attributes["name"]
    @state = :in_name
  when "endpoint"
    # This is a port in NeXpose parlance
    @host["endpoints"].push(attributes)
  when "service"
    @state = :in_service
    # Store any service info with the associated port.  There shouldn't
    # be any collisions on attribute names here, so just merge them.
    @host["endpoints"].last.merge!(attributes)
  when "fingerprint"
    if @state == :in_service
      @host["endpoints"].last.merge!(attributes)
    end
    when "test"
      if (not @only_vuln_states_needed) or (@vulnerable_markers.include? attributes["status"].to_s.chomp and @only_vuln_states_needed)
        @state = :in_test
        @current_vuln_id = attributes["id"]
        @host["vulns"][@current_vuln_id] = attributes.dup
        # Append the endpoint info for how the vuln was discovered
        unless @host["endpoints"].empty?
          @host["vulns"][@current_vuln_id].merge!("endpoint_data" => @host["endpoints"].last)
        end
        if attributes["key"]
          @host["notes"] ||= []
          @host["notes"] << [@current_vuln_id, attributes["key"]]
        end
      end
    when "vulnerability"
      @vuln.merge! attributes
    when "reference"
      @state = :in_reference
      @vuln["refs"].push attributes
    when "solution"
      @state = :in_solution
    when "description"
      @state = :in_description
    when "URLLink"
      @vuln["solution"] << attributes
  end
end

#text(str) ⇒ Object


88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rex/parser/nexpose_xml.rb', line 88

def text(str)
  case @state
  when :in_name
    @host["names"].push str
  when :in_reference
    @vuln["refs"].last["value"] = str
  when :in_solution
    @vuln["solution"] << str
  when :in_description
    @vuln["description"] << str
  when :in_test
    if @host["vulns"][@current_vuln_id]
       proof = @host["vulns"][@current_vuln_id]["proof"] || []
       proof << str
       @host["vulns"][@current_vuln_id]["proof"] = proof
    end
  end
end

#xmldecl(version, encoding, standalone) ⇒ Object

We don't need these methods, but they're necessary to keep REXML happy


121
122
# File 'lib/rex/parser/nexpose_xml.rb', line 121

def xmldecl(version, encoding, standalone) # :nodoc:
end