nexposecli 0.2.6 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/nexposecli +138 -31
- data/lib/nexposecli/args.rb +23 -0
- data/lib/nexposecli/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a07316475b55fdc50b6e3fa3ee0541a43e5f2d5f
|
4
|
+
data.tar.gz: 46bbc3f787e9cc57a48d2faac0f80ef60ed902a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c806214d80328f916283d549b127b5a1002d4d7b9047a545a2bfc327050354b4ed80f3d8a79893825546e738cbc0c4fc046a93c16a9d2b529acb3880ddc9e37a
|
7
|
+
data.tar.gz: 6a384917b44f606e4267052ddd5fafebe44d46d0c7e827abac61bdef11542f8d57ec70d402ac0145e186ab1934a1b7444c294a094eb13ef6e3a76f794df6e840
|
data/bin/nexposecli
CHANGED
@@ -35,8 +35,11 @@ require 'pp'
|
|
35
35
|
|
36
36
|
##############################################################################
|
37
37
|
# Set default var values
|
38
|
+
$nxport = 3780
|
38
39
|
$debug = false
|
40
|
+
$format = 'default'
|
39
41
|
$dryrun = false
|
42
|
+
$multitenant = false
|
40
43
|
uf_scanners = ''
|
41
44
|
|
42
45
|
@logpath = "./"
|
@@ -287,11 +290,11 @@ if args.scanpath
|
|
287
290
|
end
|
288
291
|
|
289
292
|
$debug = TRUE if args.verbose
|
293
|
+
$multitenant = TRUE if args.silo
|
290
294
|
$dryrun = TRUE if args.dryrun
|
291
295
|
uputs("CLI", "Command-line verbosity mode is #{$debug.to_s}")
|
292
296
|
uputs("CLI", "Command-line dry run mode is #{$dryrun.to_s}")
|
293
297
|
uputs("CLI", "Command-line args parsed for #{$0}")
|
294
|
-
uputs("CLI", "Command-line args parsed for #{$0}")
|
295
298
|
uputs("CLI", "Args: #{args.inspect}")
|
296
299
|
|
297
300
|
# Needs to potentially move, based on TARGET help vs general usage
|
@@ -335,8 +338,9 @@ uputs("TARGET", "Checking for the requested target")
|
|
335
338
|
@target |= 32768 if args.AUTHSRC
|
336
339
|
@target |= 65536 if args.GROUP
|
337
340
|
@target |= 131072 if args.SCHEDULE
|
341
|
+
@target |= 262144 if args.SILO
|
338
342
|
uputs("TARGET", "The requested target value is: #{@target.to_s}")
|
339
|
-
raise "You can only submit one target per task, see --help (#{@target})" unless [1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072].include?(@target)
|
343
|
+
raise "You can only submit one target per task, see --help (#{@target})" unless [1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144].include?(@target)
|
340
344
|
|
341
345
|
# Needs to potentially move into TARGET object or module instance var
|
342
346
|
## First NSC Connection and Session creation
|
@@ -360,7 +364,11 @@ end
|
|
360
364
|
# Make the initial connection to the NSC server
|
361
365
|
uputs("CONNECT", "Attempting connection to NSC: #{@nsc_server.to_s} with user: #{@nsc_user.to_s}")
|
362
366
|
begin
|
363
|
-
|
367
|
+
if $multitenant
|
368
|
+
@nsc = Nexpose::Connection.new( @nsc_server.to_s, @nsc_user.to_s, @nsc_passwd.to_s, $nxport, args.silo.to_s)
|
369
|
+
else
|
370
|
+
@nsc = Nexpose::Connection.new( @nsc_server.to_s, @nsc_user.to_s, @nsc_passwd.to_s)
|
371
|
+
end
|
364
372
|
rescue SystemCallError => e
|
365
373
|
# EJG add conditional api error handling...
|
366
374
|
uputs("CONNECT", "An error occurred while attempting to connect to the specified server: #{e.to_s}")
|
@@ -565,6 +573,7 @@ when 2 # TARGET ENGINE
|
|
565
573
|
puts 'Not yet implemented'
|
566
574
|
when 2 # list
|
567
575
|
uputs("ACTION", 'list ENGINE action requested')
|
576
|
+
|
568
577
|
uf_scanners = @nsc.engines
|
569
578
|
if uf_scanners.length > 0
|
570
579
|
if args.action
|
@@ -584,6 +593,7 @@ when 2 # TARGET ENGINE
|
|
584
593
|
end
|
585
594
|
else
|
586
595
|
uf_scanners.each do |scanner|
|
596
|
+
upp scanner
|
587
597
|
puts("\t- status: #{scanner.status}\t id:#{scanner.id}\t name:'#{scanner.name}'\n")
|
588
598
|
end
|
589
599
|
end
|
@@ -594,6 +604,8 @@ when 2 # TARGET ENGINE
|
|
594
604
|
when 4 # show
|
595
605
|
uputs("ACTION", 'show ENGINE action requested')
|
596
606
|
puts 'Not yet implemented'
|
607
|
+
engine = Nexpose::Engine.load(@nsc, args.id)
|
608
|
+
upp engine
|
597
609
|
when 8 # update
|
598
610
|
uputs("ACTION", 'update ENGINE action requested')
|
599
611
|
puts 'Not yet implemented'
|
@@ -722,7 +734,11 @@ when 8 # TARGET SCAN
|
|
722
734
|
# Make a connection and login to the NSC server
|
723
735
|
uputs("CONNECT", "Attempting connection to NSC: #{@nsc_server.to_s} with user: #{@nsc_user.to_s}")
|
724
736
|
begin
|
725
|
-
|
737
|
+
if $multitenant
|
738
|
+
@nsc = Nexpose::Connection.new( @nsc_server.to_s, @nsc_user.to_s, @nsc_passwd.to_s, $nxport, args.silo.to_s)
|
739
|
+
else
|
740
|
+
@nsc = Nexpose::Connection.new( @nsc_server.to_s, @nsc_user.to_s, @nsc_passwd.to_s)
|
741
|
+
end
|
726
742
|
@nsc.login
|
727
743
|
rescue SystemCallError => e
|
728
744
|
# EJG add conditional api error handling and consider wrapping coonect/login into a method...
|
@@ -808,7 +824,11 @@ when 8 # TARGET SCAN
|
|
808
824
|
# Make a connection and login to the NSC server
|
809
825
|
uputs("CONNECT", "Attempting connection to NSC: #{@nsc_server.to_s} with user: #{@nsc_user.to_s}")
|
810
826
|
begin
|
811
|
-
|
827
|
+
if $multitenant
|
828
|
+
@nsc = Nexpose::Connection.new( @nsc_server.to_s, @nsc_user.to_s, @nsc_passwd.to_s, $nxport, args.silo.to_s)
|
829
|
+
else
|
830
|
+
@nsc = Nexpose::Connection.new( @nsc_server.to_s, @nsc_user.to_s, @nsc_passwd.to_s)
|
831
|
+
end
|
812
832
|
@nsc.login
|
813
833
|
rescue SystemCallError => e
|
814
834
|
# EJG add conditional api error handling and consider wrapping coonect/login into a method...
|
@@ -908,7 +928,11 @@ when 8 # TARGET SCAN
|
|
908
928
|
# Make a connection and login to the NSC server
|
909
929
|
uputs("CONNECT", "Attempting connection to NSC: #{@nsc_server.to_s} with user: #{@nsc_user.to_s}")
|
910
930
|
begin
|
911
|
-
|
931
|
+
if $multitenant
|
932
|
+
@nsc = Nexpose::Connection.new( @nsc_server.to_s, @nsc_user.to_s, @nsc_passwd.to_s, $nxport, args.silo.to_s)
|
933
|
+
else
|
934
|
+
@nsc = Nexpose::Connection.new( @nsc_server.to_s, @nsc_user.to_s, @nsc_passwd.to_s)
|
935
|
+
end
|
912
936
|
@nsc.login
|
913
937
|
rescue SystemCallError => e
|
914
938
|
# EJG add conditional api error handling and consider wrapping coonect/login into a method...
|
@@ -942,13 +966,13 @@ when 8 # TARGET SCAN
|
|
942
966
|
when 2 # list
|
943
967
|
uputs("SCAN", 'list SCAN action requested')
|
944
968
|
# EJG
|
945
|
-
scans = @nsc.past_scans(args.id.to_i)
|
946
|
-
puts "Requested: nsc.past_scans(#{args.id}), but past scans length is: #{scans.length}"
|
947
|
-
puts "Past Scans:"
|
948
|
-
scans.each do |scan|
|
949
|
-
|
950
|
-
end
|
951
|
-
exit(0)
|
969
|
+
# scans = @nsc.past_scans(args.id.to_i)
|
970
|
+
# puts "Requested: nsc.past_scans(#{args.id}), but past scans length is: #{scans.length}"
|
971
|
+
# puts "Past Scans:"
|
972
|
+
# scans.each do |scan|
|
973
|
+
# puts " - " + '%-6.6s' % scan.id + " " + '%-15.15s' % scan.engine_name + " " + '%-30.30s' % scan.end_time + " " + '%-25.25s' % scan.status
|
974
|
+
# end
|
975
|
+
# exit(0)
|
952
976
|
|
953
977
|
# EJG
|
954
978
|
scan_activity = scan_activity()
|
@@ -1035,7 +1059,27 @@ when 16 # TARGET SITE
|
|
1035
1059
|
case @action
|
1036
1060
|
when 1 # create
|
1037
1061
|
uputs("ACTION", 'create SITE action requested')
|
1038
|
-
|
1062
|
+
unless (
|
1063
|
+
args.name != nil && args.range && args.template
|
1064
|
+
)
|
1065
|
+
raise 'Please supply the site name, ip range, and scan template id to define the site, see --help'
|
1066
|
+
end
|
1067
|
+
site = Nexpose::Site.new(args.name, args.template)
|
1068
|
+
|
1069
|
+
if args.range.split('-').size == 2
|
1070
|
+
site.included_addresses << Nexpose::IPRange.new(args.range.split('-')[0], args.range.split('-')[1])
|
1071
|
+
else
|
1072
|
+
site.included_addresses << Nexpose::IPRange.new(args.range)
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
begin
|
1076
|
+
site_created = site.save(@nsc)
|
1077
|
+
rescue Nexpose::APIError => e
|
1078
|
+
uputs("SITE", "An error occurred while attempting to save the Site: #{e.to_s}")
|
1079
|
+
STDERR.puts "ERROR [ " + e.to_s + " ]"
|
1080
|
+
exit(-1)
|
1081
|
+
end
|
1082
|
+
puts "Site was successfully created. The Site Id is: #{site_created}"
|
1039
1083
|
when 2 # list
|
1040
1084
|
uputs("ACTION", 'list SITE action requested')
|
1041
1085
|
site_listing = @nsc.list_sites
|
@@ -1068,20 +1112,26 @@ when 16 # TARGET SITE
|
|
1068
1112
|
site.excluded_scan_targets[:addresses].each do |iprange|
|
1069
1113
|
puts(" IPRange from: #{iprange.from} - #{iprange.to}\n")
|
1070
1114
|
end
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1115
|
+
|
1116
|
+
# If detail is requested, note this will return all assets
|
1117
|
+
if args.action
|
1118
|
+
case args.action
|
1119
|
+
when "assets", "detail"
|
1120
|
+
puts("--active assets:")
|
1121
|
+
assets = @nsc.list_site_devices(scan_site_id)
|
1122
|
+
assets.each do |asset|
|
1123
|
+
print(" Asset Id: #{asset.id}, IP Address: #{asset.address}, Risk Score: #{asset.risk_score} Hostnames: [")
|
1124
|
+
asset_detail = Nexpose::Asset.load(@nsc, asset.id)
|
1125
|
+
if asset_detail.host_names
|
1126
|
+
asset_detail.host_names.each do |hostname|
|
1127
|
+
print("#{hostname},")
|
1128
|
+
end
|
1129
|
+
end
|
1130
|
+
print("] OS: #{asset_detail.os_cpe}\n")
|
1131
|
+
upp(asset_detail)
|
1080
1132
|
end
|
1081
|
-
|
1082
|
-
upp(asset_detail)
|
1133
|
+
end
|
1083
1134
|
end
|
1084
|
-
# upp site
|
1085
1135
|
when 8 # update
|
1086
1136
|
uputs("ACTION", 'update SITE action requested')
|
1087
1137
|
site = ""
|
@@ -1389,8 +1439,11 @@ when 64 # TARGET REPORT
|
|
1389
1439
|
puts "---\n- Report Id: " + report_config.id.to_s + " \n"
|
1390
1440
|
puts "---\n- The report can be found via:\n https://#{@nsc_server}:3780" + report_summary.uri.to_s + "\n"
|
1391
1441
|
|
1392
|
-
|
1393
|
-
|
1442
|
+
report_filename = report_summary.uri.split('/').last
|
1443
|
+
if (args.name != nil)
|
1444
|
+
report_filename.sub! 'Document', "#{args.name}"
|
1445
|
+
end
|
1446
|
+
download("https://#{@nsc_server}:3780" + report_summary.uri.to_s, "./#{Time.now.strftime("%Y%m%d_%H%M%S_")}#{report_filename}", @nsc)
|
1394
1447
|
end
|
1395
1448
|
|
1396
1449
|
when 2 # list
|
@@ -1828,9 +1881,8 @@ when 4096 # TARGET TEMPLATE
|
|
1828
1881
|
templates = @nsc.list_scan_templates
|
1829
1882
|
templates.each do |template|
|
1830
1883
|
scan_template = Nexpose::ScanTemplate.load(@nsc, "#{template.id}")
|
1831
|
-
puts "Scan Template Id: #{scan_template.id}"
|
1832
|
-
|
1833
|
-
# upp scan_template
|
1884
|
+
puts "Scan Template Id: #{scan_template.id} \tScan Template Name: #{scan_template.name}"
|
1885
|
+
upp scan_template
|
1834
1886
|
end
|
1835
1887
|
when 128 # copy
|
1836
1888
|
uputs("ACTION", 'copy TEMPLATE action requested')
|
@@ -1981,6 +2033,61 @@ when 65536 # TARGET GROUP
|
|
1981
2033
|
uputs("ACTION", 'The action requested is not implemented for target')
|
1982
2034
|
puts 'The action requested is not implemented for target'
|
1983
2035
|
end
|
2036
|
+
when 262144 # TARGET SILO
|
2037
|
+
case @action
|
2038
|
+
when 1 # create
|
2039
|
+
uputs("ACTION", 'create SILO action requested')
|
2040
|
+
silo = Nexpose::Silo.new
|
2041
|
+
silo.max_assets = args.maxassets
|
2042
|
+
silo.max_users = args.maxusers
|
2043
|
+
silo.name = args.name
|
2044
|
+
silo.id = args.id
|
2045
|
+
silo.profile_id = 'default'
|
2046
|
+
silo_create = 'SILO NOT CREATED'
|
2047
|
+
|
2048
|
+
begin
|
2049
|
+
silo_create = silo.create(@nsc)
|
2050
|
+
rescue Nexpose::APIError => e
|
2051
|
+
# EJG add conditional api error handling...
|
2052
|
+
uputs("SILO", "An error occurred while attempting to create the silo: #{e.to_s}")
|
2053
|
+
STDERR.puts "ERROR [ " + e.to_s + " ]"
|
2054
|
+
exit(-1)
|
2055
|
+
end
|
2056
|
+
puts "Silo successfully created for silo id: #{silo_create}"
|
2057
|
+
upp silo
|
2058
|
+
|
2059
|
+
# Add current user as GA to the new silo
|
2060
|
+
user = Nexpose::MultiTenantUser.load(@nsc, @nsc.get_user_id(@nsc_user).id)
|
2061
|
+
user.silo_access << Nexpose::SiloAccess.new do |access|
|
2062
|
+
access.silo_id = silo_create
|
2063
|
+
access.role_name = Nexpose::Role::GLOBAL_ADMINISTRATOR
|
2064
|
+
access.default = false
|
2065
|
+
access.all_sites = true
|
2066
|
+
access.all_groups = true
|
2067
|
+
end
|
2068
|
+
begin
|
2069
|
+
user.save(@nsc)
|
2070
|
+
rescue Nexpose::APIError => e
|
2071
|
+
# EJG add conditional api error handling...
|
2072
|
+
uputs("SILO", "An error occurred while attempting to the user: #{e.to_s}")
|
2073
|
+
STDERR.puts "ERROR [ " + e.to_s + " ]"
|
2074
|
+
exit(-1)
|
2075
|
+
end
|
2076
|
+
puts "Successfully added user[#{@nsc_user}] to silo id: #{silo_create}"
|
2077
|
+
upp user
|
2078
|
+
when 2 # list
|
2079
|
+
uputs("ACTION", 'list SILO action requested')
|
2080
|
+
silos = @nsc.list_silos
|
2081
|
+
hdr = '%-15s' % 'id' + ' ' + '%-15s' % 'profile id' + ' ' + '%10s' % 'max users' + ' ' + '%15s' % 'max assets' + ' name'
|
2082
|
+
puts hdr
|
2083
|
+
silos.each do |silo|
|
2084
|
+
puts "#{silo.id.to_s.ljust(15)} #{silo.profile_id.ljust(15)} #{silo.max_users.rjust(10)} #{silo.max_assets.rjust(15)} #{silo.name}"
|
2085
|
+
upp silo
|
2086
|
+
end
|
2087
|
+
else
|
2088
|
+
uputs("ACTION", 'The action requested is not implemented for target')
|
2089
|
+
puts 'The action requested is not implemented for target'
|
2090
|
+
end
|
1984
2091
|
else
|
1985
2092
|
# there is no default target
|
1986
2093
|
uputs("ACTION", 'No default action requested')
|
data/lib/nexposecli/args.rb
CHANGED
@@ -78,6 +78,9 @@ module Nexposecli
|
|
78
78
|
short : T
|
79
79
|
desc : The SITE target is used to alter or create the SITE object
|
80
80
|
|
81
|
+
- name : SILO
|
82
|
+
desc : The SILO target is used to alter or create the SILO object
|
83
|
+
|
81
84
|
- name : ASSET
|
82
85
|
short : A
|
83
86
|
desc : The ASSET target is used to alter or create the ASSET object
|
@@ -166,10 +169,26 @@ module Nexposecli
|
|
166
169
|
desc : The object id being acted upon
|
167
170
|
required : true
|
168
171
|
|
172
|
+
- name : template
|
173
|
+
desc : The scan template id of the entity being acted upon
|
174
|
+
required : true
|
175
|
+
|
176
|
+
- name : silo
|
177
|
+
desc : The silo of the entity being acted upon
|
178
|
+
required : true
|
179
|
+
|
169
180
|
- name : site
|
170
181
|
desc : The site id of the object being acted upon
|
171
182
|
required : true
|
172
183
|
|
184
|
+
- name : maxusers
|
185
|
+
desc : The create silo maximum number of users
|
186
|
+
required : true
|
187
|
+
|
188
|
+
- name : maxassets
|
189
|
+
desc : The create silo maximum number of assets
|
190
|
+
required : true
|
191
|
+
|
173
192
|
- name : range
|
174
193
|
short : r
|
175
194
|
desc : The comma separated (begin,end) range of ip addresses to be acted upon
|
@@ -184,6 +203,10 @@ module Nexposecli
|
|
184
203
|
desc : Argument vector for the action, in the form key:value pairs
|
185
204
|
required : true
|
186
205
|
|
206
|
+
- name : output
|
207
|
+
desc : The desired format of the output, default, csv
|
208
|
+
required : true
|
209
|
+
|
187
210
|
- name : filter
|
188
211
|
short : f
|
189
212
|
desc : Filters which are applied to the action, in the form key:value pairs
|
data/lib/nexposecli/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexposecli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erik Gomez
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-03-
|
12
|
+
date: 2017-03-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nexpose
|