ruby-nessus2 2.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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.drone.yml +51 -0
  3. data/.gitignore +5 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +4 -0
  6. data/.rubocop_todo.yml +124 -0
  7. data/.travis.yml +13 -0
  8. data/.yardopts +1 -0
  9. data/Gemfile +6 -0
  10. data/Gemfile.lock +75 -0
  11. data/LICENSE.txt +20 -0
  12. data/README.md +181 -0
  13. data/Rakefile +21 -0
  14. data/bin/recess +10 -0
  15. data/examples/example.rb +46 -0
  16. data/examples/example_bid.rb +28 -0
  17. data/examples/example_cpe.rb +28 -0
  18. data/examples/example_cve.rb +36 -0
  19. data/examples/example_v1.nessus +1 -0
  20. data/examples/example_v2.nessus +2076 -0
  21. data/examples/example_v3.nessus +7449 -0
  22. data/lib/ruby-nessus.rb +5 -0
  23. data/lib/ruby-nessus/cli.rb +126 -0
  24. data/lib/ruby-nessus/log.rb +84 -0
  25. data/lib/ruby-nessus/parse.rb +46 -0
  26. data/lib/ruby-nessus/ruby-nessus.rb +6 -0
  27. data/lib/ruby-nessus/version.rb +5 -0
  28. data/lib/ruby-nessus/version1/event.rb +85 -0
  29. data/lib/ruby-nessus/version1/host.rb +267 -0
  30. data/lib/ruby-nessus/version1/port.rb +84 -0
  31. data/lib/ruby-nessus/version1/scan.rb +404 -0
  32. data/lib/ruby-nessus/version2/event.rb +410 -0
  33. data/lib/ruby-nessus/version2/host.rb +522 -0
  34. data/lib/ruby-nessus/version2/port.rb +75 -0
  35. data/lib/ruby-nessus/version2/scan.rb +393 -0
  36. data/ruby-nessus.gemspec +28 -0
  37. data/spec/ruby-nessus/parse_spec.rb +40 -0
  38. data/spec/ruby-nessus/version1/event_spec.rb +69 -0
  39. data/spec/ruby-nessus/version1/host_spec.rb +75 -0
  40. data/spec/ruby-nessus/version1/scan_spec.rb +97 -0
  41. data/spec/ruby-nessus/version2/event_spec.rb +225 -0
  42. data/spec/ruby-nessus/version2/host_spec.rb +148 -0
  43. data/spec/ruby-nessus/version2/scan_spec.rb +96 -0
  44. data/spec/ruby-nessus/version_spec.rb +11 -0
  45. data/spec/spec_fixtures/example_v1.nessus +1 -0
  46. data/spec/spec_fixtures/example_v2.nessus +2080 -0
  47. data/spec/spec_fixtures/example_v_wrong.nessus +3 -0
  48. data/spec/spec_fixtures/xml.rb +15 -0
  49. data/spec/spec_helper.rb +7 -0
  50. metadata +190 -0
@@ -0,0 +1,410 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby-nessus/version2/port'
4
+
5
+ module RubyNessus
6
+ module Version2
7
+ class Event
8
+ def initialize(event)
9
+ @event = event
10
+ end
11
+
12
+ #
13
+ # Return the event port.
14
+ #
15
+ # @return [Object]
16
+ # Return the event port object or port string.
17
+ #
18
+ # @example
19
+ # event.port #=> "https (443/tcp)"
20
+ # event.port.number #=> 443
21
+ # event.port.service #=> "https"
22
+ # event.port.protocol #=> "tcp"
23
+ #
24
+ def port
25
+ @port ||= Port.new(@event.at('@port'), @event.at('@svc_name'), @event.at('@protocol'))
26
+ end
27
+
28
+ #
29
+ # Return the event severity.
30
+ #
31
+ # @return [Integer]
32
+ # Return the event severity.
33
+ #
34
+ # @example
35
+ # event.severity #=> 3
36
+ #
37
+ def severity
38
+ @severity ||= @event.at('@severity').inner_text.to_i
39
+ end
40
+
41
+ #
42
+ # Return true if event is of informational severity.
43
+ #
44
+ # @return [Boolean]
45
+ # Return true if the event is informational.
46
+ #
47
+ def informational?
48
+ severity == 0
49
+ end
50
+
51
+ #
52
+ # Return true if the event is of low severity.
53
+ #
54
+ # @return [Boolean]
55
+ # Return true if the event is low severity.
56
+ #
57
+ def low?
58
+ severity == 1
59
+ end
60
+
61
+ #
62
+ # Return true if the event is of medium severity.
63
+ #
64
+ # @return [Boolean]
65
+ # Return true if the event is medium severity.
66
+ #
67
+ def medium?
68
+ severity == 2
69
+ end
70
+
71
+ #
72
+ # Return true if the event is of high severity.
73
+ #
74
+ # @return [Boolean]
75
+ # Return true if the event is high severity.
76
+ #
77
+ def high?
78
+ severity == 3
79
+ end
80
+
81
+ #
82
+ # Return true if the event is of critical severity.
83
+ #
84
+ # @return [Boolean]
85
+ # Return true if the event is critical severity.
86
+ #
87
+ def critical?
88
+ severity == 4
89
+ end
90
+
91
+ #
92
+ # Return the event object nessus plugin id
93
+ #
94
+ # @return [Integer]
95
+ # Return the event object nessus plugin id
96
+ #
97
+ # @example
98
+ # event.plugin_id #=> 3245
99
+ #
100
+ def id
101
+ @plugin_id ||= @event.at('@pluginID').inner_text.to_i
102
+ end
103
+ alias plugin_id id
104
+
105
+ #
106
+ # Return the event object plugin family name.
107
+ #
108
+ # @return [String]
109
+ # Return the event object plugin family name.
110
+ #
111
+ # @example
112
+ # event.family #=> "Service detection"
113
+ #
114
+ def family
115
+ @plugin_family ||= @event.at('@pluginFamily').inner_text
116
+ end
117
+ alias plugin_family family
118
+
119
+ #
120
+ # Return the event name (plugin_name)
121
+ #
122
+ # @return [String, nil]
123
+ # Return the event name (plugin_name)
124
+ #
125
+ # @example
126
+ # event.plugin_name #=> "PHP < 5.2.4 Multiple Vulnerabilities"
127
+ # event.name #=> "PHP < 5.2.4 Multiple Vulnerabilities"
128
+ #
129
+ def plugin_name
130
+ @plugin_name ||= @event.at('@pluginName')&.inner_text unless @event.at('@pluginName').inner_text.empty?
131
+ end
132
+ alias name plugin_name
133
+
134
+ #
135
+ # Return the event object plugin type (plugin_type)
136
+ #
137
+ # @return [String, nil]
138
+ # Return the event object plugin type (plugin_type)
139
+ #
140
+ # @example
141
+ # event.plugin_type #=> "remote"
142
+ #
143
+ def plugin_type
144
+ @plugin_type ||= @event.at('plugin_type')&.inner_text
145
+ end
146
+
147
+ #
148
+ # Return the event synopsis.
149
+ #
150
+ # @return [String, nil]
151
+ # Return the event synopsis.
152
+ #
153
+ def synopsis
154
+ @synopsis ||= @event.at('synopsis')&.inner_text
155
+ end
156
+
157
+ #
158
+ # Return the event description.
159
+ #
160
+ # @return [String, nil]
161
+ # Return the event description.
162
+ #
163
+ def description
164
+ @description ||= @event.at('description')&.inner_text
165
+ end
166
+
167
+ #
168
+ # Return the event solution.
169
+ #
170
+ # @return [String, nil]
171
+ # Return the event solution.
172
+ #
173
+ def solution
174
+ @solution ||= @event.at('solution')&.inner_text
175
+ end
176
+
177
+ #
178
+ # Return the event risk.
179
+ #
180
+ # @return [String, nil]
181
+ # Return the event risk.
182
+ #
183
+ def risk
184
+ @risk_factor ||= @event.at('risk_factor')&.inner_text
185
+ end
186
+
187
+ #
188
+ # Return the event plugin output.
189
+ #
190
+ # @return [String, nil]
191
+ # Return the event plugin output.
192
+ #
193
+ def output
194
+ @plugin_output ||= @event.at('plugin_output')&.inner_text
195
+ end
196
+ alias data output
197
+ alias plugin_output output
198
+
199
+ #
200
+ # Return the event plugin version.
201
+ #
202
+ # @return [String, nil]
203
+ # Return the event plugin version.
204
+ #
205
+ def version
206
+ @plugin_version ||= @event.at('plugin_version')&.inner_text
207
+ end
208
+ alias plugin_version version
209
+
210
+ #
211
+ # Return the event reference links.
212
+ #
213
+ # @return [Array<String>]
214
+ # Return the event reference links.
215
+ #
216
+ def see_also
217
+ @see_also ||= @event.at('see_also')&.inner_text&.split("\n")
218
+ end
219
+ alias links see_also
220
+ alias more see_also
221
+ alias references see_also
222
+
223
+ #
224
+ # Return the event vulnerability publication date.
225
+ #
226
+ # @return [Time, nil]
227
+ # Return the event vulnerability publication date.
228
+ #
229
+ def vuln_publication_date
230
+ @vuln_publication_date ||= Time.parse(@event.at('vuln_publication_date').inner_text + ' UTC') if @event.at('vuln_publication_date')
231
+ end
232
+
233
+ #
234
+ # Return the event patch publication date.
235
+ #
236
+ # @return [Time, nil]
237
+ # Return the event patch publication date.
238
+ #
239
+ def patch_publication_date
240
+ @patch_publication_date ||= Time.parse(@event.at('patch_publication_date').inner_text + ' UTC') if @event.at('patch_publication_date')
241
+ end
242
+
243
+ #
244
+ # Return the event cvss base score.
245
+ #
246
+ # @return [float, nil]
247
+ # Return the event cvss base score.
248
+ #
249
+ def cvss_base_score
250
+ @cvss_base_score ||= @event.at('cvss_base_score')&.inner_text.to_f
251
+ end
252
+
253
+ #
254
+ # Return the event cvss temporal score.
255
+ #
256
+ # @return [float, nil]
257
+ # Return the event cvss temporal score.
258
+ #
259
+ def cvss_temporal_score
260
+ @cvss_temporal_score ||= @event.at('cvss_temporal_score')&.inner_text.to_f
261
+ end
262
+
263
+ #
264
+ # Return the event cve.
265
+ #
266
+ # @return [Array<String>, nil]
267
+ # Return the event cvss base score.
268
+ #
269
+ def cve
270
+ unless @cve
271
+ @cve = []
272
+ @event.xpath('cve').each do |cve|
273
+ @cve << cve.inner_text
274
+ end
275
+ @cve = nil if @cve.empty?
276
+ end
277
+ @cve
278
+ end
279
+
280
+ #
281
+ # Return the event bid.
282
+ #
283
+ # @return [Array<String>, nil]
284
+ # Return the event bid.
285
+ #
286
+ def bid
287
+ unless @bid
288
+ @bid = []
289
+ @event.xpath('bid').each do |bid|
290
+ @bid << bid.inner_text
291
+ end
292
+ @bid = nil if @bid.empty?
293
+ end
294
+ @bid
295
+ end
296
+
297
+ #
298
+ # Return other event related references.
299
+ #
300
+ # @return [Array<String>]
301
+ # Return the event related references.
302
+ #
303
+ def xref
304
+ unless @xref
305
+ @xref = []
306
+ @event.xpath('xref').each do |xref|
307
+ @xref << xref.inner_text
308
+ end
309
+ end
310
+ @xref
311
+ end
312
+
313
+ #
314
+ # Return other event cvss vector.
315
+ #
316
+ # @return [String, nil]
317
+ # Return the event cvss vector.
318
+ #
319
+ def cvss_vector
320
+ @cvss_vector ||= @event.at('cvss_vector')&.inner_text
321
+ end
322
+
323
+ #
324
+ # Return the event cpe.
325
+ #
326
+ # @return [Array<String>]
327
+ # Return the event cpe.
328
+ #
329
+ def cpe
330
+ unless @cpe
331
+ @cpe = []
332
+ @event.xpath('cpe').each do |cpe|
333
+ @cpe << cpe.inner_text
334
+ end
335
+ end
336
+ @cpe
337
+ end
338
+
339
+ #
340
+ # Return event exploitability ease.
341
+ #
342
+ # @return [String, nil]
343
+ # Return the event exploitability ease.
344
+ #
345
+ def exploitability_ease
346
+ @exploitability_ease ||= @event.at('exploitability_ease')&.inner_text
347
+ end
348
+
349
+ #
350
+ # Return event exploit available.
351
+ #
352
+ # @return [Boolean]
353
+ # Return the event exploit available.
354
+ #
355
+ def exploit_available
356
+ @exploit_available ||= @event.at('exploit_available')&.inner_text == "true"
357
+ end
358
+
359
+ #
360
+ # Return if an exploit exists in the Immunity CANVAS framework.
361
+ #
362
+ # @return [Boolean]
363
+ # Return the event exploit framework canvas.
364
+ #
365
+ def exploit_framework_canvas
366
+ @exploit_framework_canvas ||= @event.at('exploit_framework_canvas')&.inner_text == "true"
367
+ end
368
+
369
+ #
370
+ # Return the name of the CANVAS exploit package
371
+ #
372
+ # @return [String, nil]
373
+ # Return the canvas_package.
374
+ #
375
+ def canvas_package
376
+ @canvas_package ||= @event.at('canvas_package')&.inner_text
377
+ end
378
+
379
+ #
380
+ # Return if an exploit exploit exists in the Metasploit framework
381
+ #
382
+ # @return [Boolean]
383
+ # Return the event exploit framework metasploit.
384
+ #
385
+ def exploit_framework_metasploit
386
+ @exploit_framework_metasploit ||= @event.at('exploit_framework_metasploit')&.inner_text == "true"
387
+ end
388
+
389
+ #
390
+ # Return name of the Metasploit exploit module.
391
+ #
392
+ # @return [String, nil]
393
+ # Return the metasploit_name.
394
+ #
395
+ def metasploit_name
396
+ @metasploit_name ||= @event.at('metasploit_name')&.inner_text
397
+ end
398
+
399
+ #
400
+ # Return if an exploit exploit exists in the CORE Impact framework
401
+ #
402
+ # @return [Boolean]
403
+ # Return the event exploit framework core.
404
+ #
405
+ def exploit_framework_core
406
+ @exploit_framework_core ||= @event.at('exploit_framework_core')&.inner_text == "true"
407
+ end
408
+ end
409
+ end
410
+ end
@@ -0,0 +1,522 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyNessus
4
+ module Version2
5
+ class Host
6
+ include Enumerable
7
+
8
+ #
9
+ # Creates A New Host Object
10
+ #
11
+ # @param [Object] Host Object
12
+ #
13
+ # @example
14
+ # Host.new(object)
15
+ #
16
+ def initialize(host)
17
+ @host = host
18
+ end
19
+
20
+ def to_s
21
+ ip.to_s
22
+ end
23
+
24
+ def name
25
+ @host["name"]
26
+ end
27
+
28
+ #
29
+ # Return the Host Object hostname.
30
+ #
31
+ # @return [String]
32
+ # The Host Object Hostname
33
+ #
34
+ # @example
35
+ # host.hostname #=> "example.com"
36
+ #
37
+ def hostname
38
+ @host.at('tag[name=host-fqdn]')&.inner_text
39
+ end
40
+ alias fqdn hostname
41
+ alias dns_name hostname
42
+
43
+ #
44
+ # Return the Host Object IP.
45
+ #
46
+ # @return [String]
47
+ # The Host Object IP
48
+ #
49
+ # @example
50
+ # host.ip #=> "127.0.0.1"
51
+ #
52
+ def ip
53
+ @host.at('tag[name=host-ip]')&.inner_text
54
+ end
55
+
56
+ #
57
+ # Return the host scan start time.
58
+ #
59
+ # @return [Time]
60
+ # The Host Scan Start Time
61
+ #
62
+ # @example
63
+ # scan.scan_start_time #=> 'Fri Nov 11 23:36:54 1985'
64
+ #
65
+ def start_time
66
+ if (start_time = @host.at('tag[name=HOST_START]'))
67
+ Time.parse(start_time.inner_text + ' UTC')
68
+ end
69
+ end
70
+
71
+ #
72
+ # Return the host scan stop time.
73
+ #
74
+ # @return [Time]
75
+ # The Host Scan Stop Time
76
+ #
77
+ # @example
78
+ # scan.scan_start_time #=> 'Fri Nov 11 23:36:54 1985'
79
+ #
80
+ def stop_time
81
+ if (stop_time = @host.at('tag[name=HOST_END]'))
82
+ Time.parse(stop_time.inner_text + ' UTC')
83
+ end
84
+ end
85
+
86
+ #
87
+ # Return the host run time.
88
+ #
89
+ # @return [String]
90
+ # The Host Scan Run Time
91
+ #
92
+ # @example
93
+ # scan.scan_run_time #=> '2 hours 5 minutes and 16 seconds'
94
+ #
95
+ def runtime
96
+ return unless stop_time && start_time
97
+ Time.at(stop_time - start_time).utc.strftime('%H hours %M minutes and %S seconds')
98
+ end
99
+ alias scan_runtime runtime
100
+ alias get_runtime runtime
101
+
102
+ #
103
+ # Return the Host Netbios Name.
104
+ #
105
+ # @return [String, nil]
106
+ # The Host Netbios Name
107
+ #
108
+ # @example
109
+ # host.netbios_name #=> "SOMENAME4243"
110
+ #
111
+ def netbios_name
112
+ @host.at('tag[name=netbios-name]')&.inner_text
113
+ end
114
+
115
+ #
116
+ # Return the Host Mac Address.
117
+ #
118
+ # @return [String]
119
+ # Return the Host Mac Address
120
+ #
121
+ # @example
122
+ # host.mac_addr #=> "00:11:22:33:44:55"
123
+ #
124
+ def mac_addr
125
+ @host.at('tag[name=mac-address]')&.inner_text
126
+ end
127
+ alias mac_address mac_addr
128
+
129
+ #
130
+ # Return the Host OS Name.
131
+ #
132
+ # @return [String]
133
+ # Return the Host OS Name
134
+ #
135
+ # @example
136
+ # host.dns_name #=> "Microsoft Windows 2000, Microsoft Windows Server 2003"
137
+ #
138
+ def os_name
139
+ @host.at('tag[name=operating-system]')&.inner_text
140
+ end
141
+ alias os os_name
142
+ alias operating_system os_name
143
+
144
+ #
145
+ # Return the open ports for a given host object.
146
+ #
147
+ # @return [Integer]
148
+ # Return the open ports for a given host object.
149
+ #
150
+ # @example
151
+ # host.open_ports #=> 213
152
+ #
153
+ def open_ports
154
+ @scanned_ports ||= host_stats[:open_ports].to_i
155
+ end
156
+
157
+ #
158
+ # Returns All Informational Event Objects For A Given Host.
159
+ #
160
+ #
161
+ # @return [Event]
162
+ # Return The Informational Event For A Given Host.
163
+ #
164
+ # @example
165
+ # host.informational_severity_events.each do |info|
166
+ # puts info.port
167
+ # puts info.data if info.data
168
+ # end
169
+ #
170
+ def informational_severity_events
171
+ return if @informational_events
172
+ @informational_events = @host.xpath('ReportItem').select { |event| event['severity'].to_i.zero? }.map do |event|
173
+ Event.new(event)
174
+ end
175
+ @informational_events
176
+ end
177
+
178
+ #
179
+ # Returns All low_severity Event Objects For A Given Host.
180
+ #
181
+ #
182
+ # @return [Event]
183
+ # Return The low_severity Event For A Given Host.
184
+ #
185
+ # @example
186
+ # host.low_severity_events.each do |low|
187
+ # puts low.port
188
+ # puts low.data if low.data
189
+ # end
190
+ #
191
+ def low_severity_events
192
+ return if @low_severity_events
193
+ @low_severity_events = @host.xpath('ReportItem').select { |event| (event['severity'].to_i == 1) }.map do |event|
194
+ Event.new(event)
195
+ end
196
+ @low_severity_events
197
+ end
198
+
199
+ #
200
+ # Returns All medium severity Event Objects For A Given Host.
201
+ #
202
+ #
203
+ # @return [Event]
204
+ # Return The medium severity Event For A Given Host.
205
+ #
206
+ # @example
207
+ # host.medium_severity_events.each do |medium|
208
+ # puts medium.port
209
+ # puts medium.data if medium.data
210
+ # end
211
+ #
212
+ def medium_severity_events
213
+ return if @medium_severity_events
214
+ @medium_severity_events = @host.xpath('ReportItem').select { |event| (event['severity'].to_i == 2) }.map do |event|
215
+ Event.new(event)
216
+ end
217
+ @medium_severity_events
218
+ end
219
+
220
+ #
221
+ # Returns All high severity Event Objects For A Given Host.
222
+ #
223
+ #
224
+ # @return [Event]
225
+ # Return The high severity Event For A Given Host.
226
+ #
227
+ # @example
228
+ # host.high_severity_events.each do |high|
229
+ # puts high.port
230
+ # puts high.data if high.data
231
+ # end
232
+ #
233
+ def high_severity_events
234
+ return if @high_severity_events
235
+ @high_severity_events = @host.xpath('ReportItem').select { |event| (event['severity'].to_i == 3) }.map do |event|
236
+ Event.new(event)
237
+ end
238
+ @high_severity_events
239
+ end
240
+
241
+ #
242
+ # Returns All critical severity Event Objects For A Given Host.
243
+ #
244
+ #
245
+ # @return [Event]
246
+ # Return The critical For A Given Host.
247
+ #
248
+ # @example
249
+ # host.critical_severity_events.each do |critical|
250
+ # puts critical.port
251
+ # puts critical.data if info.data
252
+ # end
253
+ #
254
+ def critical_severity_events
255
+ return if @critical_events
256
+ @critical_events = @host.xpath('ReportItem').select { |event| (event['severity'].to_i == 4) }.map do |event|
257
+ Event.new(event)
258
+ end
259
+ @critical_events
260
+ end
261
+
262
+ #
263
+ # Return the total event count for a given host.
264
+ #
265
+ # @return [Integer]
266
+ # Return the total event count for a given host.
267
+ #
268
+ # @example
269
+ # host.event_count #=> 3456
270
+ #
271
+ def event_count
272
+ low_severity_events.count + medium_severity_events.count + high_severity_events.count + critical_severity_events.count
273
+ end
274
+
275
+ #
276
+ # Creates a new Event object to be parser
277
+ #
278
+ # @yield [prog] If a block is given, it will be passed the newly
279
+ # created Event object.
280
+ # @yieldparam [EVENT] prog The newly created Event object.
281
+ #
282
+ # @example
283
+ # host.each_event do |event|
284
+ # puts event.name if event.name
285
+ # puts event.port
286
+ # end
287
+ #
288
+ def each_event(&block)
289
+ events.each(&block)
290
+ end
291
+
292
+ #
293
+ # Parses the events of the host.
294
+ #
295
+ # @return [Array<String>]
296
+ # The events of the host.
297
+ #
298
+ def events
299
+ @host.xpath('ReportItem').map do |event|
300
+ Event.new(event)
301
+ end
302
+ end
303
+
304
+ #
305
+ # Return an Array of open ports.
306
+ #
307
+ # @return [Array]
308
+ # The open ports
309
+ #
310
+ # @example
311
+ # scan.ports #=> ['22', '80', '443']
312
+ #
313
+ def ports
314
+ return if @ports
315
+ @ports = @host.xpath('ReportItem').map { |port| port['port'] }.uniq.sort
316
+ end
317
+
318
+ #
319
+ # Return the TCP Event Count.
320
+ #
321
+ # @return [Integer]
322
+ # The TCP Event Count
323
+ #
324
+ # @example
325
+ # scan.tcp_count #=> 3
326
+ #
327
+ def tcp_count
328
+ host_stats[:tcp].to_i
329
+ end
330
+
331
+ #
332
+ # Return the UDP Event Count.
333
+ #
334
+ # @return [Integer]
335
+ # The UDP Event Count
336
+ #
337
+ # @example
338
+ # scan.udp_count #=> 3
339
+ #
340
+ def udp_count
341
+ host_stats[:udp].to_i
342
+ end
343
+
344
+ #
345
+ # Return the ICMP Event Count.
346
+ #
347
+ # @return [Integer]
348
+ # The ICMP Event Count
349
+ #
350
+ # @example
351
+ # scan.icmp_count #=> 3
352
+ #
353
+ def icmp_count
354
+ host_stats[:icmp].to_i
355
+ end
356
+
357
+ #
358
+ # Return the informational severity count.
359
+ #
360
+ # @return [Integer]
361
+ # The Informational Severity Count
362
+ #
363
+ # @example
364
+ # scan.informational_severity_count #=> 1203
365
+ #
366
+ def informational_severity_count
367
+ host_stats[:informational].to_i
368
+ end
369
+
370
+ #
371
+ # Return the Critical severity count.
372
+ #
373
+ # @return [Integer]
374
+ # The Critical Severity Count
375
+ #
376
+ # @example
377
+ # scan.critical_severity_count #=> 10
378
+ #
379
+ def critical_severity_count
380
+ host_stats[:critical].to_i
381
+ end
382
+
383
+ #
384
+ # Return the High severity count.
385
+ #
386
+ # @return [Integer]
387
+ # The High Severity Count
388
+ #
389
+ # @example
390
+ # scan.high_severity_count #=> 10
391
+ #
392
+ def high_severity_count
393
+ host_stats[:high].to_i
394
+ end
395
+
396
+ #
397
+ # Return the Medium severity count.
398
+ #
399
+ # @return [Integer]
400
+ # The Medium Severity Count
401
+ #
402
+ # @example
403
+ # scan.medium_severity_count #=> 234
404
+ #
405
+ def medium_severity_count
406
+ host_stats[:medium].to_i
407
+ end
408
+
409
+ #
410
+ # Return the Low severity count.
411
+ #
412
+ # @return [Integer]
413
+ # The Low Severity Count
414
+ #
415
+ # @example
416
+ # scan.low_severity_count #=> 114
417
+ #
418
+ def low_severity_count
419
+ host_stats[:low].to_i
420
+ end
421
+
422
+ #
423
+ # Return the Total severity count. [high, medium, low, informational]
424
+ #
425
+ # @return [Integer]
426
+ # The Total Severity Count
427
+ #
428
+ # @example
429
+ # scan.total_event_count #=> 1561
430
+ #
431
+ def total_event_count(count_informational = nil)
432
+ if count_informational
433
+ host_stats[:all].to_i + informational_severity_count
434
+ else
435
+ host_stats[:all].to_i
436
+ end
437
+ end
438
+
439
+ #
440
+ # Return the Total severity count.
441
+ #
442
+ # @param [String] severity the severity in which to calculate percentage for.
443
+ #
444
+ # @param [true, false] round round the result to the nearest whole number.
445
+ #
446
+ # @raise [ExceptionClass] One of the following severity options must be passed. [high, medium, low, informational, all]
447
+ #
448
+ # @return [Integer]
449
+ # The Percentage Of Events For A Passed Severity
450
+ #
451
+ # @example
452
+ # scan.event_percentage_for("low", true) #=> 11%
453
+ #
454
+ def event_percentage_for(type, round_percentage = false)
455
+ @sc ||= host_stats
456
+ if %w[high medium low tcp udp icmp all].include?(type)
457
+ calc = ((@sc[:"#{type}"].to_f / @sc[:all].to_f) * 100)
458
+ if round_percentage
459
+ return calc.round.to_s
460
+ else
461
+ return calc.to_s
462
+ end
463
+ else
464
+ raise "Error: #{type} is not an acceptable severity. Possible options include: all, tdp, udp, icmp, high, medium and low."
465
+ end
466
+ end
467
+
468
+ private
469
+
470
+ def host_stats
471
+ unless @host_stats
472
+ @host_stats = {}
473
+ @open_ports = 0
474
+ @tcp = 0
475
+ @udp = 0
476
+ @icmp = 0
477
+ @informational = 0
478
+ @low = 0
479
+ @medium = 0
480
+ @high = 0
481
+ @critical = 0
482
+
483
+ @host.xpath('ReportItem').each do |s|
484
+ case s['severity'].to_i
485
+ when 0
486
+ @informational += 1
487
+ when 1
488
+ @low += 1
489
+ when 2
490
+ @medium += 1
491
+ when 3
492
+ @high += 1
493
+ when 4
494
+ @critical += 1
495
+ end
496
+
497
+ unless s['severity'].to_i == 0
498
+ @tcp += 1 if s['protocol'] == 'tcp'
499
+ @udp += 1 if s['protocol'] == 'udp'
500
+ @icmp += 1 if s['protocol'] == 'icmp'
501
+ end
502
+
503
+ @open_ports += 1 if s['port'].to_i != 0
504
+ end
505
+
506
+ @host_stats = { open_ports: @open_ports,
507
+ tcp: @tcp,
508
+ udp: @udp,
509
+ icmp: @icmp,
510
+ informational: @informational,
511
+ low: @low,
512
+ medium: @medium,
513
+ high: @high,
514
+ critical: @critical,
515
+ all: (@low + @medium + @high + @critical) }
516
+
517
+ end
518
+ @host_stats
519
+ end
520
+ end
521
+ end
522
+ end