Class: Msf::Plugin::Nexpose::NexposeCommandDispatcher

Inherits:
Object
  • Object
show all
Includes:
Ui::Console::CommandDispatcher
Defined in:
plugins/nexpose.rb

Instance Attribute Summary

Attributes included from Ui::Console::CommandDispatcher

#driver

Attributes included from Rex::Ui::Text::DispatcherShell::CommandDispatcher

#shell, #tab_complete_items

Instance Method Summary collapse

Methods included from Ui::Console::CommandDispatcher

#active_module, #active_module=, #active_session, #active_session=, #build_range_array, #docs_dir, #framework, #initialize, #log_error, #remove_lines

Methods included from Rex::Ui::Text::DispatcherShell::CommandDispatcher

#cmd_help, #cmd_help_help, #cmd_help_tabs, #deprecated_cmd, #deprecated_commands, #deprecated_help, #docs_dir, #help_to_s, #initialize, #print, #print_error, #print_good, #print_line, #print_status, #print_warning, #tab_complete_directory, #tab_complete_filenames, #tab_complete_generic, #tab_complete_source_address, #update_prompt

Instance Method Details

#cmd_nexpose_activity(*args) ⇒ Object


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'plugins/nexpose.rb', line 195

def cmd_nexpose_activity(*args)
  return if not nexpose_verify

  scans = @nsc.scan_activity || []
  case scans.length
  when 0
    print_status("There are currently no active scan jobs on this Nexpose instance")
  when 1
    print_status("There is 1 active scan job on this Nexpose instance")
  else
    print_status("There are currently #{scans.length} active scan jobs on this Nexpose instance")
  end

  scans.each do |scan|
    print_status("    Scan ##{scan.scan_id} is running on Engine ##{scan.engine_id} against site ##{scan.site_id} since #{scan.start_time.to_s}")
  end
end

#cmd_nexpose_command(*args) ⇒ Object


257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'plugins/nexpose.rb', line 257

def cmd_nexpose_command(*args)
  return if not nexpose_verify

  if args.length == 0
    print_error("No command was specified")
    return
  end

  res = @nsc.console_command(args.join(" ")) || ""

  print_status("Command Output")
  print_line(res)
  print_line("")

end

#cmd_nexpose_connect(*args) ⇒ Object


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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'plugins/nexpose.rb', line 92

def cmd_nexpose_connect(*args)
  return if not nexpose_verify_db

  if ! args[0]
    if ::File.readable?("#{Nexpose_yaml}")
      lconfig = YAML.load_file("#{Nexpose_yaml}")
      @user = lconfig['default']['username']
      @pass = lconfig['default']['password']
      @host = lconfig['default']['server']
      @port = lconfig['default']['port']
      @trust_cert = lconfig['default']['trust_cert']
      unless @trust_cert
        @sslv = "ok" # TODO: Not super-thrilled about bypassing the SSL warning...
      end
      
      return
    end
  end

  if(args.length == 0 or args[0].empty? or args[0] == "-h")
    nexpose_usage
    return
  end

  @user = @pass = @host = @port = @sslv = @trust_cert = @trust_cert_file = nil

  case args.length
  when 1,2
    cred,targ = args[0].split('@', 2)
    @user,@pass = cred.split(':', 2)
    targ ||= '127.0.0.1:3780'
    @host,@port = targ.split(':', 2)
    @port ||= '3780'
    unless args.length == 1
      @trust_cert_file = args[1]
      if File.exists? @trust_cert_file
        @trust_cert = File.read(@trust_cert_file)
      else
        @sslv = @trust_cert_file
      end
    end
  when 4,5
    @user,@pass,@host,@port,@trust_cert = args
    unless args.length == 4
      @trust_cert_file = @trust_cert
      if File.exists? @trust_cert_file
        @trust_cert = File.read(@trust_cert_file)
      else
        @sslv = @trust_cert_file
      end
    end
  else
    nexpose_usage
    return
  end
  
end

#cmd_nexpose_disconnect(*args) ⇒ Object


603
604
605
606
# File 'plugins/nexpose.rb', line 603

def cmd_nexpose_disconnect(*args)
  @nsc.logout if @nsc
  @nsc = nil
end

#cmd_nexpose_discover(*args) ⇒ Object


338
339
340
341
342
343
# File 'plugins/nexpose.rb', line 338

def cmd_nexpose_discover(*args)
  args << "-h" if args.length == 0
  args << "-t"
  args << "aggressive-discovery"
  cmd_nexpose_scan(*args)
end

#cmd_nexpose_dos(*args) ⇒ Object


352
353
354
355
356
357
# File 'plugins/nexpose.rb', line 352

def cmd_nexpose_dos(*args)
  args << "-h" if args.length == 0
  args << "-t"
  args << "dos-audit"
  cmd_nexpose_scan(*args)
end

#cmd_nexpose_exhaustive(*args) ⇒ Object


345
346
347
348
349
350
# File 'plugins/nexpose.rb', line 345

def cmd_nexpose_exhaustive(*args)
  args << "-h" if args.length == 0
  args << "-t"
  args << "exhaustive-audit"
  cmd_nexpose_scan(*args)
end

#cmd_nexpose_report_templates(*args) ⇒ Object


247
248
249
250
251
252
253
254
255
# File 'plugins/nexpose.rb', line 247

def cmd_nexpose_report_templates(*args)
  return if not nexpose_verify

  res = @nsc.list_report_templates || []

  res.each do |report|
    print_status("    Template: #{report.id} Name: '#{report.name}' Description: #{report.description}")
  end
end

#cmd_nexpose_save(*args) ⇒ Object


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
# File 'plugins/nexpose.rb', line 66

def cmd_nexpose_save(*args)
  #if we are logged in, save session details to nexpose.yaml
  if args[0] == "-h"
    print_status("Usage: ")
    print_status("       nexpose_save")
    return
  end

  if args[0]
    print_status("Usage: ")
    print_status("       nexpose_save")
    return
  end

  group = "default"

  if ((@user and @user.length > 0) and (@host and @host.length > 0) and (@port and @port.length > 0 and @port.to_i > 0) and (@pass and @pass.length > 0))
    config = {"#{group}" => {'username' => @user, 'password' => @pass, 'server' => @host, 'port' => @port, 'trust_cert' => @trust_cert}}
    ::File.open("#{Nexpose_yaml}", "wb") { |f| f.puts YAML.dump(config) }
    print_good("#{Nexpose_yaml} created.")
  else
    print_error("Missing username/password/server/port - relogin and then try again.")
    return
  end
end

#cmd_nexpose_scan(*args) ⇒ Object


359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'plugins/nexpose.rb', line 359

def cmd_nexpose_scan(*args)

  opts = Rex::Parser::Arguments.new(
    "-h"   => [ false,  "This help menu"],
    "-t"   => [ true,   "The scan template to use (default:pentest-audit options:full-audit,exhaustive-audit,discovery,aggressive-discovery,dos-audit)"],
    "-c"   => [ true,   "Specify credentials to use against these targets (format is type:user:pass"],
    "-n"   => [ true,   "The maximum number of IPs to scan at a time (default is 32)"],
    "-s"   => [ true,   "The directory to store the raw XML files from the Nexpose instance (optional)"],
    "-P"   => [ false,  "Leave the scan data on the server when it completes (this counts against the maximum licensed IPs)"],
    "-v"   => [ false,  "Display diagnostic information about the scanning process"],
    "-d"   => [ false,  "Scan hosts based on the contents of the existing database"],
    "-I"   => [ true,   "Only scan systems with an address within the specified range"],
    "-E"   => [ true,   "Exclude hosts in the specified range from the scan"]
  )

  opt_template  = "pentest-audit"
  opt_maxaddrs  = 32
  opt_monitor   = false
  opt_verbose   = false
  opt_savexml   = nil
  opt_preserve  = false
  opt_rescandb  = false
  opt_addrinc   = nil
  opt_addrexc   = nil
  opt_scanned   = []
  opt_credentials = []

  opt_ranges    = []


  opts.parse(args) do |opt, idx, val|
    case opt
    when "-h"
      print_line("Usage: nexpose_scan [options] <Target IP Ranges>")
      print_line(opts.usage)
      return
    when "-t"
      opt_template = val
    when "-n"
      opt_maxaddrs = val.to_i
    when "-s"
      opt_savexml = val
    when "-c"
      if (val =~ /^([^:]+):([^:]+):(.+)/)
        type, user, pass = [ $1, $2, $3 ]
        msfid = Time.now.to_i
        newcreds = Nexpose::SiteCredentials.for_service("Metasploit Site Credential #{msfid}", nil, nil, nil, nil, type)
        newcreds.user_name = user
        newcreds.password = pass
        opt_credentials << newcreds
      else
        print_error("Unrecognized Nexpose scan credentials: #{val}")
        return
      end
    when "-v"
      opt_verbose = true
    when "-P"
      opt_preserve = true
    when "-d"
      opt_rescandb = true
    when '-I'
      opt_addrinc = OptAddressRange.new('TEMPRANGE', [ true, '' ]).normalize(val)
    when '-E'
      opt_addrexc = OptAddressRange.new('TEMPRANGE', [ true, '' ]).normalize(val)
    else
      opt_ranges << val
    end
  end

  return if not nexpose_verify

  # Include all database hosts as scan targets if specified
  if(opt_rescandb)
    print_status("Loading scan targets from the active database...") if opt_verbose
    framework.db.hosts.each do |host|
      next if host.state != ::Msf::HostState::Alive
      opt_ranges << host.address
    end
  end

  possible_files = opt_ranges # don't allow DOS by circular reference
  possible_files.each do |file|
    if ::File.readable? file
      print_status "Parsing ranges from #{file}"
      range_list = ::File.open(file,"rb") {|f| f.read f.stat.size}
      range_list.each_line { |subrange| opt_ranges << subrange}
      opt_ranges.delete(file)
    end
  end

  opt_ranges = opt_ranges.join(' ')

  if(opt_ranges.strip.empty?)
    print_line("Usage: nexpose_scan [options] <Target IP Ranges>")
    print_line(opts.usage)
    return
  end

  if(opt_verbose)
    print_status("Creating a new scan using template #{opt_template} and #{opt_maxaddrs} concurrent IPs against #{opt_ranges}")
  end

  range_inp = ::Msf::OptAddressRange.new('TEMPRANGE', [ true, '' ]).normalize(opt_ranges)
  range     = ::Rex::Socket::RangeWalker.new(range_inp)
  include_range = opt_addrinc ? ::Rex::Socket::RangeWalker.new(opt_addrinc) : nil
  exclude_range = opt_addrexc ? ::Rex::Socket::RangeWalker.new(opt_addrexc) : nil

  completed = 0
  total     = range.num_ips
  count     = 0

  print_status("Scanning #{total} addresses with template #{opt_template} in sets of #{opt_maxaddrs}")

  while(completed < total)
    count    += 1
    queue     = []

    while(ip = range.next_ip and queue.length < opt_maxaddrs)

      if(exclude_range and exclude_range.include?(ip))
        print_status(" >> Skipping host #{ip} due to exclusion") if opt_verbose
        next
      end

      if(include_range and ! include_range.include?(ip))
        print_status(" >> Skipping host #{ip} due to inclusion filter") if opt_verbose
        next
      end

      opt_scanned << ip
      queue << ip
    end

    break if queue.empty?
    print_status("Scanning #{queue[0]}-#{queue[-1]}...") if opt_verbose

    msfid = Time.now.to_i

    # Create a temporary site
    site = Nexpose::Site.new(nil, opt_template)
    site.name = "Metasploit-#{msfid}"
    site.description = "Autocreated by the Metasploit Framework"
    site.included_addresses = queue
    site.site_credentials = opt_credentials
    site.save(@nsc)

    print_status(" >> Created temporary site ##{site.id}") if opt_verbose

    report_formats = ["raw-xml-v2", "ns-xml"]
    report_format  = report_formats.shift

    report = Nexpose::ReportConfig.build(@nsc, site.id, site.name, opt_template, report_format, true)
    report.delivery = Nexpose::Delivery.new(true)

    begin
      report.format = report_format
      report.save(@nsc, true)
    rescue ::Exception => e
    report_format = report_formats.shift
      if report_format
        retry
      end
      raise e
    end

    print_status(" >> Created temporary report configuration ##{report.id}") if opt_verbose

    # Run the scan
    begin
      res = site.scan(@nsc)
    rescue Nexpose::APIError => e
      nexpose_error_message = e.message
      nexpose_error_message.gsub!(/NexposeAPI: Action failed: /, '')
      print_error "#{nexpose_error_message}"
      return
    end

    sid = res.id

    print_status(" >> Scan has been launched with ID ##{sid}") if opt_verbose

    rep = true
    begin
    prev = nil
    while(true)
      info = @nsc.scan_statistics(sid)
      break if info.status != "running"
      stat = "Found #{info.nodes.live} devices and #{info.nodes.dead} unresponsive"
      if(stat != prev)
        print_status(" >> #{stat}") if opt_verbose
      end
      prev = stat
      select(nil, nil, nil, 5.0)
    end
    print_status(" >> Scan has been completed with ID ##{sid}") if opt_verbose
    rescue ::Interrupt
      rep = false
      print_status(" >> Terminating scan ID ##{sid} due to console interupt") if opt_verbose
      @nsc.stop_scan(sid)
      break
    end

    # Wait for the automatic report generation to complete
    if(rep)
      print_status(" >> Waiting on the report to generate...") if opt_verbose
      last_report = nil
      while(! last_report)
        last_report = @nsc.last_report(report.id)
        select(nil, nil, nil, 1.0)
      end
      url = last_report.uri

      print_status(" >> Downloading the report data from Nexpose...") if opt_verbose
      data = @nsc.download(url)

      if(opt_savexml)
        ::FileUtils.mkdir_p(opt_savexml)
        path = ::File.join(opt_savexml, "nexpose-#{msfid}-#{count}.xml")
        print_status(" >> Saving scan data into #{path}") if opt_verbose
        ::File.open(path, "wb") { |fd| fd.write(data) }
      end

      process_nexpose_data(report_format, data)
    end

    if ! opt_preserve
      # Make sure the scan has finished clean up before attempting to delete the site
      while (true)
        info = @nsc.scan_statistics(sid)
        break if info.status == 'stopped' || info.status == 'finished'
        select(nil, nil, nil, 5.0)
      end
      print_status(" >> Deleting the temporary site and report...") if opt_verbose
      begin
        @nsc.delete_site(site.id)
      rescue ::Nexpose::APIError => e
        print_status(" >> Deletion of temporary site and report failed: #{e.inspect}")
      end
    end
  end

  print_status("Completed the scan of #{total} addresses")
end

#cmd_nexpose_site_devices(*args) ⇒ Object


227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'plugins/nexpose.rb', line 227

def cmd_nexpose_site_devices(*args)
  return if not nexpose_verify

  site_id = args.shift
  if not site_id
    print_error("No site ID was specified")
    return
  end

  devices = @nsc.list_site_devices(site_id) || []
  case devices.length
  when 0
    print_status("There are currently no devices within this site")
  end

  devices.each do |device|
    print_status("    Host: #{device.address} ID: #{device.id} Risk Factor: #{device.risk_factor} Risk Score: #{device.risk_score}")
  end
end

#cmd_nexpose_site_import(*args) ⇒ Object


293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'plugins/nexpose.rb', line 293

def cmd_nexpose_site_import(*args)
  site_id = args.shift
  if not site_id
    print_error("No site ID was specified")
    return
  end

  msfid = Time.now.to_i

  report_formats = ["raw-xml-v2", "ns-xml"]
  report_format  = report_formats.shift

  report = Nexpose::ReportConfig.build(@nsc, site_id, "Metasploit Export #{msfid}", "pentest-audit", report_format, true)
  report.delivery = Nexpose::Delivery.new(true)

  begin
    report.format = report_format
    report.save(@nsc)
  rescue ::Exception => e
    report_format = report_formats.shift
    if report_format
      retry
    end
    raise e
  end

  print_status("Generating the export data file...")
  last_report = nil
  while(! last_report)
    last_report = @nsc.last_report(report.id)
    select(nil, nil, nil, 1.0)
  end
  url = last_report.uri

  print_status("Downloading the export data...")
  data = @nsc.download(url)

  # Delete the temporary report ID
  @nsc.delete_report_config(report.id)

  print_status("Importing Nexpose data...")
  process_nexpose_data(report_format, data)

end

#cmd_nexpose_sites(*args) ⇒ Object


213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'plugins/nexpose.rb', line 213

def cmd_nexpose_sites(*args)
  return if not nexpose_verify

  sites = @nsc.list_sites || []
  case sites.length
  when 0
    print_status("There are currently no active sites on this Nexpose instance")
  end

  sites.each do |site|
    print_status("    Site ##{site.id} '#{site.name}' Risk Factor: #{site.risk_factor} Risk Score: #{site.risk_score}")
  end
end

#cmd_nexpose_sysinfo(*args) ⇒ Object


273
274
275
276
277
278
279
280
281
282
# File 'plugins/nexpose.rb', line 273

def cmd_nexpose_sysinfo(*args)
  return if not nexpose_verify

  res = @nsc.system_information

  print_status("System Information")
  res.each_pair do |k,v|
    print_status("    #{k}: #{v}")
  end
end

#commandsObject


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'plugins/nexpose.rb', line 21

def commands
  {
    'nexpose_connect'        => "Connect to a running Nexpose instance ( user:[email protected][:port] )",
    'nexpose_save'           => "Save credentials to a Nexpose instance",
    'nexpose_activity'       => "Display any active scan jobs on the Nexpose instance",

    'nexpose_scan'           => "Launch a Nexpose scan against a specific IP range and import the results",
    'nexpose_discover'       => "Launch a scan but only perform host and minimal service discovery",
    'nexpose_exhaustive'     => "Launch a scan covering all TCP ports and all authorized safe checks",
    'nexpose_dos'            => "Launch a scan that includes checks that can crash services and devices (caution)",

    'nexpose_disconnect'     => "Disconnect from an active Nexpose instance",

    'nexpose_sites'          => "List all defined sites",
    'nexpose_site_devices'   => "List all discovered devices within a site",
    'nexpose_site_import'    => "Import data from the specified site ID",
    'nexpose_report_templates' => "List all available report templates",
    'nexpose_command'        => "Execute a console command on the Nexpose instance",
    'nexpose_sysinfo'        => "Display detailed system information about the Nexpose instance",

    # TODO:
    # nexpose_stop_scan
  }
end

#nameObject


17
18
19
# File 'plugins/nexpose.rb', line 17

def name
  "Nexpose"
end

#nexpose_compatibility_checkObject


284
285
286
287
288
289
290
291
# File 'plugins/nexpose.rb', line 284

def nexpose_compatibility_check
  res = @nsc.console_command("ver")
  if res !~ /^(NSC|Console) Version ID:\s*4[89]0\s*$/m
    print_error("")
    print_error("Warning: This version of Nexpose has not been tested with Metasploit!")
    print_error("")
  end
end

#nexpose_loginObject


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'plugins/nexpose.rb', line 157

def 

  if ! ((@user and @user.length > 0) and (@host and @host.length > 0) and (@port and @port.length > 0 and @port.to_i > 0) and (@pass and @pass.length > 0))
    nexpose_usage
    return
  end

  if(@host != "localhost" and @host != "127.0.0.1" and (@trust_cert.nil? && @sslv != "ok"))
    # consider removing this message and replacing with check on trust_store, and if trust_store is not found validate @host already has a truly trusted cert?
    print_error("Warning: SSL connections are not verified in this release, it is possible for an attacker")
    print_error("         with the ability to man-in-the-middle the Nexpose traffic to capture the Nexpose")
    print_error("         credentials. If you are running this on a trusted network, please pass in 'ok'")
    print_error("         as an additional parameter to this command.")
    return
  end

  # Wrap this so a duplicate session does not prevent a new login
  begin
    cmd_nexpose_disconnect
  rescue ::Interrupt
    raise $!
  rescue ::Exception
  end

  begin
    print_status("Connecting to Nexpose instance at #{@host}:#{@port} with username #{@user}...")
    nsc = Nexpose::Connection.new(@host, @user, @pass, @port, nil, nil, @trust_cert)
    nsc.
  rescue ::Nexpose::APIError => e
    print_error("Connection failed: #{e.reason}")
    return
  end

  @nsc = nsc
  nexpose_compatibility_check
  nsc
end

#nexpose_usageObject


150
151
152
153
154
155
# File 'plugins/nexpose.rb', line 150

def nexpose_usage
  print_status("Usage: ")
  print_status("       nexpose_connect username:[email protected][:port] <ssl-confirm || trusted_cert_file>")
  print_status("        -OR- ")
  print_status("       nexpose_connect username password host port <ssl-confirm || trusted_cert_file>")
end

#nexpose_verifyObject


55
56
57
58
59
60
61
62
63
64
# File 'plugins/nexpose.rb', line 55

def nexpose_verify
  return false if not nexpose_verify_db

  if ! @nsc
    print_error("No active Nexpose instance has been configured, please use 'nexpose_connect'")
    return false
  end

  true
end

#nexpose_verify_dbObject


46
47
48
49
50
51
52
53
# File 'plugins/nexpose.rb', line 46

def nexpose_verify_db
  if ! (framework.db and framework.db.usable and framework.db.active)
    print_error("No database has been configured, please use db_create/db_connect first")
    return false
  end

  true
end

#nexpose_vuln_lookup(doc, vid, refs, host, serv = nil) ⇒ Object

Nexpose vuln lookup


622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
# File 'plugins/nexpose.rb', line 622

def nexpose_vuln_lookup(doc, vid, refs, host, serv=nil)
  doc.elements.each("/NexposeReport/VulnerabilityDefinitions/vulnerability[@id = '#{vid}']]") do |vulndef|

    title = vulndef.attributes['title']
    pciSeverity = vulndef.attributes['pciSeverity']
    cvss_score = vulndef.attributes['cvssScore']
    cvss_vector = vulndef.attributes['cvssVector']

    vulndef.elements['references'].elements.each('reference') do |ref|
      if ref.attributes['source'] == 'BID'
        refs[ 'BID-' + ref.text ] = true
      elsif ref.attributes['source'] == 'CVE'
        # ref.text is CVE-$ID
        refs[ ref.text ] = true
      elsif ref.attributes['source'] == 'MS'
        refs[ 'MSB-MS-' + ref.text ] = true
      end
    end

    refs[ 'NEXPOSE-' + vid.downcase ] = true

    vuln = framework.db.find_or_create_vuln(
      :host => host,
      :service => serv,
      :name => 'NEXPOSE-' + vid.downcase,
      :data => title)

    rids = []
    refs.keys.each do |r|
      rids << framework.db.find_or_create_ref(:name => r)
    end

    vuln.refs << (rids - vuln.refs)
  end
end

#process_nexpose_data(fmt, data) ⇒ Object


608
609
610
611
612
613
614
615
616
617
# File 'plugins/nexpose.rb', line 608

def process_nexpose_data(fmt, data)
  case fmt
  when 'raw-xml-v2'
    framework.db.import({:data => data})
  when 'ns-xml'
    framework.db.import({:data => data})
  else
    print_error("Unsupported Nexpose data format: #{fmt}")
  end
end