Module: Msf::DBManager::Import::Nessus::XML::V2

Included in:
Msf::DBManager::Import::Nessus::XML
Defined in:
lib/msf/core/db_manager/import/nessus/xml/v2.rb

Instance Method Summary collapse

Instance Method Details

#handle_nessus_v2(wspace, hobj, port, proto, name, nasl, nasl_name, severity, description, cve, bid, xref, msf, task = nil) ⇒ Object (protected)

NESSUS v2 file format has a dramatically different layout for ReportItem data



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/msf/core/db_manager/import/nessus/xml/v2.rb', line 114

def handle_nessus_v2(wspace,hobj,port,proto,name,nasl,nasl_name,severity,description,cve,bid,xref,msf,task=nil)
  addr = hobj.address

  info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto, :task => task }

  unless name =~ /^unknown$|\?$/
    info[:name] = name
  end

  if port.to_i != 0
    msf_import_service(info)
  end

  if nasl.nil? || nasl.empty? || nasl == 0 || nasl == "0"
    return
  end

  refs = []

  cve.each do |r|
    r.to_s.gsub!(/C(VE|AN)\-/, '')
    refs.push('CVE-' + r.to_s)
  end if cve

  bid.each do |r|
    refs.push('BID-' + r.to_s)
  end if bid

  xref.each do |r|
    ref_id, ref_val = r.to_s.split(':')
    ref_val ? refs.push(ref_id + '-' + ref_val) : refs.push(ref_id)
  end if xref

  msfref = "MSF-" << msf if msf
  refs.push msfref if msfref

  nss = 'NSS-' + nasl
  if nasl_name.nil? || nasl_name.empty?
    vuln_name = nss
  else
    vuln_name = nasl_name
  end

  refs << nss.strip

  vuln = {
    :workspace => wspace,
    :host => hobj,
    :name => vuln_name,
    :info => description ? description : "",
    :refs => refs,
    :task => task,
  }

  if port.to_i != 0
    vuln[:port]  = port
    vuln[:proto] = proto
  end

  msf_import_vuln(vuln)
end

#import_nessus_xml_v2(args = {}, &block) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/msf/core/db_manager/import/nessus/xml/v2.rb', line 3

def import_nessus_xml_v2(args={}, &block)
  data = args[:data]
  wspace = Msf::Util::DBManager.process_opts_workspace(args, framework).name
  bl = validate_ips(args[:blacklist]) ? args[:blacklist].split : []

  #@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'                  => []
      #				}
      #			]
      #}
  parser = Rex::Parser::NessusXMLStreamParser.new
  parser.on_found_host = Proc.new { |host|

    hobj = nil
    addr = host['addr'] || host['hname']

    next unless ipv46_validator(addr) # Catches SCAN-ERROR, among others.

    if bl.include? addr
      next
    else
      yield(:address,addr) if block
    end

    os = host['os']
    hname = host['hname']
    mac = host['mac']

    host_info = {
      :workspace => wspace,
      :host => addr,
      :task => args[:task]
    }
    host_info[:name] = hname.to_s.strip if hname
    # Short mac, protect against Nessus's habit of saving multiple macs
    # We can't use them anyway, so take just the first.
    host_info[:mac]  = mac.to_s.strip.upcase.split(/\s+/).first if mac

    hobj = msf_import_host(host_info)
    report_import_note(wspace,hobj)

    os = host['os']
    yield(:os,os) if block
    if os
      msf_import_note(
        :workspace => wspace,
        :task => args[:task],
        :host => hobj,
        :type => 'host.os.nessus_fingerprint',
        :data => {
          :os => os.to_s.strip
        }
      )
    end

    mapped_protos = {
      'rmi-p4' => 'tcp'
    }

    host['ports'].each do |item|
      # XXX: The value of item['port'] is the string '0' - re-evaluate if this line is required
      next if item['port'] == 0
      msf = nil
      nasl = item['nasl'].to_s
      nasl_name = item['nasl_name'].to_s
      port = item['port'].to_s
      proto = item['proto'] ? item['proto'].downcase : "tcp"
      proto = mapped_protos[proto] if mapped_protos[proto]
      sname = item['svc_name']
      severity = item['severity']
      description = item['description']
      cve = item['cve']
      bid = item['bid']
      xref = item['xref']
      msf = item['msf']

      unless Mdm::Service::PROTOS.include?(proto)
        elog("Unknown protocol '#{proto}' for #{addr}:#{port} for nessus import, defaulting to tcp")
        proto = "tcp"
      end

      yield(:port,port) if block

      handle_nessus_v2(wspace, hobj, port, proto, sname, nasl, nasl_name, severity, description, cve, bid, xref, msf, args[:task])

    end
    yield(:end,hname) if block
  }

  REXML::Document.parse_stream(data, parser)

end