excl_site_asset_scan 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/extended-api.rb'))
4
+
5
+ #------------------------------------------------------------------------------------------------------
6
+ # == Synopsis
7
+ # Main script to execute specified API commands against a specified NSC
8
+ #
9
+ # == Usage
10
+ # ruby nexpose_api_util.rb --help
11
+ #
12
+ # == Author
13
+ # Christopher Lee, Rapid7 LLC
14
+ #------------------------------------------------------------------------------------------------------
15
+
16
+ begin
17
+ if ARGV.length > 0
18
+ $is_command_line = false
19
+ begin
20
+ options = Options.parse ARGV
21
+ extended_api = ::ExtendedAPI.new options.user, options.password, options.host
22
+ extended_api.do_login
23
+ case options.key
24
+ when 1 then
25
+ extended_api.print_asset_groups
26
+ when 2 then
27
+ extended_api.print_asset_group_info options.args
28
+ when 3 then
29
+ extended_api.start_excluded_scan options.args
30
+ else
31
+ puts "Invalid Input!"
32
+ end
33
+
34
+ rescue Exception => e
35
+ puts e
36
+ ensure
37
+ begin
38
+ if extended_api
39
+ extended_api.do_logout
40
+ end
41
+ rescue Nexpose::APIError => e
42
+ # Don't care, maybe session already dead
43
+ end
44
+ end
45
+ exit 0
46
+ else
47
+ puts 'Input required'
48
+ end
49
+ end
50
+
51
+
@@ -0,0 +1,41 @@
1
+ require 'ostruct'
2
+ require 'optparse'
3
+
4
+ #------------------------------------------------------------------------------------------------------
5
+ # Defines options to be executed against the NeXpose API
6
+ #------------------------------------------------------------------------------------------------------
7
+ class Options
8
+ def self.parse(args)
9
+ options = OpenStruct.new
10
+ options.verbose = false
11
+
12
+ option_parser = OptionParser.new do |option_parser|
13
+ option_parser.on("-h HOST", "The network address of the NeXpose instance - Required") {|arg| options.host=arg}
14
+ option_parser.on("-u USER", "The user name - Required") {|arg| options.user=arg}
15
+ option_parser.on("-p PASSWORD", "The password - Required") {|arg| options.password=arg}
16
+ option_parser.on("--n1", "List all the asset groups") {|arg| options.key=1}
17
+ option_parser.on("--n2 GI", "List an asset groups config. The GI (group id or group name is required)") do |arg|
18
+ options.key=2
19
+ options.args=arg
20
+ end
21
+ option_parser.on("--ses params", "Start an asset group excluded scan where params are a comma separated list of the site-id to scan followed by
22
+ asset group id(s) to exclude") do |arg|
23
+ options.key=3
24
+ options.args=arg.chomp
25
+ end
26
+ option_parser.on_tail("--help", "Help") do
27
+ puts option_parser
28
+ exit 0
29
+ end
30
+ end
31
+
32
+ begin
33
+ option_parser.parse!(args)
34
+ rescue OptionParser::ParseError => e
35
+ puts "#{e}\n\n#{option_parser}"
36
+ exit 1
37
+ end
38
+
39
+ options
40
+ end
41
+ end
@@ -0,0 +1,117 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'util.rb'))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'api-options.rb'))
3
+ require 'rubygems'
4
+ require 'rexml/document'
5
+ require 'hirb'
6
+ require 'nexpose'
7
+
8
+ #------------------------------------------------------------------------------------------------------
9
+ # Extends the base API functionality by combining common API commands to produce a simplified
10
+ # user command.
11
+ #------------------------------------------------------------------------------------------------------
12
+ class ExtendedAPI
13
+ attr_accessor :user_name, :password, :host, :nexpose_api, :scan_manager
14
+ @@connected = false
15
+
16
+ def initialize user_name, password, host
17
+ @user_name = user_name
18
+ @password = password
19
+ @host = host
20
+ @nexpose_api = Nexpose::Connection.new @host, @user_name, @password
21
+ end
22
+
23
+ #-------------------------------------------------------------------
24
+ # Logs in to NeXpose and sets a session key on the connector object.
25
+ #-------------------------------------------------------------------
26
+ def do_login
27
+ if not @@connected
28
+ begin
29
+ if @nexpose_api.login
30
+ @@connected = true
31
+ end
32
+ rescue Exception => e
33
+ puts e.message
34
+ end
35
+ end
36
+ end
37
+
38
+ #------------------------------------------------------
39
+ # Prints all asset group information in tabular format:
40
+ # | site_id | device_id | address | riskfactor |
41
+ #------------------------------------------------------
42
+ def print_asset_group_info group_id
43
+ group_configs = @nexpose_api.asset_group_config group_id
44
+ puts "\nASSET GROUP INFO (id: #{group_id})"
45
+ puts Hirb::Helpers::AutoTable.render group_configs, :fields => [:site_id, :device_id, :address, :riskfactor]
46
+ rescue Exception => e
47
+ if e.message =~ /Invalid groupID/
48
+ puts 'Group ID does not exist'
49
+ else
50
+ puts e.message
51
+ end
52
+ end
53
+
54
+ #----------------------------------------------------------------
55
+ # Prints asset group configuration information in tabular format:
56
+ # | site_id | device_id | address | riskfactor |
57
+ #----------------------------------------------------------------
58
+ def print_asset_groups
59
+ res = @nexpose_api.asset_groups_listing
60
+ puts "\nASSET GROUPS:"
61
+ puts Hirb::Helpers::AutoTable.render res, :fields => [:asset_group_id, :name, :description, :risk_score]
62
+ end
63
+
64
+ #
65
+ #
66
+ #
67
+ def start_excluded_scan scan_info
68
+ # Parse the scan_info object to get site
69
+ # to be scanned and the asset group(s) to exclude
70
+ parsed_string = scan_info.to_s.split ','
71
+ site_id = parsed_string[0]
72
+ unless Util.is_number? site_id
73
+ raise ArgumentError.new 'The site-id must be a number'
74
+ end
75
+
76
+ # Get all the device_ids for the site
77
+ device_listing_hash = @nexpose_api.site_device_listing site_id
78
+ device_ids = []
79
+ device_listing_hash.each do |device_listing|
80
+ device_ids << device_listing[:device_id].to_i
81
+ end
82
+
83
+ # Get all the devices associated with the group(s)
84
+ device_ids_excluded = []
85
+ parsed_string.delete_at(0)
86
+ parsed_string.each do |group_id|
87
+ group_infos = @nexpose_api.asset_group_config group_id
88
+ group_infos.each do |group_info|
89
+ device_ids_excluded << group_info[:device_id].to_i
90
+ end
91
+ end
92
+
93
+ # Remove all the devices in the group
94
+ devices_to_scan = device_ids - device_ids_excluded
95
+
96
+ # Hopefully this is not an empty set
97
+ if not devices_to_scan or devices_to_scan.empty?
98
+ raise "There are no devices left to scan after devices in groups: #{parsed_string.inspect} are removed from site: #{site_id}"
99
+ end
100
+
101
+ # Start an ad-hoc scan.
102
+ res = @nexpose_api.site_device_scan_start site_id, devices_to_scan, nil
103
+ if res
104
+ puts "Scan started scan ID: #{res[:scan_id]}, on engine ID: #{res[:engine_id]}"
105
+ else
106
+ put "Scan start failed for site #{site}"
107
+ end
108
+ end
109
+
110
+ #
111
+ #
112
+ #
113
+ def do_logout
114
+ @nexpose_api.logout
115
+ end
116
+
117
+ end
@@ -0,0 +1,33 @@
1
+ class Util
2
+
3
+ #------------------------------------------------------------------------------------------------------
4
+ # Checks if the input is a number
5
+ #
6
+ # input: The object that will be tested
7
+ #------------------------------------------------------------------------------------------------------
8
+ def self.is_number? input
9
+ true if Float input rescue false
10
+ end
11
+
12
+ #------------------------------------------------------------------------------------------------------
13
+ # Retrieves numeric input only from the command line
14
+ #
15
+ # mssg: The message to display that requests the input
16
+ #------------------------------------------------------------------------------------------------------
17
+ def self.get_numeric_input mssg
18
+ begin
19
+ while true
20
+ print mssg
21
+ input = gets().chomp()
22
+ if Util.is_number? input
23
+ return input.to_i
24
+ else
25
+ puts "Input is not a number"
26
+ end
27
+ end
28
+ rescue Exception => e
29
+ puts e.message
30
+ end
31
+ end
32
+
33
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: excl_site_asset_scan
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Christopher Lee
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-07-20 00:00:00.000000000 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nexpose
17
+ requirement: &23552100 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 0.0.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *23552100
26
+ - !ruby/object:Gem::Dependency
27
+ name: hirb
28
+ requirement: &23551800 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.5
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *23551800
37
+ description: ! " \tList asset groups, list information about certain asset groups,
38
+ start a site scan with certain asset groups excluded.\n"
39
+ email: christopher_lee@rapid7.com
40
+ executables:
41
+ - nexpose_api_util
42
+ extensions: []
43
+ extra_rdoc_files: []
44
+ files:
45
+ - lib/api-options.rb
46
+ - lib/extended-api.rb
47
+ - lib/util.rb
48
+ - bin/nexpose_api_util
49
+ has_rdoc: true
50
+ homepage: https://github.com/chrlee/NeXpose-ScanManager-Interface/tree/master/examples/excluded_asset_scan
51
+ licenses: []
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 1.5.2
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: List asset groups, list information about certain asset groups, start a site
74
+ scan with certain asset groups excluded.
75
+ test_files: []