CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/plugins/nessus.rb
Views: 11704
1
# $Id$ $Revision$
2
require 'nessus_rest'
3
4
module Msf
5
PLUGIN_NAME = 'Nessus'.freeze
6
PLUGIN_DESCRIPTION = 'Nessus Bridge for Metasploit'.freeze
7
8
class Plugin::Nessus < Msf::Plugin
9
10
def name
11
PLUGIN_NAME
12
end
13
14
def desc
15
PLUGIN_DESCRIPTION
16
end
17
18
class ConsoleCommandDispatcher
19
include Msf::Ui::Console::CommandDispatcher
20
21
def name
22
PLUGIN_NAME
23
end
24
25
def xindex
26
"#{Msf::Config.config_directory}/nessus_index"
27
end
28
29
def nessus_yaml
30
"#{Msf::Config.config_directory}/nessus.yaml"
31
end
32
33
def msf_local
34
Msf::Config.local_directory.to_s
35
end
36
37
def commands
38
{
39
'nessus_connect' => 'Connect to a nessus server: nconnect username:password@hostname:port <verify_ssl>',
40
'nessus_admin' => 'Checks if user is an admin',
41
'nessus_help' => 'Get help on all commands',
42
'nessus_logout' => 'Terminate the session',
43
'nessus_server_status' => 'Check the status of your Nessus server',
44
'nessus_server_properties' => 'Nessus server properties such as feed type, version, plugin set and server UUID',
45
'nessus_report_download' => 'Download a report from the nessus server in either Nessus, HTML, PDF, CSV, or DB format',
46
'nessus_report_vulns' => 'Get list of vulns from a report',
47
'nessus_report_hosts' => 'Get list of hosts from a report',
48
'nessus_report_host_details' => 'Get detailed information from a report item on a host',
49
'nessus_scan_list' => 'List of currently running Nessus scans',
50
'nessus_scan_new' => 'Create a new Nessus scan',
51
'nessus_scan_launch' => 'Launch a previously added scan',
52
'nessus_scan_pause' => 'Pause a running Nessus scan',
53
'nessus_scan_pause_all' => 'Pause all running Nessus scans',
54
'nessus_scan_stop' => 'Stop a running or paused Nessus scan',
55
'nessus_scan_stop_all' => 'Stop all running or paused Nessus scans',
56
'nessus_scan_resume' => 'Resume a paused Nessus scan',
57
'nessus_scan_resume_all' => 'Resume all paused Nessus scans',
58
'nessus_scan_details' => 'Return detailed information of a given scan',
59
'nessus_scan_export' => 'Export a scan result in either Nessus, HTML, PDF, CSV, or DB format',
60
'nessus_scan_export_status' => 'Check the status of scan export',
61
'nessus_user_list' => 'List of Nessus users',
62
'nessus_user_add' => 'Add a new Nessus user',
63
'nessus_user_del' => 'Delete a Nessus user',
64
'nessus_user_passwd' => 'Change Nessus Users Password',
65
'nessus_plugin_details' => 'List details of a particular plugin',
66
'nessus_plugin_list' => 'Display plugin details in a particular plugin family',
67
'nessus_policy_list' => 'List all polciies',
68
'nessus_policy_del' => 'Delete a policy',
69
'nessus_index' => 'Manually generates a search index for exploits',
70
'nessus_template_list' => 'List all the templates on the server',
71
'nessus_db_scan' => 'Create a scan of all IP addresses in db_hosts',
72
'nessus_db_scan_workspace' => 'Create a scan of all IP addresses in db_hosts for a given workspace',
73
'nessus_db_import' => 'Import Nessus scan to the Metasploit connected database',
74
'nessus_save' => 'Save credentials of the logged in user to nessus.yml',
75
'nessus_folder_list' => 'List folders configured on the Nessus server',
76
'nessus_scanner_list' => 'List the configured scanners on the Nessus server',
77
'nessus_family_list' => 'List all the plugin families along with their corresponding family IDs and plugin count'
78
}
79
end
80
81
def ncusage
82
print_status('%redYou must do this before any other commands.%clr')
83
print_status('Usage: ')
84
print_status('nessus_connect username:password@hostname:port <ssl_verify>')
85
print_status('Example:> nessus_connect msf:[email protected]:8834')
86
print_status('OR')
87
print_status('nessus_connect username@hostname:port ssl_verify')
88
print_status('Example:> nessus_connect [email protected]:8834 ssl_verify')
89
print_status('OR')
90
print_status('nessus_connect hostname:port ssl_verify')
91
print_status('Example:> nessus_connect 192.168.1.10:8834 ssl_verify')
92
print_status('OR')
93
print_status('nessus_connect')
94
print_status('Example:> nessus_connect')
95
print_status('This only works after you have saved creds with nessus_save')
96
return
97
end
98
99
# creates the index of exploit details to make searching for exploits much faster.
100
def create_xindex
101
start = Time.now
102
print_status("Creating Exploit Search Index - (#{xindex}) - this won't take long.")
103
# Use Msf::Config.config_directory as the location.
104
File.open(xindex.to_s, 'w+') do |f|
105
# need to add version line.
106
f.puts(Msf::Framework::Version)
107
framework.exploits.each_module do |refname, mod|
108
stuff = ''
109
o = nil
110
begin
111
o = mod.new
112
rescue ::Exception
113
end
114
stuff << "#{refname}|#{o.name}|#{o.platform_to_s}|#{o.arch_to_s}"
115
next if !o
116
117
o.references.map do |x|
118
if x.ctx_id != 'URL'
119
if (x.ctx_id == 'MSB')
120
stuff << "|#{x.ctx_val}"
121
else
122
stuff << "|#{x.ctx_id}-#{x.ctx_val}"
123
end
124
end
125
end
126
stuff << "\n"
127
f.puts(stuff)
128
end
129
end
130
total = Time.now - start
131
print_status("It has taken : #{total} seconds to build the exploits search index")
132
end
133
134
def nessus_index
135
if File.exist?(xindex.to_s)
136
# check if it's version line matches current version.
137
File.open(xindex.to_s) do |f|
138
line = f.readline
139
line.chomp!
140
if line.to_i == Msf::Framework::RepoRevision
141
print_good("Exploit Index - (#{xindex}) - is valid.")
142
else
143
create_xindex
144
end
145
end
146
else
147
create_xindex
148
end
149
end
150
151
def nessus_login
152
if !((@user && !@user.empty?) && (@host && !@host.empty?) && (@port && !@port.empty? && (@port.to_i > 0)) && (@pass && !@pass.empty?))
153
print_status('You need to connect to a server first.')
154
ncusage
155
return
156
end
157
@url = "https://#{@host}:#{@port}/"
158
print_status("Connecting to #{@url} as #{@user}")
159
verify_ssl = false
160
if @sslv == 'verify_ssl'
161
verify_ssl = true
162
end
163
@n = NessusREST::Client.new(url: @url, username: @user, password: @pass, ssl_verify: verify_ssl)
164
if @n.authenticated
165
print_status("User #{@user} authenticated successfully.")
166
@token = 1
167
else
168
print_error('Error connecting/logging to the server!')
169
return
170
end
171
end
172
173
def nessus_verify_token
174
if @token.nil? || (@token == '')
175
ncusage
176
return false
177
end
178
true
179
end
180
181
def valid_policy(*args)
182
case args.length
183
when 1
184
pid = args[0]
185
else
186
print_error('No Policy ID supplied.')
187
return
188
end
189
pol = @n.list_policies
190
pol['policies'].each do |p|
191
if p['template_uuid'] == pid
192
return true
193
end
194
end
195
return false
196
end
197
198
def nessus_verify_db
199
if !(framework.db && framework.db.active)
200
print_error('No database has been configured, please use db_connect first')
201
return false
202
end
203
true
204
end
205
206
def check_scan(*args)
207
case args.length
208
when 1
209
scan_id = args[0]
210
else
211
print_error('No scan ID supplied')
212
return
213
end
214
scans = @n.scan_list
215
scans.each do |scan|
216
if scan['scans']['id'] == scan_id && scan['scans']['status'] == 'completed'
217
return true
218
end
219
end
220
return false
221
end
222
223
def is_scan_complete(scan_id)
224
complete = false
225
status = @n.scan_list
226
status['scans'].each do |scan|
227
if scan['id'] == scan_id.to_i && (scan['status'] == 'completed' || scan['status'] == 'imported')
228
complete = true
229
end
230
end
231
complete
232
end
233
234
def cmd_nessus_help(*_args)
235
tbl = Rex::Text::Table.new(
236
'Columns' => [
237
'Command',
238
'Help Text'
239
],
240
'SortIndex' => -1
241
)
242
tbl << [ 'Generic Commands', '' ]
243
tbl << [ '-----------------', '-----------------']
244
tbl << [ 'nessus_connect', 'Connect to a Nessus server' ]
245
tbl << [ 'nessus_logout', 'Logout from the Nessus server' ]
246
tbl << [ 'nessus_login', 'Login into the connected Nesssus server with a different username and password']
247
tbl << [ 'nessus_save', 'Save credentials of the logged in user to nessus.yml']
248
tbl << [ 'nessus_help', 'Listing of available nessus commands' ]
249
tbl << [ 'nessus_server_properties', 'Nessus server properties such as feed type, version, plugin set and server UUID.' ]
250
tbl << [ 'nessus_server_status', 'Check the status of your Nessus Server' ]
251
tbl << [ 'nessus_admin', 'Checks if user is an admin' ]
252
tbl << [ 'nessus_template_list', 'List scan or policy templates' ]
253
tbl << [ 'nessus_folder_list', 'List all configured folders on the Nessus server' ]
254
tbl << [ 'nessus_scanner_list', 'List all the scanners configured on the Nessus server' ]
255
tbl << [ 'Nessus Database Commands', '' ]
256
tbl << [ '-----------------', '-----------------' ]
257
tbl << [ 'nessus_db_scan', 'Create a scan of all IP addresses in db_hosts' ]
258
tbl << [ 'nessus_db_scan_workspace', 'Create a scan of all IP addresses in db_hosts for a given workspace' ]
259
tbl << [ 'nessus_db_import', 'Import Nessus scan to the Metasploit connected database' ]
260
tbl << [ '', '']
261
tbl << [ 'Reports Commands', '' ]
262
tbl << [ '-----------------', '-----------------']
263
tbl << [ 'nessus_report_hosts', 'Get list of hosts from a report' ]
264
tbl << [ 'nessus_report_vulns', 'Get list of vulns from a report' ]
265
tbl << [ 'nessus_report_host_details', 'Get detailed information from a report item on a host' ]
266
tbl << [ '', '']
267
tbl << [ 'Scan Commands', '' ]
268
tbl << [ '-----------------', '-----------------']
269
tbl << [ 'nessus_scan_list', 'List of all current Nessus scans' ]
270
tbl << [ 'nessus_scan_new', 'Create a new Nessus Scan' ]
271
tbl << [ 'nessus_scan_launch', 'Launch a newly created scan. New scans need to be manually launched through this command' ]
272
tbl << [ 'nessus_scan_pause', 'Pause a running Nessus scan' ]
273
tbl << [ 'nessus_scan_pause_all', 'Pause all running Nessus scans' ]
274
tbl << [ 'nessus_scan_stop', 'Stop a running or paused Nessus scan' ]
275
tbl << [ 'nessus_scan_stop_all', 'Stop all running or paused Nessus scans' ]
276
tbl << [ 'nessus_scan_resume', 'Resume a pasued Nessus scan' ]
277
tbl << [ 'nessus_scan_resume_all', 'Resume all paused Nessus scans' ]
278
tbl << [ 'nessus_scan_details', 'Return detailed information of a given scan' ]
279
tbl << [ 'nessus_scan_export', 'Export a scan result in either Nessus, HTML, PDF, CSV, or DB format' ]
280
tbl << [ 'nessus_scan_export_status', 'Check the status of an exported scan' ]
281
tbl << [ '', '']
282
tbl << [ 'Plugin Commands', '' ]
283
tbl << [ '-----------------', '-----------------']
284
tbl << [ 'nessus_plugin_list', 'List all plugins in a particular plugin family.' ]
285
tbl << [ 'nessus_family_list', 'List all the plugin families along with their corresponding family IDs and plugin count.' ]
286
tbl << [ 'nessus_plugin_details', 'List details of a particular plugin' ]
287
tbl << [ '', '']
288
tbl << [ 'User Commands', '' ]
289
tbl << [ '-----------------', '-----------------']
290
tbl << [ 'nessus_user_list', 'Show Nessus Users' ]
291
tbl << [ 'nessus_user_add', 'Add a new Nessus User' ]
292
tbl << [ 'nessus_user_del', 'Delete a Nessus User' ]
293
tbl << [ 'nessus_user_passwd', 'Change Nessus Users Password' ]
294
tbl << [ '', '']
295
tbl << [ 'Policy Commands', '' ]
296
tbl << [ '-----------------', '-----------------']
297
tbl << [ 'nessus_policy_list', 'List all polciies' ]
298
tbl << [ 'nessus_policy_del', 'Delete a policy' ]
299
print_line ''
300
print_line tbl.to_s
301
print_line ''
302
end
303
304
def cmd_nessus_index
305
nessus_index
306
end
307
308
def cmd_nessus_connect(*args)
309
# Check if config file exists and load it
310
if !args[0]
311
if File.exist?(nessus_yaml)
312
lconfig = YAML.load_file(nessus_yaml)
313
@user = lconfig['default']['username'].to_s
314
@pass = lconfig['default']['password'].to_s
315
@host = lconfig['default']['server'].to_s
316
@port = lconfig['default']['port'].to_s
317
nessus_login
318
else
319
ncusage
320
end
321
return
322
end
323
324
if args[0] == '-h'
325
print_status('%redYou must do this before any other commands.%clr')
326
print_status('Usage: ')
327
print_status('nessus_connect username:password@hostname:port <ssl_verify/ssl_ignore>')
328
print_status('%bldusername%clr and %bldpassword%clr are the ones you use to login to the nessus web front end')
329
print_status('%bldhostname%clr can be an IP address or a DNS name of the Nessus server.')
330
print_status('%bldport%clr is the RPC port that the Nessus web front end runs on. By default it is TCP port 8834.')
331
print_status('The "ssl_verify" to verify the SSL certificate used by the Nessus front end. By default the server')
332
print_status('use a self signed certificate, therefore, users should use ssl_ignore.')
333
return
334
end
335
336
if !@token == ''
337
print_error('You are already authenticated. Call nessus_logout before authenticating again')
338
return
339
end
340
if (args.empty? || args[0].empty?)
341
ncusage
342
return
343
end
344
345
@user = @pass = @host = @port = @sslv = nil
346
case args.length
347
when 1, 2
348
if args[0].include? '@'
349
cred, _split, targ = args[0].rpartition('@')
350
@user, @pass = cred.split(':', 2)
351
targ ||= '127.0.0.1:8834'
352
@host, @port = targ.split(':', 2)
353
else
354
@host, @port = args[0].split(':', 2)
355
end
356
@port ||= '8834'
357
@sslv = args[1]
358
when 3, 4, 5
359
ncusage
360
return
361
else
362
ncusage
363
return
364
end
365
if %r{//}.match(@host)
366
ncusage
367
return
368
end
369
if !@user
370
print_error('Missing Username')
371
ncusage
372
return
373
end
374
if !@pass
375
print_error('Missing Password')
376
ncusage
377
return
378
end
379
if !((@user && !@user.empty?) && (@host && !@host.empty?) && (@port && !@port.empty? && (@port.to_i > 0)) && (@pass && !@pass.empty?))
380
ncusage
381
return
382
end
383
nessus_login
384
end
385
386
def cmd_nessus_logout
387
logout = @n.user_logout
388
status = logout.to_s
389
if status == '200'
390
print_good('User account logged out successfully')
391
@token = ''
392
elsif status == '403'
393
print_status('No user session to logout')
394
else
395
print_error("There was some problem in logging out the user #{@user}")
396
end
397
return
398
end
399
400
def cmd_nessus_save(*args)
401
# if we are logged in, save session details to nessus.yaml
402
if args[0] == '-h'
403
print_status(' nessus_save')
404
return
405
end
406
if args[0]
407
print_status('Usage: ')
408
print_status('nessus_save')
409
return
410
end
411
group = 'default'
412
if ((@user && !@user.empty?) && (@host && !@host.empty?) && (@port && !@port.empty? && (@port.to_i > 0)) && (@pass && !@pass.empty?))
413
config = Hash.new
414
config = { group.to_s => { 'username' => @user, 'password' => @pass, 'server' => @host, 'port' => @port } }
415
File.open(nessus_yaml.to_s, 'w+') do |f|
416
f.puts YAML.dump(config)
417
end
418
print_good("#{nessus_yaml} created.")
419
else
420
print_error('Missing username/password/server/port - relogin and then try again.')
421
return
422
end
423
end
424
425
def cmd_nessus_server_properties(*args)
426
search_term = nil
427
while (arg = args.shift)
428
case arg
429
when '-h', '--help'
430
print_status('nessus_server_properties')
431
print_status('Example:> nessus_server_properties -S searchterm')
432
print_status('Returns information about the feed type and server version.')
433
return
434
when '-S', '--search'
435
search_term = /#{args.shift}/nmi
436
end
437
end
438
439
resp = @n.server_properties
440
tbl = Rex::Text::Table.new(
441
'SearchTerm' => search_term,
442
'Columns' => [
443
'Feed',
444
'Type',
445
'Nessus Version',
446
'Nessus Web Version',
447
'Plugin Set',
448
'Server UUID'
449
]
450
)
451
tbl << [ resp['feed'], resp['nessus_type'], resp['server_version'], resp['nessus_ui_version'], resp['loaded_plugin_set'], resp['server_uuid'] ]
452
print_line tbl.to_s
453
end
454
455
def cmd_nessus_server_status(*args)
456
search_term = nil
457
while (arg = args.shift)
458
case arg
459
when '-h', '--help'
460
print_status('nessus_server_status')
461
print_status('Example:> nessus_server_status -S searchterm')
462
print_status('Returns some status items for the server..')
463
return
464
when '-S', '--search'
465
search_term = /#{args.shift}/nmi
466
end
467
end
468
469
tbl = Rex::Text::Table.new(
470
'SearchTerm' => search_term,
471
'Columns' => [
472
'Status',
473
'Progress'
474
]
475
)
476
list = @n.server_status
477
tbl << [ list['progress'], list['status'] ]
478
print_line tbl.to_s
479
end
480
481
def cmd_nessus_admin(*args)
482
while (arg = args.shift)
483
case arg
484
when '-h', '--help'
485
print_status('nessus_admin')
486
print_status('Example:> nessus_admin')
487
print_status('Checks to see if the current user is an admin')
488
print_status('Use nessus_user_list to list all users')
489
return
490
end
491
end
492
493
if !nessus_verify_token
494
return
495
end
496
497
if !@n.is_admin
498
print_error('Your Nessus user is not an admin')
499
else
500
print_good('Your Nessus user is an admin')
501
end
502
end
503
504
def cmd_nessus_template_list(*args)
505
search_term = nil
506
while (arg = args.shift)
507
case arg
508
when '-h', '--help'
509
print_status('nessus_template_list <scan> | <policy>')
510
print_status('Example:> nessus_template_list scan -S searchterm')
511
print_status('OR')
512
print_status('nessus_template_list policy')
513
print_status('Returns a list of information about the scan or policy templates..')
514
return
515
when '-S', '--search'
516
search_term = /#{args.shift}/nmi
517
else
518
type = arg
519
end
520
end
521
522
if !nessus_verify_token
523
return
524
end
525
526
if type.in?(['scan', 'policy'])
527
list = @n.list_templates(type)
528
else
529
print_error('Only scan and policy are valid templates')
530
return
531
end
532
if list.empty?
533
print_status('No templates created')
534
return
535
end
536
tbl = Rex::Text::Table.new(
537
'SearchTerm' => search_term,
538
'Columns' => [
539
'Name',
540
'Title',
541
'Description',
542
'Subscription Only',
543
'Cloud Only'
544
]
545
)
546
list['templates'].each do |template|
547
tbl << [ template['name'], template['title'], template['desc'], template['subscription_only'], template['cloud_only'] ]
548
end
549
print_line
550
print_line tbl.to_s
551
end
552
553
def cmd_nessus_folder_list(*args)
554
search_term = nil
555
while (arg = args.shift)
556
case arg
557
when '-S', '--search'
558
search_term = /#{args.shift}/nmi
559
end
560
end
561
if !nessus_verify_token
562
return
563
end
564
565
list = @n.list_folders
566
tbl = Rex::Text::Table.new(
567
'SearchTerm' => search_term,
568
'Columns' => [
569
'ID',
570
'Name',
571
'Type'
572
]
573
)
574
list['folders'].each do |folder|
575
tbl << [ folder['id'], folder['name'], folder['type'] ]
576
end
577
print_line
578
print_line tbl.to_s
579
end
580
581
def cmd_nessus_scanner_list(*args)
582
search_term = nil
583
while (arg = args.shift)
584
case arg
585
when '-h', '--help'
586
print_status('nessus_scanner_list')
587
print_status('Example:> nessus_scanner_list -S searchterm')
588
print_status('Returns information about the feed type and server version.')
589
return
590
when '-S', '--search'
591
search_term = /#{args.shift}/nmi
592
end
593
end
594
if !nessus_verify_token
595
return
596
end
597
if !@n.is_admin
598
return
599
end
600
601
list = @n.list_scanners
602
tbl = Rex::Text::Table.new(
603
'SearchTerm' => search_term,
604
'Columns' => [
605
'ID',
606
'Name',
607
'Status',
608
'Platform',
609
'Plugin Set',
610
'UUID'
611
]
612
)
613
list.each do |scanner|
614
tbl << [ scanner['id'], scanner['name'], scanner['status'], scanner['platform'], scanner['loaded_plugin_set'], scanner['uuid'] ]
615
end
616
print_line tbl.to_s
617
end
618
619
def cmd_nessus_report_hosts(*args)
620
search_term = nil
621
scan_id = nil
622
while (arg = args.shift)
623
case arg
624
when '-h', '--help'
625
print_status('nessus_report_hosts <scan ID> -S searchterm')
626
print_status('Use nessus_scan_list to get a list of all the scans. Only completed scans can be reported.')
627
return
628
when '-S', '--search'
629
search_term = /#{args.shift}/nmi
630
else
631
scan_id = arg
632
end
633
end
634
635
if scan_id.nil?
636
print_status('Usage: ')
637
print_status('nessus_report_hosts <scan ID> -S searchterm')
638
print_status('Use nessus_scan_list to get a list of all the scans. Only completed scans can be reported.')
639
return
640
end
641
642
tbl = Rex::Text::Table.new(
643
'SearchTerm' => search_term,
644
'Columns' => [
645
'Host ID',
646
'Hostname',
647
'% of Critical Findings',
648
'% of High Findings',
649
'% of Medium Findings',
650
'% of Low Findings'
651
]
652
)
653
if is_scan_complete(scan_id)
654
details = @n.scan_details(scan_id)
655
details['hosts'].each do |host|
656
tbl << [ host['host_id'], host['hostname'], host['critical'], host['high'], host['medium'], host['low'] ]
657
end
658
print_line
659
print_line tbl.to_s
660
else
661
print_error('Only completed scans can be used for host reporting')
662
return
663
end
664
end
665
666
def cmd_nessus_report_vulns(*args)
667
search_term = nil
668
scan_id = nil
669
while (arg = args.shift)
670
case arg
671
when '-h', '--help'
672
print_status('nessus_report_vulns <scan ID> -S searchterm')
673
print_status('Use nessus_scan_list to get a list of all the scans. Only completed scans can be reported.')
674
return
675
when '-S', '--search'
676
search_term = /#{args.shift}/nmi
677
else
678
scan_id = arg
679
end
680
end
681
if scan_id.nil?
682
print_status('Usage: ')
683
print_status('nessus_report_vulns <scan ID>')
684
print_status('Use nessus_scan_list to get a list of all the scans. Only completed scans can be reported.')
685
return
686
end
687
tbl = Rex::Text::Table.new(
688
'SearchTerm' => search_term,
689
'Columns' => [
690
'Plugin ID',
691
'Plugin Name',
692
'Plugin Family',
693
'Vulnerability Count'
694
]
695
)
696
if is_scan_complete(scan_id)
697
details = @n.scan_details(scan_id)
698
details['vulnerabilities'].each do |vuln|
699
tbl << [ vuln['plugin_id'], vuln['plugin_name'], vuln['plugin_family'], vuln['count'] ]
700
end
701
print_line
702
print_line tbl.to_s
703
else
704
print_error('Only completed scans can be used for vulnerability reporting')
705
end
706
return
707
end
708
709
def cmd_nessus_report_host_details(*args)
710
search_term = nil
711
search_vuln = nil
712
scan_id = nil
713
host_id = nil
714
while (arg = args.shift)
715
case arg
716
when '-h', '--help'
717
print_status('nessus_report_host_details <scan ID> <host ID>')
718
print_status('Example:> nessus_report_host_details 10 5 -S hostinfo -SV vulninfo')
719
print_status('Use nessus_scan_list to get list of all scans. Only completed scans can be used for reporting.')
720
print_status('Use nessus_report_hosts to get a list of all the hosts along with their corresponding host IDs.')
721
return
722
when '-S', '--search'
723
search_term = /#{args.shift}/nmi
724
when '-SV', '--search-vuln'
725
search_vuln = /#{args.shift}/nmi
726
else
727
scan_id =
728
arg,
729
host_id = args.shift
730
end
731
end
732
733
if [scan_id, host_id].any?(&:nil?)
734
print_status('Usage: ')
735
print_status('nessus_report_host_detail <scan ID> <host ID>')
736
print_status('Example:> nessus_report_host_detail 10 5')
737
print_status('Use nessus_scan_list to get list of all scans. Only completed scans can be used for reporting.')
738
print_status('Use nessus_report_hosts <scan ID> to get a list of all the hosts along with their corresponding host IDs.')
739
return
740
end
741
tbl = Rex::Text::Table.new(
742
'SearchTerm' => search_term,
743
'Columns' => [
744
'Plugin Name',
745
'Plugin Famil',
746
'Severity'
747
]
748
)
749
details = @n.host_detail(scan_id, host_id)
750
print_line
751
print_status('Host information')
752
print_line("IP Address: #{details['info']['host-ip']}")
753
print_line("Hostname: #{details['info']['host-name']}")
754
print_line("Operating System: #{details['info']['operating-system']}")
755
print_line
756
print_status('Vulnerability information')
757
details['vulnerabilities'].each do |vuln|
758
tbl << [ vuln['plugin_name'], vuln['plugin_family'], vuln['severity'] ]
759
end
760
print_line tbl.to_s
761
tbl2 = Rex::Text::Table.new(
762
'SearchTerm' => search_vuln,
763
'Columns' => [
764
'Plugin Name',
765
'Plugin Famil',
766
'Severity'
767
]
768
)
769
print_status('Compliance information')
770
details['compliance'].each do |comp|
771
tbl2 << [ comp['plugin_name'], comp['plugin_family'], comp['severity'] ]
772
end
773
print_line tbl2.to_s
774
end
775
776
def cmd_nessus_report_download(*args)
777
if args[0] == '-h'
778
print_status('nessus_scan_report_download <scan_id> <file ID> ')
779
print_status('Use nessus_scan_export_status <scan ID> <file ID> to check the export status.')
780
print_status('Use nessus_scan_list -c to list all completed scans along with their corresponding scan IDs')
781
return
782
end
783
if !nessus_verify_token
784
return
785
end
786
787
case args.length
788
when 2
789
scan_id = args[0]
790
file_id = args[1]
791
if is_scan_complete(scan_id)
792
report = @n.report_download(scan_id, file_id)
793
File.open("#{msf_local}/#{scan_id}-#{file_id}", 'w+') do |f|
794
f.puts report
795
print_status("Report downloaded to #{msf_local} directory")
796
end
797
else
798
print_error('Only completed scans can be downloaded')
799
end
800
else
801
print_status('Usage: ')
802
print_status('nessus_scan_report_download <scan_id> <file ID> ')
803
print_status('Use nessus_scan_export_status <scan ID> <file ID> to check the export status.')
804
print_status('Use nessus_scan_list -c to list all completed scans along with their corresponding scan IDs')
805
end
806
end
807
808
def cmd_nessus_report_host_ports(*args)
809
search_term = nil
810
rid = nil
811
host = nil
812
while (arg = args.shift)
813
case arg
814
when '-h', '--help'
815
print_status('nessus_report_host_ports <hostname> <report id>')
816
print_status('Example:> nessus_report_host_ports 192.168.1.250 f0eabba3-4065-7d54-5763-f191e98eb0f7f9f33db7e75a06ca -S searchterm')
817
print_status('Returns all the ports associated with a host and details about their vulnerabilities')
818
print_status('Use nessus_report_hosts to list all available hosts for a report')
819
return
820
when '-S', '--search'
821
search_term = /#{args.shift}/nmi
822
else
823
scan_id = arg
824
end
825
end
826
827
if [host, rid].any?(&:nil?)
828
print_status('Usage: ')
829
print_status('nessus_report_host_ports <hostname> <report id>')
830
print_status('Use nessus_report_list to list all available reports')
831
return
832
end
833
tbl = Rex::Text::Table.new(
834
'SearchTerm' => search_term,
835
'Columns' => [
836
'Port',
837
'Protocol',
838
'Severity',
839
'Service Name',
840
'Sev 0',
841
'Sev 1',
842
'Sev 2',
843
'Sev 3'
844
]
845
)
846
ports = @n.report_host_ports(rid, host)
847
ports.each do |port|
848
tbl << [ port['portnum'], port['protocol'], port['severity'], port['svcname'], port['sev0'], port['sev1'], port['sev2'], port['sev3'] ]
849
end
850
print_good('Host Info')
851
print_good "\n"
852
print_line tbl.to_s
853
print_status('You can:')
854
print_status('Get detailed scan information about a specific port: nessus_report_host_detail <hostname> <port> <protocol> <report id>')
855
end
856
857
def cmd_nessus_report_del(*args)
858
if args[0] == '-h'
859
print_status('nessus_report_del <reportname>')
860
print_status('Example:> nessus_report_del f0eabba3-4065-7d54-5763-f191e98eb0f7f9f33db7e75a06ca')
861
print_status('Must be an admin to del reports.')
862
print_status('Use nessus_report_list to list all reports')
863
return
864
end
865
if !nessus_verify_token
866
return
867
end
868
869
if !@n.is_admin
870
print_error('Your Nessus user is not an admin')
871
return
872
end
873
case args.length
874
when 1
875
rid = args[0]
876
else
877
print_status('Usage: ')
878
print_status('nessus_report_del <report ID>')
879
print_status('nessus_report_list to find the id.')
880
return
881
end
882
del = @n.report_del(rid)
883
status = del.root.elements['status'].text
884
if status == 'OK'
885
print_good("Report #{rid} has been deleted")
886
else
887
print_error("Report #{rid} was not deleted")
888
end
889
end
890
891
def cmd_nessus_scan_list(*args)
892
search_term = nil
893
while (arg = args.shift)
894
case arg
895
when '-h', '--help'
896
print_status('nessus_scan_list')
897
print_status('Example:> nessus_scan_list -S searchterm')
898
print_status('Returns a list of information about currently running scans.')
899
return
900
when '-S', '--search'
901
search_term = /#{args.shift}/nmi
902
end
903
end
904
905
if !nessus_verify_token
906
return
907
end
908
909
list = @n.scan_list
910
if list.to_s.empty?
911
print_status('No scans performed.')
912
return
913
else
914
tbl = Rex::Text::Table.new(
915
'SearchTerm' => search_term,
916
'Columns' => [
917
'Scan ID',
918
'Name',
919
'Owner',
920
'Started',
921
'Status',
922
'Folder'
923
]
924
)
925
926
list['scans'].each do |scan|
927
if args[0] == '-r'
928
if scan['status'] == 'running'
929
tbl << [ scan['id'], scan['name'], scan['owner'], scan['starttime'], scan['status'], scan['folder_id'] ]
930
end
931
elsif args[0] == '-p'
932
if scan['status'] == 'paused'
933
tbl << [ scan['id'], scan['name'], scan['owner'], scan['starttime'], scan['status'], scan['folder_id'] ]
934
end
935
elsif args[0] == '-c'
936
if scan['status'] == 'completed'
937
tbl << [ scan['id'], scan['name'], scan['owner'], scan['starttime'], scan['status'], scan['folder_id'] ]
938
end
939
elsif args[0] == '-a'
940
if scan['status'] == 'canceled'
941
tbl << [ scan['id'], scan['name'], scan['owner'], scan['starttime'], scan['status'], scan['folder_id'] ]
942
end
943
else
944
tbl << [ scan['id'], scan['name'], scan['owner'], scan['starttime'], scan['status'], scan['folder_id'] ]
945
end
946
end
947
print_line tbl.to_s
948
end
949
end
950
951
def cmd_nessus_scan_new(*args)
952
if args[0] == '-h'
953
print_status('nessus_scan_new <UUID of Policy> <Scan name> <Description> <Targets>')
954
print_status('Use nessus_policy_list to list all available policies with their corresponding UUIDs')
955
return
956
end
957
if !nessus_verify_token
958
return
959
end
960
961
case args.length
962
when 4
963
uuid = args[0]
964
scan_name = args[1]
965
description = args[2]
966
targets = args[3]
967
else
968
print_status('Usage: ')
969
print_status('nessus_scan_new <UUID of Policy> <Scan name> <Description> <Targets>')
970
print_status('Use nessus_policy_list to list all available policies with their corresponding UUIDs')
971
return
972
end
973
if valid_policy(uuid)
974
print_status("Creating scan from policy number #{uuid}, called #{scan_name} - #{description} and scanning #{targets}")
975
et = {
976
'enabled' => false,
977
'launch' => 'ONETIME',
978
'name' => scan_name,
979
'text_targets' => targets,
980
'description' => description,
981
'launch_now' => false
982
}
983
scan = @n.scan_create(uuid, et)
984
tbl = Rex::Text::Table.new(
985
'Columns' => [
986
'Scan ID',
987
'Scanner ID',
988
'Policy ID',
989
'Targets',
990
'Owner'
991
]
992
)
993
print_status('New scan added')
994
tbl << [ scan['scan']['id'], scan['scan']['scanner_id'], scan['scan']['policy_id'], scan['scan']['custom_targets'], scan['scan']['owner'] ]
995
print_status("Use nessus_scan_launch #{scan['scan']['id']} to launch the scan")
996
print_line tbl.to_s
997
else
998
print_error('The policy does not exist')
999
end
1000
end
1001
1002
def cmd_nessus_scan_launch(*args)
1003
if args[0] == '-h'
1004
print_status('nessus_scan_launch <scan ID>')
1005
print_status('Use nessus_scan_list to list all the availabla scans with their corresponding scan IDs')
1006
end
1007
if !nessus_verify_token
1008
return
1009
end
1010
1011
case args.length
1012
when 1
1013
scan_id = args[0]
1014
else
1015
print_status('Usage: ')
1016
print_status('nessus_scan_launch <scan ID>')
1017
print_status('Use nessus_scan_list to list all the availabla scans with their corresponding scan IDs')
1018
return
1019
end
1020
launch = @n.scan_launch(scan_id)
1021
print_good("Scan ID #{scan_id} successfully launched. The Scan UUID is #{launch['scan_uuid']}")
1022
end
1023
1024
def cmd_nessus_scan_pause(*args)
1025
if args[0] == '-h'
1026
print_status('nessus_scan_pause <scan id>')
1027
print_status('Example:> nessus_scan_pause f0eabba3-4065-7d54-5763-f191e98eb0f7f9f33db7e75a06ca')
1028
print_status('Pauses a running scan')
1029
print_status('Use nessus_scan_list to list all available scans')
1030
return
1031
end
1032
if !nessus_verify_token
1033
return
1034
end
1035
1036
case args.length
1037
when 1
1038
sid = args[0]
1039
else
1040
print_status('Usage: ')
1041
print_status('nessus_scan_pause <scan id>')
1042
print_status('Use nessus_scan_list to list all available scans')
1043
return
1044
end
1045
pause = @n.scan_pause(sid)
1046
if pause['error']
1047
print_error 'Invalid scan ID'
1048
else
1049
print_status("#{sid} has been paused")
1050
end
1051
end
1052
1053
def cmd_nessus_db_scan(*args)
1054
if args[0] == '-h'
1055
print_status('nessus_db_scan <policy ID> <scan name> <scan description>')
1056
print_status('Creates a scan based on all the hosts listed in db_hosts.')
1057
print_status('Use nessus_policy_list to list all available policies with their corresponding policy IDs')
1058
return
1059
end
1060
if !nessus_verify_db
1061
return
1062
end
1063
if !nessus_verify_token
1064
return
1065
end
1066
1067
case args.length
1068
when 3
1069
policy_id = args[0]
1070
name = args[1]
1071
desc = args[3]
1072
else
1073
print_status('Usage: ')
1074
print_status('nessus_db_scan <policy ID> <scan name> <scan description>')
1075
print_status('Use nessus_policy_list to list all available policies with their corresponding policy IDs')
1076
return
1077
end
1078
if !valid_policy(policy_id)
1079
print_error('That policy does not exist.')
1080
return
1081
end
1082
targets = ''
1083
framework.db.hosts.each do |host|
1084
targets << host.address
1085
targets << ','
1086
end
1087
targets.chop!
1088
print_status("Creating scan from policy #{policy_id}, called \"#{name}\" and scanning all hosts in all the workspaces")
1089
et = {
1090
'enabled' => false,
1091
'launch' => 'ONETIME',
1092
'name' => name,
1093
'text_targets' => targets,
1094
'description' => desc,
1095
'launch_now' => true
1096
}
1097
scan = @n.scan_create(policy_id, et)
1098
if !scan['error']
1099
scan = scan['scan']
1100
print_status("Scan ID #{scan['id']} successfully created and launched")
1101
else
1102
print_error(JSON.pretty_generate(scan))
1103
end
1104
end
1105
1106
def cmd_nessus_db_scan_workspace(*args)
1107
if args[0] == '-h'
1108
print_status('nessus_db_scan_workspace <policy ID> <scan name> <scan description> <workspace>')
1109
print_status('Creates a scan based on all the hosts listed in db_hosts for a given workspace.')
1110
print_status('Use nessus_policy_list to list all available policies with their corresponding policy IDs')
1111
return
1112
end
1113
if !nessus_verify_db
1114
return
1115
end
1116
if !nessus_verify_token
1117
return
1118
end
1119
1120
case args.length
1121
when 4
1122
policy_id = args[0]
1123
name = args[1]
1124
desc = args[2]
1125
new_workspace = framework.db.find_workspace(args[3])
1126
else
1127
print_status('Usage: ')
1128
print_status('nessus_db_scan_workspace <policy ID> <scan name> <scan description> <workspace>')
1129
print_status('Use nessus_policy_list to list all available policies with their corresponding policy IDs')
1130
return
1131
end
1132
if !valid_policy(policy_id)
1133
print_error('That policy does not exist.')
1134
return
1135
end
1136
if new_workspace.nil?
1137
print_error('That workspace does not exist.')
1138
return
1139
end
1140
framework.db.workspace = new_workspace
1141
print_status("Switched workspace: #{framework.db.workspace.name}")
1142
targets = ''
1143
framework.db.hosts.each do |host|
1144
targets << host.address
1145
targets << ','
1146
print_status("Targets: #{targets}")
1147
end
1148
targets.chop!
1149
print_status("Creating scan from policy #{policy_id}, called \"#{name}\" and scanning all hosts in #{framework.db.workspace.name}")
1150
et = {
1151
'enabled' => false,
1152
'launch' => 'ONETIME',
1153
'name' => name,
1154
'text_targets' => targets,
1155
'description' => desc,
1156
'launch_now' => false
1157
}
1158
scan = @n.scan_create(policy_id, et)
1159
if !scan['error']
1160
scan = scan['scan']
1161
print_status("Scan ID #{scan['id']} successfully created")
1162
print_status("Run nessus_scan_launch #{scan['id']} to launch the scan")
1163
else
1164
print_error(JSON.pretty_generate(scan))
1165
end
1166
end
1167
1168
def cmd_nessus_db_import(*args)
1169
if args[0] == '-h'
1170
print_status('nessus_db_import <scan ID>')
1171
print_status('Example:> nessus_db_import 500')
1172
print_status('Use nessus_scan_list -c to list all completed scans')
1173
end
1174
if !nessus_verify_db
1175
return
1176
end
1177
if !nessus_verify_token
1178
return
1179
end
1180
1181
case args.length
1182
when 1
1183
scan_id = args[0]
1184
else
1185
print_status('Usage: ')
1186
print_status('nessus_db_import <scan ID>')
1187
print_status('Example:> nessus_db_import 500')
1188
print_status('Use nessus_scan_list -c to list all completed scans')
1189
end
1190
if is_scan_complete(scan_id)
1191
print_status("Exporting scan ID #{scan_id} is Nessus format...")
1192
export = @n.scan_export(scan_id, 'nessus')
1193
status = {}
1194
if export['file']
1195
file_id = export['file']
1196
print_good("The export file ID for scan ID #{scan_id} is #{file_id}")
1197
print_status('Checking export status...')
1198
loop do
1199
status = @n.scan_export_status(scan_id, file_id)
1200
print_status('Export status: ' + status['status'])
1201
if status['status'] == 'ready'
1202
break
1203
end
1204
1205
sleep(1)
1206
break unless (status['status'] == 'loading')
1207
end
1208
if status['status'] == 'ready'
1209
print_status("The status of scan ID #{scan_id} export is ready")
1210
select(nil, nil, nil, 5)
1211
report = @n.report_download(scan_id, file_id)
1212
print_status('Importing scan results to the database...')
1213
framework.db.import({ data: report }) do |type, data|
1214
case type
1215
when :address
1216
print_status("Importing data of #{data}")
1217
end
1218
end
1219
print_good('Done')
1220
else
1221
print_error("There was some problem in exporting the scan. The error message is #{status}")
1222
end
1223
else
1224
print_error(export)
1225
end
1226
else
1227
print_error('Only completed scans could be used for import')
1228
end
1229
end
1230
1231
def cmd_nessus_scan_pause_all(*args)
1232
scan_ids = Array.new
1233
if args[0] == '-h'
1234
print_status('nessus_scan_pause_all')
1235
print_status('Example:> nessus_scan_pause_all')
1236
print_status('Pauses all currently running scans')
1237
print_status('Use nessus_scan_list to list all running scans')
1238
return
1239
end
1240
if !nessus_verify_token
1241
return
1242
end
1243
1244
list = @n.scan_list
1245
list['scans'].each do |scan|
1246
if scan['status'] == 'running'
1247
scan_ids << scan['id']
1248
end
1249
end
1250
if !scan_ids.empty?
1251
scan_ids.each do |scan_id|
1252
@n.scan_pause(scan_id)
1253
end
1254
print_status('All scans have been paused')
1255
else
1256
print_error('No running scans')
1257
end
1258
end
1259
1260
def cmd_nessus_scan_stop(*args)
1261
if args[0] == '-h'
1262
print_status('nessus_scan_stop <scan id>')
1263
print_status('Example:> nessus_scan_stop f0eabba3-4065-7d54-5763-f191e98eb0f7f9f33db7e75a06ca')
1264
print_status('Stops a currently running scans')
1265
print_status('Use nessus_scan_list to list all running scans')
1266
return
1267
end
1268
if !nessus_verify_token
1269
return
1270
end
1271
1272
case args.length
1273
when 1
1274
sid = args[0]
1275
else
1276
print_status('Usage: ')
1277
print_status('nessus_scan_stop <scan id>')
1278
print_status('Use nessus_scan_list to list all available scans')
1279
return
1280
end
1281
stop = @n.scan_stop(sid)
1282
if stop['error']
1283
print_error 'Invalid scan ID'
1284
else
1285
print_status("#{sid} has been stopped")
1286
end
1287
end
1288
1289
def cmd_nessus_scan_stop_all(*args)
1290
scan_ids = Array.new
1291
if args[0] == '-h'
1292
print_status('nessus_scan_stop_all')
1293
print_status('Example:> nessus_scan_stop_all')
1294
print_status('stops all currently running scans')
1295
print_status('Use nessus_scan_list to list all running scans')
1296
return
1297
end
1298
if !nessus_verify_token
1299
return
1300
end
1301
1302
list = @n.scan_list
1303
list['scans'].each do |scan|
1304
if scan['status'] == 'running' || scan['status'] == 'paused'
1305
scan_ids << scan['id']
1306
end
1307
end
1308
if !scan_ids.empty?
1309
scan_ids.each do |scan_id|
1310
@n.scan_stop(scan_id)
1311
end
1312
print_status('All scans have been stopped')
1313
else
1314
print_error('No running or paused scans to be stopped')
1315
end
1316
end
1317
1318
def cmd_nessus_scan_resume(*args)
1319
if args[0] == '-h'
1320
print_status('nessus_scan_resume <scan id>')
1321
print_status('Example:> nessus_scan_resume f0eabba3-4065-7d54-5763-f191e98eb0f7f9f33db7e75a06ca')
1322
print_status('resumes a running scan')
1323
print_status('Use nessus_scan_list to list all available scans')
1324
return
1325
end
1326
if !nessus_verify_token
1327
return
1328
end
1329
1330
case args.length
1331
when 1
1332
sid = args[0]
1333
else
1334
print_status('Usage: ')
1335
print_status('nessus_scan_resume <scan id>')
1336
print_status('Use nessus_scan_list to list all available scans')
1337
return
1338
end
1339
resume = @n.scan_resume(sid)
1340
if resume['error']
1341
print_error 'Invalid scan ID'
1342
else
1343
print_status("#{sid} has been resumed")
1344
end
1345
end
1346
1347
def cmd_nessus_scan_resume_all(*args)
1348
scan_ids = Array.new
1349
if args[0] == '-h'
1350
print_status('nessus_scan_resume_all')
1351
print_status('Example:> nessus_scan_resume_all')
1352
print_status('resumes all currently running scans')
1353
print_status('Use nessus_scan_list to list all running scans')
1354
return
1355
end
1356
if !nessus_verify_token
1357
return
1358
end
1359
1360
list = @n.scan_list
1361
list['scans'].each do |scan|
1362
if scan['status'] == 'paused'
1363
scan_ids << scan['id']
1364
end
1365
end
1366
if !scan_ids.empty?
1367
scan_ids.each do |scan_id|
1368
@n.scan_resume(scan_id)
1369
end
1370
print_status('All scans have been resumed')
1371
else
1372
print_error('No running scans to be resumed')
1373
end
1374
end
1375
1376
def cmd_nessus_scan_details(*args)
1377
valid_categories = ['info', 'hosts', 'vulnerabilities', 'history']
1378
search_term = nil
1379
scan_id = nil
1380
category = nil
1381
while (arg = args.shift)
1382
case arg
1383
when '-h', '--help'
1384
print_status('Usage: ')
1385
print_status('nessus_scan_details <scan ID> <category> -S searchterm')
1386
print_status('Availble categories are info, hosts, vulnerabilities, and history')
1387
print_status('Use nessus_scan_list to list all available scans with their corresponding scan IDs')
1388
return
1389
when '-S', '--search'
1390
search_term = /#{args.shift}/nmi
1391
else
1392
scan_id = arg
1393
if args[0].in?(valid_categories)
1394
category = args.shift
1395
else
1396
print_error('Invalid category. The available categories are info, hosts, vulnerabilities, and history')
1397
return
1398
end
1399
end
1400
end
1401
1402
if !nessus_verify_token
1403
return
1404
end
1405
1406
details = @n.scan_details(scan_id)
1407
if category == 'info'
1408
tbl = Rex::Text::Table.new(
1409
'SearchTerm' => search_term,
1410
'Columns' => [
1411
'Status',
1412
'Policy',
1413
'Scan Name',
1414
'Scan Targets',
1415
'Scan Start Time',
1416
'Scan End Time'
1417
]
1418
)
1419
tbl << [ details['info']['status'], details['info']['policy'], details['info']['name'], details['info']['targets'], details['info']['scan_start'], details['info']['scan_end'] ]
1420
elsif category == 'hosts'
1421
tbl = Rex::Text::Table.new(
1422
'SearchTerm' => search_term,
1423
'Columns' => [
1424
'Host ID',
1425
'Hostname',
1426
'% of Critical Findings',
1427
'% of High Findings',
1428
'% of Medium Findings',
1429
'% of Low Findings'
1430
]
1431
)
1432
details['hosts'].each do |host|
1433
tbl << [ host['host_id'], host['hostname'], host['critical'], host['high'], host['medium'], host['low'] ]
1434
end
1435
elsif category == 'vulnerabilities'
1436
tbl = Rex::Text::Table.new(
1437
'SearchTerm' => search_term,
1438
'Columns' => [
1439
'Plugin ID',
1440
'Plugin Name',
1441
'Plugin Family',
1442
'Count'
1443
]
1444
)
1445
details['vulnerabilities'].each do |vuln|
1446
tbl << [ vuln['plugin_id'], vuln['plugin_name'], vuln['plugin_family'], vuln['count'] ]
1447
end
1448
elsif category == 'history'
1449
tbl = Rex::Text::Table.new(
1450
'SearchTerm' => search_term,
1451
'Columns' => [
1452
'History ID',
1453
'Status',
1454
'Creation Date',
1455
'Last Modification Date'
1456
]
1457
)
1458
details['history'].each do |hist|
1459
tbl << [ hist['history_id'], hist['status'], hist['creation_date'], hist['modification_date'] ]
1460
end
1461
end
1462
print_line tbl.to_s
1463
end
1464
1465
def cmd_nessus_scan_export(*args)
1466
if args[0] == '-h'
1467
print_status('nessus_scan_export <scan ID> <export format>')
1468
print_status('The available export formats are Nessus, HTML, PDF, CSV, or DB')
1469
print_status('Use nessus_scan_list to list all available scans with their corresponding scan IDs')
1470
return
1471
end
1472
if !nessus_verify_token
1473
return
1474
end
1475
1476
case args.length
1477
when 2
1478
scan_id = args[0]
1479
format = args[1].downcase
1480
else
1481
print_status('Usage: ')
1482
print_status('nessus_scan_export <scan ID> <export format>')
1483
print_status('The available export formats are Nessus, HTML, PDF, CSV, or DB')
1484
print_status('Use nessus_scan_list to list all available scans with their corresponding scan IDs')
1485
return
1486
end
1487
if format.in?(['nessus', 'html', 'pdf', 'csv', 'db'])
1488
export = @n.scan_export(scan_id, format)
1489
status = {}
1490
if export['file']
1491
file_id = export['file']
1492
print_good("The export file ID for scan ID #{scan_id} is #{file_id}")
1493
print_status('Checking export status...')
1494
loop do
1495
status = @n.scan_export_status(scan_id, file_id)
1496
print_status('Export status: ' + status['status'])
1497
if status['status'] == 'ready'
1498
break
1499
end
1500
1501
sleep(1)
1502
break unless (status['status'] == 'loading')
1503
end
1504
if status['status'] == 'ready'
1505
print_good("The status of scan ID #{scan_id} export is ready")
1506
else
1507
print_error("There was some problem in exporting the scan. The error message is #{status}")
1508
end
1509
else
1510
print_error(export)
1511
end
1512
else
1513
print_error('Invalid export format. The available export formats are Nessus, HTML, PDF, CSV, or DB')
1514
return
1515
end
1516
end
1517
1518
def cmd_nessus_scan_export_status(*args)
1519
if args[0] == '-h'
1520
print_status('nessus_scan_export_status <scan ID> <file ID>')
1521
print_status('Use nessus_scan_export <scan ID> <format> to export a scan and get its file ID')
1522
end
1523
if !nessus_verify_token
1524
return
1525
end
1526
1527
case args.length
1528
when 2
1529
scan_id = args[0]
1530
file_id = args[1]
1531
status = {}
1532
loop do
1533
status = @n.scan_export_status(scan_id, file_id)
1534
print_status('Export status: ' + status['status'])
1535
if status['status'] == 'ready'
1536
break
1537
end
1538
1539
sleep(1)
1540
break unless (status['status'] == 'loading')
1541
end
1542
if status['status'] == 'ready'
1543
print_status("The status of scan ID #{scan_id} export is ready")
1544
else
1545
print_error("There was some problem in exporting the scan. The error message is #{status}")
1546
end
1547
else
1548
print_status('Usage: ')
1549
print_status('nessus_scan_export_status <scan ID> <file ID>')
1550
print_status('Use nessus_scan_export <scan ID> <format> to export a scan and get its file ID')
1551
end
1552
end
1553
1554
def cmd_nessus_plugin_list(*args)
1555
search_term = nil
1556
family_id = nil
1557
while (arg = args.shift)
1558
case arg
1559
when '-h', '--help'
1560
print_status('nessus_plugin_list <Family ID> -S searchterm')
1561
print_status('Example:> nessus_plugin_list 10')
1562
print_status('Returns a list of all plugins in that family.')
1563
print_status('Use nessus_family_list to display all the plugin families along with their corresponding family IDs')
1564
return
1565
when '-S', '--search'
1566
search_term = /#{args.shift}/nmi
1567
else
1568
family_id = arg
1569
end
1570
end
1571
1572
if family_id.nil?
1573
print_status('Usage: ')
1574
print_status('nessus_plugin_list <Family ID>')
1575
print_status('Use nessus_family_list to display all the plugin families along with their corresponding family IDs')
1576
return
1577
end
1578
tbl = Rex::Text::Table.new(
1579
'SearchTerm' => search_term,
1580
'Columns' => [
1581
'Plugin ID',
1582
'Plugin Name'
1583
]
1584
)
1585
list = @n.list_plugins(family_id)
1586
list['plugins'].each do |plugin|
1587
tbl << [ plugin['id'], plugin['name'] ]
1588
end
1589
print_line
1590
print_good("Plugin Family Name: #{list['name']}")
1591
print_line
1592
print_line tbl.to_s
1593
end
1594
1595
def cmd_nessus_family_list(*args)
1596
search_term = nil
1597
while (arg = args.shift)
1598
case arg
1599
when '-h', '--help'
1600
print_status('nessus_family_list')
1601
print_status('Example:> nessus_family_list -S searchterm')
1602
print_status('Returns a list of all the plugin families along with their corresponding family IDs and plugin count.')
1603
return
1604
when '-S', '--search'
1605
search_term = /#{args.shift}/nmi
1606
end
1607
end
1608
1609
list = @n.list_families
1610
tbl = Rex::Text::Table.new(
1611
'SearchTerm' => search_term,
1612
'Columns' => [
1613
'Family ID',
1614
'Family Name',
1615
'Number of Plugins'
1616
]
1617
)
1618
list['families'].each do |family|
1619
tbl << [ family['id'], family['name'], family['count'] ]
1620
end
1621
print_line
1622
print_line tbl.to_s
1623
end
1624
1625
def cmd_nessus_plugin_details(*args)
1626
search_term = nil
1627
plugin_id = nil
1628
while (arg = args.shift)
1629
case arg
1630
when '-h', '--help'
1631
print_status('nessus_plugin_details <Plugin ID>')
1632
print_status('Example:> nessus_plugin_details 10264 -S searchterm')
1633
print_status('Returns details on a particular plugin.')
1634
print_status('Use nessus_plugin_list to list all plugins and their corresponding plugin IDs belonging to a particular plugin family.')
1635
return
1636
when '-S', '--search'
1637
search_term = /#{args.shift}/nmi
1638
else
1639
plugin_id = arg
1640
end
1641
end
1642
1643
if !nessus_verify_token
1644
return
1645
end
1646
1647
if plugin_id.nil?
1648
print_status('Usage: ')
1649
print_status('nessus_plugin_details <Plugin ID>')
1650
print_status('Use nessus_plugin_list to list all plugins and their corresponding plugin IDs belonging to a particular plugin family.')
1651
return
1652
end
1653
tbl = Rex::Text::Table.new(
1654
'SearchTerm' => search_term,
1655
'Columns' => [
1656
'Reference',
1657
'Value'
1658
]
1659
)
1660
begin
1661
list = @n.plugin_details(plugin_id)
1662
rescue ::Exception => e
1663
if e.message =~ /unexpected token/
1664
print_error('No plugin info found')
1665
return
1666
else
1667
raise e
1668
end
1669
end
1670
list['attributes'].each do |attrib|
1671
tbl << [ attrib['attribute_name'], attrib['attribute_value'] ]
1672
end
1673
print_line
1674
print_good("Plugin Name: #{list['name']}")
1675
print_good("Plugin Family: #{list['family_name']}")
1676
print_line
1677
print_line tbl.to_s
1678
end
1679
1680
def cmd_nessus_user_list(*args)
1681
scan_id = nil
1682
while (arg = args.shift)
1683
case arg
1684
when '-h', '--help'
1685
print_status('nessus_user_list')
1686
print_status('Example:> nessus_user_list -S searchterm')
1687
print_status('Returns a list of the users on the Nessus server and their access level.')
1688
return
1689
when '-S', '--search'
1690
search_term = /#{args.shift}/nmi
1691
end
1692
end
1693
1694
if !nessus_verify_token
1695
return
1696
end
1697
1698
if !@n.is_admin
1699
print_status('Your Nessus user is not an admin')
1700
end
1701
list = @n.list_users
1702
tbl = Rex::Text::Table.new(
1703
'SearchTerm' => search_term,
1704
'Columns' => [
1705
'ID',
1706
'Name',
1707
'Username',
1708
'Type',
1709
'Email',
1710
'Permissions'
1711
]
1712
)
1713
list['users'].each do |user|
1714
tbl << [ user['id'], user['name'], user['username'], user['type'], user['email'], user['permissions'] ]
1715
end
1716
print_line
1717
print_line tbl.to_s
1718
end
1719
1720
def cmd_nessus_user_add(*args)
1721
if args[0] == '-h'
1722
print_status('nessus_user_add <username> <password> <permissions> <type>')
1723
print_status('Permissions are 32, 64, and 128')
1724
print_status('Type can be either local or LDAP')
1725
print_status('Example:> nessus_user_add msf msf 16 local')
1726
print_status('You need to be an admin in order to add accounts')
1727
print_status('Use nessus_user_list to list all users')
1728
return
1729
end
1730
if !nessus_verify_token
1731
return
1732
end
1733
1734
if !@n.is_admin
1735
print_error('Your Nessus user is not an admin')
1736
return
1737
end
1738
case args.length
1739
when 4
1740
user = args[0]
1741
pass = args[1]
1742
permissions = args[2]
1743
type = args[3]
1744
else
1745
print_status('Usage')
1746
print_status('nessus_user_add <username> <password> <permissions> <type>')
1747
return
1748
end
1749
add = @n.user_add(user, pass, permissions, type)
1750
if add['id']
1751
print_good("#{user} created successfully")
1752
else
1753
print_error(add.to_s)
1754
end
1755
end
1756
1757
def cmd_nessus_user_del(*args)
1758
if args[0] == '-h'
1759
print_status('nessus_user_del <User ID>')
1760
print_status('Example:> nessus_user_del 10')
1761
print_status('This command can only delete non admin users. You must be an admin to delete users.')
1762
print_status('Use nessus_user_list to list all users with their corresponding user IDs')
1763
return
1764
end
1765
if !nessus_verify_token
1766
return
1767
end
1768
1769
if !@n.is_admin
1770
print_error('Your Nessus user is not an admin')
1771
return
1772
end
1773
case args.length
1774
when 1
1775
user_id = args[0]
1776
else
1777
print_status('Usage: ')
1778
print_status('nessus_user_del <User ID>')
1779
print_status('This command can only delete non admin users')
1780
return
1781
end
1782
del = @n.user_delete(user_id)
1783
status = del.to_s
1784
if status == '200'
1785
print_good("User account having user ID #{user_id} deleted successfully")
1786
elsif status == '403'
1787
print_error("You do not have permission to delete the user account having user ID #{user_id}")
1788
elsif status == '404'
1789
print_error("User account having user ID #{user_id} does not exist")
1790
elsif status == '409'
1791
print_error('You cannot delete your own account')
1792
elsif status == '500'
1793
print_error("The server failed to delete the user account having user ID #{user_id}")
1794
else
1795
print_error("Unknown problem occurred by deleting the user account having user ID #{user_id}.")
1796
end
1797
end
1798
1799
def cmd_nessus_user_passwd(*args)
1800
if args[0] == '-h'
1801
print_status('nessus_user_passwd <User ID> <New Password>')
1802
print_status('Example:> nessus_user_passwd 10 mynewpassword')
1803
print_status('Changes the password of a user. You must be an admin to change passwords.')
1804
print_status('Use nessus_user_list to list all users with their corresponding user IDs')
1805
return
1806
end
1807
if !nessus_verify_token
1808
return
1809
end
1810
1811
if !@n.is_admin
1812
print_error('Your Nessus user is not an admin')
1813
return
1814
end
1815
case args.length
1816
when 2
1817
user_id = args[0]
1818
pass = args[1]
1819
else
1820
print_status('Usage: ')
1821
print_status('nessus_user_passwd <User ID> <New Password>')
1822
print_status('Use nessus_user_list to list all users with their corresponding user IDs')
1823
return
1824
end
1825
pass = @n.user_chpasswd(user_id, pass)
1826
status = pass.to_s
1827
if status == '200'
1828
print_good("Password of account having user ID #{user_id} changed successfully")
1829
elsif status == '400'
1830
print_error('Password is too short')
1831
elsif status == '403'
1832
print_error("You do not have the permission to change password for the user having user ID #{user_id}")
1833
elsif status == '404'
1834
print_error("User having user ID #{user_id} does not exist")
1835
elsif status == '500'
1836
print_error('Nessus server failed to changed the user password')
1837
else
1838
print_error('Unknown problem occurred while changing the user password')
1839
end
1840
end
1841
1842
def cmd_nessus_policy_list(*args)
1843
search_term = nil
1844
while (arg = args.shift)
1845
case arg
1846
when '-h', '--help'
1847
print_status('nessus_policy_list')
1848
print_status('Example:> nessus_policy_list -S searchterm')
1849
print_status('Lists all policies on the server')
1850
return
1851
when '-S', '--search'
1852
search_term = /#{args.shift}/nmi
1853
end
1854
end
1855
1856
if !nessus_verify_token
1857
return
1858
end
1859
1860
list = @n.list_policies
1861
1862
unless list['policies']
1863
print_error('No policies found')
1864
return
1865
end
1866
1867
tbl = Rex::Text::Table.new(
1868
'Columns' => [
1869
'Policy ID',
1870
'Name',
1871
'Policy UUID'
1872
]
1873
)
1874
list['policies'].each do |policy|
1875
tbl << [ policy['id'], policy['name'], policy['template_uuid'] ]
1876
end
1877
print_line tbl.to_s
1878
end
1879
1880
def cmd_nessus_policy_del(*args)
1881
if args[0] == '-h'
1882
print_status('nessus_policy_del <policy ID>')
1883
print_status('Example:> nessus_policy_del 1')
1884
print_status('You must be an admin to delete policies.')
1885
print_status('Use nessus_policy_list to list all policies with their corresponding policy IDs')
1886
return
1887
end
1888
if !nessus_verify_token
1889
return
1890
end
1891
1892
if !@n.is_admin
1893
print_error('Your Nessus user is not an admin')
1894
return
1895
end
1896
case args.length
1897
when 1
1898
policy_id = args[0]
1899
else
1900
print_status('Usage: ')
1901
print_status('nessus_policy_del <policy ID>')
1902
print_status('Use nessus_policy_list to list all the policies with their corresponding policy IDs')
1903
return
1904
end
1905
del = @n.policy_delete(policy_id)
1906
status = del.to_s
1907
if status == '200'
1908
print_good("Policy ID #{policy_id} successfully deleted")
1909
elsif status == '403'
1910
print_error("You do not have permission to delete policy ID #{policy_id}")
1911
elsif status == '404'
1912
print_error("Policy ID #{policy_id} does not exist")
1913
elsif status == '405'
1914
print_error("Policy ID #{policy_id} is currently in use and cannot be deleted")
1915
else
1916
print_error("Unknown problem occurred by deleting the user account having user ID #{user_id}.")
1917
end
1918
end
1919
end
1920
1921
def initialize(framework, opts)
1922
super
1923
add_console_dispatcher(ConsoleCommandDispatcher)
1924
print_status(PLUGIN_DESCRIPTION)
1925
print_status('Type %bldnessus_help%clr for a command listing')
1926
end
1927
1928
def cleanup
1929
remove_console_dispatcher('Nessus')
1930
end
1931
end
1932
end
1933
1934