nexpose 7.2.1 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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