nexposecli 0.2.6 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|