nexpose_ticketing 1.0.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module NexposeTicketing
2
- VERSION = "1.0.2"
2
+ VERSION = "1.2.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexpose_ticketing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damian Finol
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-02-08 00:00:00.000000000 Z
13
+ date: 2016-07-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nexpose
@@ -18,20 +18,20 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '2.1'
21
+ version: '3.1'
22
22
  - - ">="
23
23
  - !ruby/object:Gem::Version
24
- version: 2.1.0
24
+ version: 3.1.0
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
29
  - - "~>"
30
30
  - !ruby/object:Gem::Version
31
- version: '2.1'
31
+ version: '3.1'
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 2.1.0
34
+ version: 3.1.0
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: savon
37
37
  requirement: !ruby/object:Gem::Requirement
@@ -105,22 +105,15 @@ description: This gem provides a Ruby implementation of different integrations w
105
105
  email:
106
106
  - integrations_support@rapid7.com
107
107
  executables:
108
- - nexpose_jira
109
- - nexpose_servicenow
110
- - nexpose_remedy
111
- - nexpose_servicedesk
108
+ - nexpose_ticketing
112
109
  extensions: []
113
110
  extra_rdoc_files:
114
111
  - README.md
115
112
  files:
116
113
  - Gemfile
117
114
  - README.md
118
- - bin/nexpose_jira
119
- - bin/nexpose_remedy
120
- - bin/nexpose_servicedesk
121
- - bin/nexpose_servicenow
115
+ - bin/nexpose_ticketing
122
116
  - lib/nexpose_ticketing.rb
123
- - lib/nexpose_ticketing/common_helper.rb
124
117
  - lib/nexpose_ticketing/config/jira.config
125
118
  - lib/nexpose_ticketing/config/remedy.config
126
119
  - lib/nexpose_ticketing/config/remedy_wsdl/HPD_IncidentInterface_Create_WS.xml
@@ -129,13 +122,19 @@ files:
129
122
  - lib/nexpose_ticketing/config/servicenow.config
130
123
  - lib/nexpose_ticketing/config/servicenow_updateset/Rapid7_Nexpose_Ticketing_ServiceNow_update_set.xml
131
124
  - lib/nexpose_ticketing/config/ticket_service.config
125
+ - lib/nexpose_ticketing/helpers/base_helper.rb
132
126
  - lib/nexpose_ticketing/helpers/jira_helper.rb
133
127
  - lib/nexpose_ticketing/helpers/remedy_helper.rb
134
128
  - lib/nexpose_ticketing/helpers/servicedesk_helper.rb
135
129
  - lib/nexpose_ticketing/helpers/servicenow_helper.rb
130
+ - lib/nexpose_ticketing/modes/base_mode.rb
131
+ - lib/nexpose_ticketing/modes/default_mode.rb
132
+ - lib/nexpose_ticketing/modes/ip_mode.rb
133
+ - lib/nexpose_ticketing/modes/vulnerability_mode.rb
136
134
  - lib/nexpose_ticketing/nx_logger.rb
137
135
  - lib/nexpose_ticketing/queries.rb
138
136
  - lib/nexpose_ticketing/report_helper.rb
137
+ - lib/nexpose_ticketing/ticket_metrics.rb
139
138
  - lib/nexpose_ticketing/ticket_repository.rb
140
139
  - lib/nexpose_ticketing/ticket_service.rb
141
140
  - lib/nexpose_ticketing/version.rb
@@ -151,7 +150,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
151
150
  requirements:
152
151
  - - ">="
153
152
  - !ruby/object:Gem::Version
154
- version: '1.9'
153
+ version: 2.1.5
155
154
  required_rubygems_version: !ruby/object:Gem::Requirement
156
155
  requirements:
157
156
  - - ">="
data/bin/nexpose_jira DELETED
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'yaml'
3
- require 'nexpose_ticketing'
4
- require 'nexpose_ticketing/nx_logger'
5
- require 'nexpose_ticketing/version'
6
-
7
- log = NexposeTicketing::NxLogger.instance
8
- log.setup_statistics_collection('Atlassian', 'JIRA', NexposeTicketing::VERSION)
9
- log.setup_logging(true, 'info')
10
-
11
- # Path to the JIRA Configuration file.
12
- JIRA_CONFIG_PATH = File.join(File.dirname(__FILE__),
13
- '../lib/nexpose_ticketing/config/jira.config')
14
-
15
- current_encoding = Encoding.default_external=Encoding.find("UTF-8")
16
-
17
- # Read in JIRA options from jira.config.
18
- jira_options = begin
19
- YAML.load_file(JIRA_CONFIG_PATH)
20
- rescue ArgumentError => e
21
- raise "Could not parse YAML #{JIRA_CONFIG_PATH} : #{e.message}"
22
- end
23
-
24
- log.log_message("Current Encoding set to: #{current_encoding}")
25
-
26
- # Initialize Ticket Service using JIRA.
27
- NexposeTicketing.start(jira_options)
data/bin/nexpose_remedy DELETED
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'yaml'
3
- require 'nexpose_ticketing'
4
- require 'nexpose_ticketing/nx_logger'
5
- require 'nexpose_ticketing/version'
6
-
7
- log = NexposeTicketing::NxLogger.instance
8
- log.setup_statistics_collection('bmc', 'Remedy', NexposeTicketing::VERSION)
9
- log.setup_logging(true, 'info')
10
-
11
- # Path to ServiceNow configuration file
12
- REMEDY_CONFIG_PATH = File.join(File.dirname(__FILE__),
13
- '../lib/nexpose_ticketing/config/remedy.config')
14
-
15
- current_encoding = Encoding.default_external=Encoding.find("UTF-8")
16
-
17
- # Read in ServiceNow options from servicenow.config
18
- remedy_options = begin
19
- YAML.load_file(REMEDY_CONFIG_PATH)
20
- rescue ArgumentError => e
21
- raise "Could not parse YAML #{REMEDY_CONFIG_PATH} : #{e.message}"
22
- end
23
-
24
- log.log_message("Current Encoding set to: #{current_encoding}")
25
-
26
- # Initialize Nexpose Ticket Service using Remedy
27
- NexposeTicketing.start(remedy_options)
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'yaml'
3
- require 'nexpose_ticketing'
4
- require 'nexpose_ticketing/nx_logger'
5
- require 'nexpose_ticketing/version'
6
-
7
- log = NexposeTicketing::NxLogger.instance
8
- log.setup_statistics_collection('ManageEngine', 'ServiceDesk', NexposeTicketing::VERSION)
9
- log.setup_logging(true, 'info')
10
-
11
- # Path to ServiceNow configuration file
12
- SERVICEDESK_CONFIG_PATH = File.join(File.dirname(__FILE__),
13
- '../lib/nexpose_ticketing/config/servicedesk.config')
14
-
15
- current_encoding = Encoding.default_external=Encoding.find("UTF-8")
16
-
17
- # Read in ServiceDesk options from servicenow.config
18
- servicedesk_options = begin
19
- YAML.load_file(SERVICEDESK_CONFIG_PATH)
20
- rescue ArgumentError => e
21
- raise "Could not parse YAML #{SERVICEDESK_CONFIG_PATH} : #{e.message}"
22
- end
23
-
24
- log.log_message("Current Encoding set to: #{current_encoding}")
25
-
26
- # Initialize Nexpose Ticket Service using ServiceDesk
27
- NexposeTicketing.start(servicedesk_options)
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'yaml'
3
- require 'nexpose_ticketing'
4
- require 'nexpose_ticketing/nx_logger'
5
- require 'nexpose_ticketing/version'
6
-
7
- log = NexposeTicketing::NxLogger.instance
8
- log.setup_statistics_collection('ServiceNow', 'ServiceNow', NexposeTicketing::VERSION)
9
- log.setup_logging(true, 'info')
10
-
11
- # Path to ServiceNow configuration file
12
- SERVICENOW_CONFIG_PATH = File.join(File.dirname(__FILE__),
13
- '../lib/nexpose_ticketing/config/servicenow.config')
14
-
15
- current_encoding = Encoding.default_external=Encoding.find("UTF-8")
16
-
17
- # Read in ServiceNow options from servicenow.config
18
- servicenow_options = begin
19
- YAML.load_file(SERVICENOW_CONFIG_PATH)
20
- rescue ArgumentError => e
21
- raise "Could not parse YAML #{SERVICENOW_CONFIG_PATH} : #{e.message}"
22
- end
23
-
24
- log.log_message("Current Encoding set to: #{current_encoding}")
25
-
26
- # Initialize Nexpose Ticket Service using ServiceNow
27
- NexposeTicketing.start(servicenow_options)
@@ -1,344 +0,0 @@
1
- module NexposeTicketing
2
- class CommonHelper
3
- MAX_NUM_REFS = 3
4
-
5
- def initialize(options)
6
- @ticketing_mode = options[:ticket_mode]
7
- end
8
-
9
- # Gets the base description hash from the relevant mode-specific method
10
- # which can converted into a finished description.
11
- #
12
- # - +nexpose_id+ - The site or tag indentifier.
13
- # - +options+ - The options read from the ticket config file.
14
- #
15
- # * *Returns* :
16
- # - Hash containing ticket description information.
17
- #
18
- def get_description(nexpose_id, row)
19
- description = { nxid: "NXID: #{generate_nxid(nexpose_id, row)}" }
20
- case @ticketing_mode
21
- when 'D' then get_default_ticket_description(description, row)
22
- when 'I' then get_ip_ticket_description(description, row)
23
- when 'V' then get_vuln_ticket_description(description, row)
24
- else fail "Ticketing mode #{@ticketing_mode} not recognised."
25
- end
26
- end
27
-
28
- # Updates an existing description hash containing information
29
- # necessary to generate a ticket description.
30
- # Note that Default mode tickets may not be updated.
31
- #
32
- # - +description+ - The existing ticket hash to be updated.
33
- # - +row+ - CSV row containing vulnerability data.
34
- #
35
- # * *Returns* :
36
- # - Hash containing ticket description information.
37
- #
38
- def update_description(description, row)
39
- case @ticketing_mode
40
- when 'I' then return update_ip_ticket_description(description, row)
41
- when 'V' then return update_vuln_ticket_description(description, row)
42
- else description
43
- end
44
- end
45
-
46
- # Generates a final description string based on a description hash.
47
- #
48
- # - +description+ - The finished ticket hash to be converted.
49
- #
50
- # * *Returns* :
51
- # - String containing ticket description text.
52
- #
53
- def print_description(description)
54
- ticket = case @ticketing_mode
55
- when 'D' then print_default_ticket_description(description)
56
- when 'I' then print_ip_ticket_description(description)
57
- when 'V' then print_vuln_ticket_description(description)
58
- else fail "Ticketing mode #{@ticketing_mode} not recognised."
59
- end
60
- ticket << "\n\n\n#{description[:nxid]}"
61
- ticket
62
- end
63
-
64
- # Generates a hash containing the information necessary
65
- # to generate a Default-mode ticket description.
66
- #
67
- # - +description+ - Base ticket hash with NXID.
68
- # - +row+ - CSV row containing vulnerability data.
69
- #
70
- # * *Returns* :
71
- # - Hash containing ticket description information.
72
- #
73
- def get_default_ticket_description(description, row)
74
- description[:header] = get_vuln_header(row)
75
- description[:header] << get_discovery_info(row)
76
- description[:references] = get_references(row)
77
- description[:solutions] = get_solutions(row)
78
- description
79
- end
80
-
81
- # Generates a hash containing the information necessary
82
- # to generate an IP-mode ticket description.
83
- #
84
- # - +description+ - Base ticket hash with NXID.
85
- # - +row+ - CSV row containing vulnerability data.
86
- #
87
- # * *Returns* :
88
- # - Hash containing ticket description information.
89
- #
90
- def get_ip_ticket_description(description, row)
91
- description[:vulnerabilities] = []
92
-
93
- status = row['comparison']
94
- vuln_info = "++ #{status} Vulnerabilities ++\n" if !status.nil?
95
- description[:ticket_status] = status
96
-
97
- vuln_info = vuln_info.to_s + get_vuln_info(row)
98
- description[:vulnerabilities] << vuln_info
99
- description
100
- end
101
-
102
- # Generates a hash containing the information necessary
103
- # to generate a Vulnerability-mode ticket description.
104
- #
105
- # - +description+ - Base ticket hash with NXID.
106
- # - +row+ - CSV row containing vulnerability data.
107
- #
108
- # * *Returns* :
109
- # - Hash containing ticket description information.
110
- #
111
- def get_vuln_ticket_description(description, row)
112
- description[:header] = get_vuln_header(row)
113
- description[:references] = get_references(row)
114
- description[:solutions] = get_solutions(row)
115
- description[:assets] = get_assets(row)
116
- description
117
- end
118
-
119
- # Updates an existing IP-mode description hash containing information
120
- # necessary to generate a ticket description.
121
- #
122
- # - +description+ - The existing ticket hash to be updated.
123
- # - +row+ - CSV row containing vulnerability data.
124
- #
125
- # * *Returns* :
126
- # - Hash containing updated ticket description information.
127
- #
128
- def update_ip_ticket_description(description, row)
129
- status = row['comparison']
130
- header = "++ #{status} Vulnerabilities ++\n"
131
- header = "" unless description[:ticket_status] != status
132
-
133
- description[:vulnerabilities] << "#{header}#{get_vuln_info(row)}"
134
- description
135
- end
136
-
137
- # Updates an existing Vulnerability-mode description hash containing
138
- # information necessary to generate a ticket description.
139
- #
140
- # - +description+ - The existing ticket hash to be updated.
141
- # - +row+ - CSV row containing vulnerability data.
142
- #
143
- # * *Returns* :
144
- # - Hash containing updated ticket description information.
145
- #
146
- def update_vuln_ticket_description(description, row)
147
- description[:assets] += "\n#{get_assets(row)}"
148
- description
149
- end
150
-
151
- # Generates a final description string based on a Default-mode
152
- # description hash.
153
- #
154
- # - +description+ - The finished ticket hash to be converted.
155
- #
156
- # * *Returns* :
157
- # - String containing ticket description text.
158
- #
159
- def print_default_ticket_description(description)
160
- ticket = "#{description[:header]}\n#{description[:references]}"
161
- ticket << "#{description[:solutions]}"
162
- ticket
163
- end
164
-
165
- # Generates a final description string based on an IP-mode
166
- # description hash.
167
- #
168
- # - +description+ - The finished ticket hash to be converted.
169
- #
170
- # * *Returns* :
171
- # - String containing ticket description text.
172
- #
173
- def print_ip_ticket_description(description)
174
- ticket = ''
175
- description[:vulnerabilities].each { |v| ticket << "#{v}\n" }
176
- ticket
177
- end
178
-
179
- # Generates a final description string based on a Vulnerability-mode
180
- # description hash.
181
- #
182
- # - +description+ - The finished ticket hash to be converted.
183
- #
184
- # * *Returns* :
185
- # - String containing ticket description text.
186
- #
187
- def print_vuln_ticket_description(description)
188
- ticket = "#{description[:header]}\n#{description[:assets]}"
189
- ticket << "\n#{description[:references]}\n#{description[:solutions]}"
190
- ticket
191
- end
192
-
193
- # Generates the NXID. The NXID is a unique identifier used to find and update and/or close tickets.
194
- #
195
- # * *Args* :
196
- # - +nexpose_identifier_id+ - Site/TAG ID the tickets are being generated for. Required for all? { |e| } ticketing modes
197
- # - +row+ - Row from the generated Nexpose CSV report. Required for default ('D') mode.
198
- # - +current_ip+ - The IP address of that this ticket is for. Required for IP mode ('I') mode.
199
- #
200
- # * *Returns* :
201
- # - NXID string.
202
- #
203
- def generate_nxid(nexpose_id, row)
204
- fail 'Row data is nil' if row.nil?
205
-
206
- case @ticketing_mode
207
- when 'D' then "#{nexpose_id}d#{row['asset_id']}d#{row['vulnerability_id']}"
208
- when 'I' then "#{nexpose_id}i#{row['ip_address']}"
209
- when 'V' then "#{nexpose_id}v#{row['vulnerability_id']}"
210
- else fail 'Ticketing mode not recognised.'
211
- end
212
- end
213
-
214
- # Formats the row data to be inserted into a 'D' or 'I' mode ticket description.
215
- #
216
- # - +row+ - CSV row containing vulnerability data.
217
- #
218
- # * *Returns* :
219
- # - String formatted with vulnerability data.
220
- #
221
- def get_vuln_info(row)
222
- ticket = get_vuln_header(row)
223
- ticket << get_discovery_info(row)
224
- ticket << get_references(row)
225
- ticket << "\n#{get_solutions(row)}"
226
- ticket.gsub("\n", "\n ")
227
- end
228
-
229
- # Generates the vulnerability header from the row data.
230
- #
231
- # - +row+ - CSV row containing vulnerability data.
232
- #
233
- # * *Returns* :
234
- # - String formatted with vulnerability data.
235
- #
236
- def get_vuln_header(row)
237
- ticket = "\n=============================="
238
- ticket << "\nVulnerability ID: #{row['vulnerability_id']}"
239
- ticket << "\nCVSS Score: #{row['cvss_score']}"
240
- ticket << "\n=============================="
241
- ticket
242
- end
243
-
244
- # Generates the ticket's title depending on the ticketing mode.
245
- #
246
- # - +row+ - CSV row containing vulnerability data.
247
- #
248
- # * *Returns* :
249
- # - String containing the ticket title.
250
- #
251
- def get_title(row, maximum=nil)
252
- title = case @ticketing_mode
253
- when 'D' then "#{row['ip_address']} => #{get_short_summary(row)}"
254
- when 'I' then "#{row['ip_address']} => Vulnerabilities"
255
- when 'V' then "Vulnerability: #{row['title']}"
256
- else fail 'Ticketing mode not recognised.'
257
- end
258
- return title if maximum == nil || title.length < maximum
259
-
260
- title = "#{title[0, 97]}..."
261
- end
262
-
263
- # Generates a short summary for a vulnerability.
264
- #
265
- # - +row+ - CSV row containing vulnerability data.
266
- #
267
- # * *Returns* :
268
- # - String containing a short summary of the vulnerability.
269
- #
270
- def get_short_summary(row)
271
- summary = row['solutions']
272
- delimiter = summary.to_s.index('|')
273
- return summary[summary.index(':')+1...delimiter].strip if delimiter
274
- summary.length <= 100 ? summary : summary[0...100]
275
- end
276
-
277
- # Formats the solutions for a vulnerability in a format suitable to be inserted into a ticket.
278
- #
279
- # - +row+ - CSV row containing vulnerability data.
280
- #
281
- # * *Returns* :
282
- # - String formatted with solution information.
283
- #
284
- def get_solutions(row)
285
- row['solutions'].to_s.gsub('|', "\n").gsub('~', "\n--\n")
286
- end
287
-
288
- def get_discovery_info(row)
289
- return '' if row['first_discovered'].to_s == ""
290
- info = "\nFirst Seen: #{row['first_discovered']}\n"
291
- info << "Last Seen: #{row['most_recently_discovered']}\n"
292
- info
293
- end
294
-
295
- # Formats the references for a vulnerability in a format suitable to be inserted into a ticket.
296
- #
297
- # - +row+ - CSV row containing vulnerability data.
298
- #
299
- # * *Returns* :
300
- # - String formatted with source and reference.
301
- #
302
- def get_references(row)
303
- return '' if row['references'].nil?
304
- references = "\nSources:\n"
305
- refs = row['references'].split(', ')
306
- refs[MAX_NUM_REFS] = '...' if refs.count > MAX_NUM_REFS
307
- refs[0..MAX_NUM_REFS].each { |r| references << " - #{r}\n" }
308
- references
309
- end
310
-
311
-
312
- # Returns the assets for a vulnerability in a format suitable to be inserted into a ticket.
313
- #
314
- # - +row+ - CSV row containing vulnerability data.
315
- #
316
- # * *Returns* :
317
- # - String formatted with affected assets.
318
- #
319
- def get_assets(row)
320
- status = row['comparison']
321
- header = "\n#{status || 'Affected' } Assets\n"
322
-
323
- assets = []
324
- row['assets'].to_s.split('~').each do |a|
325
- details = a.split('|')
326
- assets << " - #{details[1]} #{"\t(#{details[2]})" if !details[2].empty?}"
327
- end
328
- asset_list = assets.join("\n")
329
- "#{header}#{asset_list}"
330
- end
331
-
332
- # Returns the relevant row values for printing.
333
- #
334
- # - +fields+ - The fields which are relevant to the ticket.
335
- # - +row+ - CSV row containing vulnerability data.
336
- #
337
- # * *Returns* :
338
- # - String formatted with relevant fields.
339
- #
340
- def get_field_info(fields, row)
341
- fields.map { |x| "#{x.sub("_", " ")}: #{row[x]}" }.join(", ")
342
- end
343
- end
344
- end