nexpose 7.2.1 → 7.3.0

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.
@@ -0,0 +1,212 @@
1
+ require 'nexpose'
2
+
3
+ module Eso
4
+ module ServiceNames
5
+ ACTIVE_DIRECTORY = 'active-directory'
6
+ AWS = 'amazon-web-services'
7
+ AZURE = 'azure'
8
+ DXL = 'dxl'
9
+ EPO = 'epo'
10
+ NEXPOSE = 'nexpose'
11
+ end
12
+
13
+ module StepNames
14
+ ADD_TO_SITE = 'add-to-site'
15
+ ADD_VULN_AND_SCAN = 'add-vulnerabilities-to-site-and-scan'
16
+ DISCOVER_ACTIVE_DIRECTORY = 'discover-ad-assets'
17
+ DISCOVER_AWS_ASSETS = 'discover-aws-assets'
18
+ DISCOVER_AZURE_ASSETS = 'discover-azure-assets'
19
+ DISCOVER_EPO = 'discover-epo-assets'
20
+ DISCOVER_KNOWN = 'discover-known-assets'
21
+ DISCOVER_NEW = 'discover-new-assets'
22
+ DISCOVERY_CONFIG_METADATA = 'discoveryConfigMetadata'
23
+ EMPTY = ''
24
+ FILE_REPUTATION_TRIGGER = 'tie-file-reputation-trigger'
25
+ IMPORT_EXTERNAL = 'import-external-assets'
26
+ NEW_ASSET_VULN = 'new-asset-vulnerability'
27
+ NEW_VULN = 'new-vulnerabilities'
28
+ PUBLISH_VULN_INT_TYPE = 'publish-vulnerability-integration-type'
29
+ PUSH_RISK_SCORE = 'push-risk-score'
30
+ RISK_SCORE_UPDATED = 'risk-score-updated'
31
+ SCAN = 'scan'
32
+ SCAN_IN_SITE = 'scan-in-site'
33
+ SYNC_EXTERNAL = 'sync-external-assets'
34
+ TAG = 'tag'
35
+ VERIFY_AWS_ASSETS = 'verify-aws-targets'
36
+ VERIFY_EXTERNAL_TARGETS = 'verify-external-targets'
37
+ VULN_DETAILS = 'vulnerability-details'
38
+ VULN_DETAILS_REQUEST = 'vulnerability-details-request'
39
+ end
40
+
41
+ module Values
42
+ ARRAY = 'Array'
43
+ BOOLEAN = 'Boolean'
44
+ INTEGER = 'Integer'
45
+ OBJECT = 'Object'
46
+ STRING = 'String'
47
+ end
48
+
49
+ module StepConfigTypes
50
+ DISCOVERY_CONFIG = [StepNames::DISCOVER_ACTIVE_DIRECTORY,
51
+ StepNames::DISCOVER_AWS_ASSETS,
52
+ StepNames::DISCOVER_AZURE_ASSETS,
53
+ StepNames::DISCOVER_EPO,
54
+ StepNames::DISCOVER_KNOWN,
55
+ StepNames::DISCOVER_NEW,
56
+ StepNames::FILE_REPUTATION_TRIGGER,
57
+ StepNames::PUBLISH_VULN_INT_TYPE,
58
+ StepNames::PUSH_RISK_SCORE,
59
+ StepNames::VULN_DETAILS_REQUEST]
60
+ EMPTY = [StepNames::NEW_ASSET_VULN,
61
+ StepNames::NEW_VULN,
62
+ StepNames::RISK_SCORE_UPDATED,
63
+ StepNames::VULN_DETAILS]
64
+ SITE = [StepNames::ADD_TO_SITE,
65
+ StepNames::ADD_VULN_AND_SCAN,
66
+ StepNames::IMPORT_EXTERNAL,
67
+ StepNames::SCAN,
68
+ StepNames::SCAN_IN_SITE,
69
+ StepNames::SYNC_EXTERNAL]
70
+ TAG = [StepNames::TAG]
71
+ VERIFY = [StepNames::DISCOVER_AWS_ASSETS]
72
+ end
73
+
74
+ module Filters
75
+ CVSS_SCORE = 'CVSS_SCORE'
76
+ DHCP_HOST_NAME = 'DHCP_HOST_NAME'
77
+ HOURS_SINCE_LAST_SCAN= 'HOURS_SINCE_LAST_SCAN'
78
+ HOURS_SINCE_LAST_SCAN_ITEM = 'HOURS_SINCE_LAST_SCAN_ITEM'
79
+ IP_ADDRESS = 'IP_ADDRESS'
80
+ IP_RANGE = 'IP_RANGE'
81
+ MAC_ADDRESS = 'MAC_ADDRESS'
82
+ OPEN_PORT = 'OPEN_PORT'
83
+ RISK_SCORE = 'RISK_SCORE'
84
+ SERVICE_NAME = 'SERVICE_NAME'
85
+ end
86
+
87
+ module Nexpose
88
+ def self.create_discovery_workflow(conductor:, name:, step1_type:, step1_param: nil, step2_type:, step2_param:)
89
+ step1 = self.send("create_#{step1_type.to_s.gsub(/-/, "_")}_step", id: step1_param)
90
+ step2 = self.send("create_#{step2_type.to_s.gsub(/-/, "_")}_step", id: step2_param)
91
+ step2.previous_type_name = step1.type_name
92
+ conductor.create_workflow(name: name, steps: [step1, step2])
93
+ end
94
+
95
+ def self.create_scan_new_vuln_workflow(conductor:, name:, filters:, site_id:)
96
+ step1 = self.create_new_vuln_step(workflow: nil, filters: filters, previous_type_name: StepNames::EMPTY)
97
+ step2 = self.create_add_vuln_and_scan_step(id: site_id)
98
+ step2.previous_type_name = step1.type_name
99
+ conductor.create_workflow(name: name, steps: [step1, step2])
100
+ end
101
+
102
+ def self.create_file_trigger_workflow(conductor:, name:, step1_param:, step2_param:)
103
+ step1 = self.create_file_reputation_step(workflow: nil, id: step1_param)
104
+ step2 = self.create_tag_step(workflow: nil, id: step2_param)
105
+ step2.previous_type_name = step1.type_name
106
+ conductor.create_workflow(name: name, steps: [step1, step2])
107
+ end
108
+
109
+ def self.create_scan_in_site_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
110
+ Step.new(workflow: workflow,
111
+ service_name: ServiceNames::NEXPOSE,
112
+ type_name: StepNames::SCAN_IN_SITE,
113
+ previous_type_name: previous_type_name)
114
+ .add_property(StepConfiguration::ConfigParamProperties::SITE_ID, id)
115
+ end
116
+
117
+ def self.create_file_reputation_step(workflow: nil, id:)
118
+ Step.new(workflow: workflow,
119
+ service_name: ServiceNames::DXL,
120
+ type_name: StepNames::FILE_REPUTATION_TRIGGER,
121
+ previous_type_name: nil)
122
+ .add_property(StepConfiguration::ConfigParamProperties::DISCOVERY_CONFIG_ID, id)
123
+ end
124
+
125
+ def self.create_discover_new_assets_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
126
+ Step.new(workflow: workflow,
127
+ service_name: ServiceNames::NEXPOSE,
128
+ type_name: StepNames::DISCOVER_NEW,
129
+ previous_type_name: previous_type_name)
130
+ .add_property(StepConfiguration::ConfigParamProperties::DISCOVERY_CONFIG_ID, id)
131
+ end
132
+
133
+ def self.create_discover_known_assets_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
134
+ step = Step.new(workflow: workflow,
135
+ service_name: ServiceNames::NEXPOSE,
136
+ type_name: StepNames::DISCOVER_KNOWN,
137
+ previous_type_name: previous_type_name)
138
+ .add_property(StepConfiguration::ConfigParamProperties::DISCOVERY_CONFIG_ID, id)
139
+ config_params = step.configuration_params
140
+ config_params[:HOURS_SINCE_LAST_SCAN] = {
141
+ :valueClass => Values::ARRAY,
142
+ :items => [
143
+ {
144
+ :valueClass => Values::OBJECT,
145
+ :objectType => Filters::HOURS_SINCE_LAST_SCAN_ITEM,
146
+ :properties => {
147
+ :operator => {
148
+ :valueClass => Values::STRING,
149
+ :value => ::Nexpose::Search::Operator::GREATER_THAN
150
+ },
151
+ :operand1 => {
152
+ :valueClass => Values::STRING,
153
+ :value => '1'
154
+ }
155
+ }
156
+ }
157
+ ]
158
+ }
159
+ step.configuration_params = config_params
160
+ step
161
+ end
162
+
163
+ def self.create_new_vuln_step(workflow: nil, filters:, previous_type_name: StepNames::EMPTY)
164
+ # The filter definitions on the server are not standard at this point so that is why it is necessary to hard code this
165
+ # Opening a defect to fix the consistency on these on the backend so we can use the add_filter function in the automation
166
+ step = Step.new(workflow: workflow,
167
+ service_name: ServiceNames::NEXPOSE,
168
+ type_name: StepNames::NEW_VULN,
169
+ previous_type_name: previous_type_name)
170
+
171
+ filters.each { |filter| step.add_filter(filter) }
172
+ step
173
+ end
174
+
175
+ def self.create_add_vuln_and_scan_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
176
+ Step.new(workflow: workflow,
177
+ service_name: ServiceNames::NEXPOSE,
178
+ type_name: StepNames::ADD_VULN_AND_SCAN,
179
+ previous_type_name: previous_type_name)
180
+ .add_property(StepConfiguration::ConfigParamProperties::SITE_ID, id)
181
+ end
182
+
183
+ def self.create_add_to_site_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
184
+ Step.new(workflow: workflow,
185
+ service_name: ServiceNames::NEXPOSE,
186
+ type_name: StepNames::ADD_TO_SITE,
187
+ previous_type_name: previous_type_name)
188
+ .add_property(StepConfiguration::ConfigParamProperties::SITE_ID, id)
189
+ end
190
+
191
+ def self.create_scan_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
192
+ Step.new(workflow: workflow,
193
+ service_name: ServiceNames::NEXPOSE,
194
+ type_name: StepNames::SCAN,
195
+ previous_type_name: previous_type_name)
196
+ .add_property(StepConfiguration::ConfigParamProperties::SITE_ID, id)
197
+ end
198
+
199
+ def self.create_tag_step(workflow: nil, id:, previous_type_name: StepNames::EMPTY)
200
+ Step.new(workflow: workflow,
201
+ service_name: ServiceNames::NEXPOSE,
202
+ type_name: StepNames::TAG,
203
+ previous_type_name: previous_type_name)
204
+ .add_property(StepConfiguration::ConfigParamProperties::TAG_ID, id)
205
+ end
206
+
207
+ def self.get_discover_step(workflow: )
208
+ workflow.get_step(StepNames::DISCOVER_NEW) || workflow.get_step(StepNames::DISCOVER_KNOWN)
209
+ end
210
+ end
211
+ end
212
+
@@ -0,0 +1,83 @@
1
+ module Eso
2
+ class Service
3
+ attr_accessor :host
4
+
5
+ attr_accessor :port
6
+
7
+ attr_accessor :url
8
+
9
+ CONTENT_TYPE_JSON = 'application/json; charset-utf-8'
10
+
11
+ def initialize(host:, port: 3780, nsc:)
12
+ @host = host
13
+ @port = port
14
+ @nexpose_console = nsc
15
+ end
16
+
17
+ def get(url:, content_type: CONTENT_TYPE_JSON)
18
+ get = Net::HTTP::Get.new(url)
19
+ get.set_content_type(content_type)
20
+ request(request: get)
21
+ end
22
+
23
+ def put(url:, payload:, content_type: CONTENT_TYPE_JSON)
24
+ put = Net::HTTP::Put.new(url)
25
+ put.set_content_type(content_type)
26
+ put.body = payload.to_s if payload
27
+ request(request: put)
28
+ end
29
+
30
+ def post(url:, payload: nil, content_type: CONTENT_TYPE_JSON)
31
+ post = Net::HTTP::Post.new(url)
32
+ post.set_content_type(content_type)
33
+ post.body = payload.to_s if payload
34
+ request(request: post)
35
+ end
36
+
37
+ def delete(url:, content_type: CONTENT_TYPE_JSON)
38
+ delete = Net::HTTP::Delete.new(url)
39
+ delete.set_content_type(content_type)
40
+ request(request: delete)
41
+ end
42
+
43
+ def http(timeout:)
44
+ http = Net::HTTP.new(@host, @port)
45
+ http.read_timeout = timeout if timeout
46
+ http.use_ssl = false
47
+ http
48
+ end
49
+
50
+ def https(timeout:)
51
+ http = Net::HTTP.new(@host, @port)
52
+ http.read_timeout = timeout if timeout
53
+ http.use_ssl = true
54
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
55
+ http
56
+ end
57
+
58
+ def add_nexpose_session(request:)
59
+ request.add_field('nexposeCCSessionID', @nexpose_console.session_id)
60
+ request.add_field('Cookie', "nexposeCCSessionID=#{@nexpose_console.session_id}")
61
+ request.add_field('X-Requested-With', 'XMLHttpRequest')
62
+ end
63
+
64
+ def request(request:, timeout: nil)
65
+ http = https(timeout: timeout)
66
+ add_nexpose_session(request: request)
67
+ response = http.request(request)
68
+ case response
69
+ when Net::HTTPOK, Net::HTTPCreated
70
+ rv = nil
71
+ if response.content_type == "application/json" && !response.body.empty?
72
+ json_data = JSON.parse(response.body, symbolize_names: true)
73
+ json_data[:data].nil? ? rv = json_data : rv = json_data[:data]
74
+ end
75
+ rv
76
+ when Net::HTTPForbidden
77
+ raise "Access denied. Response was #{response.body}"
78
+ else
79
+ raise "There was an error sending the request. Response was #{response.body}"
80
+ end
81
+ end
82
+ end
83
+ end
data/lib/eso/step.rb ADDED
@@ -0,0 +1,166 @@
1
+ module Eso
2
+ # Object representation of a step, which are attributes of Workflows and Integration Options
3
+ #
4
+ class Step
5
+ # UUID of this step. This is generated on creation on the server.
6
+ attr_accessor :uuid
7
+
8
+ # Type of this step. Should be one of Eso::ServiceNames
9
+ attr_accessor :serviceName
10
+
11
+ # The configuration for this step.
12
+ attr_accessor :stepConfiguration
13
+
14
+ # Constructor for Step.
15
+ #
16
+ # @param [String] uuid UUID of this Step. This is created on the server side upon creation through the API.
17
+ # @param [String] service_name The name of step this is.
18
+ # @param [Workflow] workflow The workflow this step belongs to.
19
+ # @param [Hash] configuration_params Hash of the parameters for this step.
20
+ #
21
+ def initialize(uuid: nil, service_name:, workflow: nil, type_name:, previous_type_name: StepNames::EMPTY, configuration_params: nil)
22
+ @uuid = uuid if uuid
23
+ @serviceName = service_name
24
+ @stepConfiguration = StepConfiguration.new(type_name, previous_type_name)
25
+ @stepConfiguration.configurationParams = configuration_params if configuration_params
26
+ @stepConfiguration.workflowID = workflow.id if workflow
27
+ end
28
+
29
+ # Return the configuration parameters for this step.
30
+ #
31
+ # @return [Hash] Hash of the configuration parameters for this step.
32
+ #
33
+ def configuration_params
34
+ @stepConfiguration.configurationParams
35
+ end
36
+
37
+ # Set the the configuration parameters for this step.
38
+ #
39
+ # @param [Hash] config_params of the new configuration parameters you would like to set.
40
+ # @return [Hash] Hash of the updated configuration parameters for this step.
41
+ #
42
+ def configuration_params=(config_params)
43
+ @stepConfiguration.configurationParams = config_params
44
+ end
45
+
46
+ # Return the type name for this step.
47
+ #
48
+ # @return [String] The currently configured type name.
49
+ #
50
+ def type_name
51
+ @stepConfiguration.typeName
52
+ end
53
+
54
+ # Set the type name for this step.
55
+ #
56
+ # @param [String] The new type_name that you would like to set this to. See Eso::StepNames for valid names.
57
+ # @return [String] The newly set type name.
58
+ #
59
+ def type_name=(wf_action_name)
60
+ @stepConfiguration.typeName = wf_action_name
61
+ end
62
+
63
+ # Return the previous type name for this step.
64
+ #
65
+ # @return [String] The previous type name for this step.
66
+ #
67
+ def previous_type_name
68
+ @stepConfiguration.previousTypeName
69
+ end
70
+
71
+ # Set the previous type name for this step.
72
+ #
73
+ # @param [String] The new previous type name that you would like to set. See Eso::StepNames for valid names.
74
+ # @return [String] Hash of the configuration parameters for this step.
75
+ #
76
+ def previous_type_name=(action_name)
77
+ @stepConfiguration.previousTypeName = action_name
78
+ end
79
+
80
+ # Return the properties of this step.
81
+ #
82
+ # @return [Hash{}] Hash of the properties for this step.
83
+ #
84
+ def properties
85
+ @stepConfiguration.configurationParams[:properties]
86
+ end
87
+
88
+ # Set the properties of this step.
89
+ #
90
+ # @param [Hash] The new properties to set for this step.
91
+ # @return [Hash] Hash of the newly configured properties for this step.
92
+ #
93
+ def properties=(new_properties)
94
+ @stepConfiguration.configurationParams[:properties] = new_properties
95
+ end
96
+
97
+ # Determine the siteID of this step, if it exists
98
+ #
99
+ # @return [String|nil] The String siteID value or nil if no siteID
100
+ def site_id
101
+ if @stepConfiguration.configurationParams[:properties][:siteID]
102
+ @stepConfiguration.configurationParams[:properties][:siteID][:value]
103
+ end
104
+ end
105
+
106
+ # Returns all configured filters for this step.
107
+ #
108
+ # @return [Array] An array of the currently configured filters for this step, each represented as a hash.
109
+ #
110
+ def filters
111
+ rv = {}
112
+ self.properties.each_pair do |key, value|
113
+ if value[:properties]
114
+ rv[key] = value if value[:properties].has_key?(:operators)
115
+ end
116
+ end
117
+ rv
118
+ end
119
+
120
+ # Convenience method which calls the #add_property method of the @stepConfiguration, but returns the Step
121
+ #
122
+ # @return [Step] Returns this Step for chaining
123
+ def add_property(name, value)
124
+ @stepConfiguration.add_property(name, value)
125
+ self
126
+ end
127
+
128
+ # Convenience method which calls the #add_property method of the @stepConfiguration, but returns the Step
129
+ #
130
+ # @return [Step] Returns this Step for chaining
131
+ def update_property(name, value)
132
+ @stepConfiguration.add_property(name, value)
133
+ self
134
+ end
135
+
136
+ # Add the specified filter to this step. The filter is converted to a hash and saved as such instead of being saved as a ESO::Filter object.
137
+ #
138
+ # @param [Filter] filter The filter to add to this step.
139
+ #
140
+ def add_filter(filter)
141
+ @stepConfiguration.configurationParams[:properties].merge! filter.to_hash
142
+ end
143
+
144
+ # Return this step in a JSON digestible format.
145
+ #
146
+ # @return [String] JSON interpretation of this step.
147
+ #
148
+ def to_json
149
+ self.to_hash.to_json
150
+ end
151
+
152
+ # Return this step as a hash.
153
+ #
154
+ # @return [Hash] Hash interpretation of this step.
155
+ #
156
+ def to_hash
157
+ hash = {}
158
+ instance_variables.each do |var|
159
+ value = instance_variable_get(var)
160
+ value = value.to_h if value.respond_to?('to_h')
161
+ hash[var.to_s.delete('@')] = value
162
+ end
163
+ hash
164
+ end
165
+ end
166
+ end