yawast 0.7.0.beta1 → 0.7.0.beta2

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 +4 -4
  2. data/.rubocop.yml +12 -0
  3. data/CHANGELOG.md +5 -1
  4. data/Gemfile +2 -2
  5. data/README.md +8 -1
  6. data/Rakefile +1 -1
  7. data/bin/yawast +8 -0
  8. data/lib/commands/cms.rb +2 -0
  9. data/lib/commands/dns.rb +3 -3
  10. data/lib/commands/head.rb +2 -0
  11. data/lib/commands/scan.rb +2 -0
  12. data/lib/commands/ssl.rb +2 -0
  13. data/lib/commands/utils.rb +5 -3
  14. data/lib/scanner/core.rb +34 -26
  15. data/lib/scanner/generic.rb +33 -130
  16. data/lib/scanner/plugins/applications/cms/generic.rb +20 -0
  17. data/lib/scanner/plugins/applications/generic/password_reset.rb +180 -0
  18. data/lib/scanner/plugins/dns/caa.rb +30 -12
  19. data/lib/scanner/plugins/dns/generic.rb +38 -1
  20. data/lib/scanner/plugins/http/directory_search.rb +14 -12
  21. data/lib/scanner/plugins/http/file_presence.rb +21 -13
  22. data/lib/scanner/plugins/http/generic.rb +95 -0
  23. data/lib/scanner/plugins/servers/apache.rb +23 -23
  24. data/lib/scanner/plugins/servers/generic.rb +25 -0
  25. data/lib/scanner/plugins/servers/iis.rb +6 -6
  26. data/lib/scanner/plugins/servers/nginx.rb +3 -1
  27. data/lib/scanner/plugins/servers/python.rb +3 -1
  28. data/lib/scanner/plugins/spider/spider.rb +7 -7
  29. data/lib/scanner/plugins/ssl/ssl.rb +14 -14
  30. data/lib/scanner/plugins/ssl/ssl_labs/analyze.rb +14 -13
  31. data/lib/scanner/plugins/ssl/ssl_labs/info.rb +6 -4
  32. data/lib/scanner/plugins/ssl/sweet32.rb +68 -63
  33. data/lib/scanner/ssl.rb +33 -36
  34. data/lib/scanner/ssl_labs.rb +373 -110
  35. data/lib/scanner/vuln_scan.rb +27 -0
  36. data/lib/shared/http.rb +31 -27
  37. data/lib/shared/output.rb +7 -15
  38. data/lib/shared/uri.rb +14 -14
  39. data/lib/string_ext.rb +10 -4
  40. data/lib/uri_ext.rb +1 -1
  41. data/lib/util.rb +28 -0
  42. data/lib/version.rb +3 -1
  43. data/lib/yawast.rb +12 -2
  44. data/test/data/ssl_labs_analyze_data_cam_hmhreservations_com.json +1933 -0
  45. data/test/test_scan_cms.rb +2 -2
  46. data/test/test_ssl_labs_analyze.rb +15 -0
  47. data/yawast.gemspec +8 -5
  48. metadata +75 -28
  49. data/lib/scanner/cms.rb +0 -14
  50. data/lib/scanner/php.rb +0 -19
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
  require 'openssl'
3
5
  require 'digest/sha1'
@@ -10,7 +12,7 @@ module Yawast
10
12
  puts 'Beginning SSL Labs scan (this could take a minute or two)'
11
13
 
12
14
  begin
13
- endpoint = URI::Parser.new.parse 'https://api.ssllabs.com'
15
+ endpoint = URI::DEFAULT_PARSER.parse 'https://api.ssllabs.com'
14
16
 
15
17
  info_body = Yawast::Scanner::Plugins::SSL::SSLLabs::Info.call_info endpoint
16
18
 
@@ -39,12 +41,12 @@ module Yawast
39
41
  json = nil
40
42
  begin
41
43
  json = JSON.parse data_body
42
- rescue => e
44
+ rescue => e # rubocop:disable Style/RescueStandardError
43
45
  raise Exception, "Invalid response from SSL Labs: '#{e.message}'"
44
46
  end
45
47
 
46
48
  process_results uri, json, tdes_session_count
47
- rescue => e
49
+ rescue => e # rubocop:disable Style/RescueStandardError
48
50
  puts
49
51
  Yawast::Utilities.puts_error "SSL Labs Error: #{e.message}"
50
52
  end
@@ -65,7 +67,7 @@ module Yawast
65
67
  else
66
68
  Yawast::Utilities.puts_error "Error getting information for IP: #{ep['ipAddress']}: #{ep['statusMessage']}"
67
69
  end
68
- rescue => e
70
+ rescue => e # rubocop:disable Style/RescueStandardError
69
71
  Yawast::Utilities.puts_error "Error getting information for IP: #{ep['ipAddress']}: #{e.message}"
70
72
  end
71
73
 
@@ -76,13 +78,13 @@ module Yawast
76
78
  else
77
79
  Yawast::Utilities.puts_error 'SSL Labs Error: No Endpoint Data Received.'
78
80
 
79
- #TODO - Remove this before release
81
+ # TODO: Remove this before release
80
82
  puts
81
83
  puts "DEBUG DATA (send to adam@adamcaudill.com): #{body}"
82
84
  puts
83
85
  puts
84
86
  end
85
- rescue => e
87
+ rescue => e # rubocop:disable Style/RescueStandardError
86
88
  puts
87
89
  Yawast::Utilities.puts_error "SSL Labs Error: #{e.message}"
88
90
  end
@@ -100,44 +102,26 @@ module Yawast
100
102
  end
101
103
 
102
104
  puts "\tCertificate Information:"
103
- unless cert['issues'] == 0
105
+ unless cert['issues'].zero?
104
106
  Yawast::Utilities.puts_vuln "\t\tCertificate Has Issues - Not Valid"
105
107
 
106
- if cert['issues'] & 1 != 0
107
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: no chain of trust"
108
- end
108
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: no chain of trust" if cert['issues'] & 1 != 0
109
109
 
110
- if cert['issues'] & (1<<1) != 0
111
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: certificate not yet valid"
112
- end
110
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: certificate not yet valid" if cert['issues'] & (1 << 1) != 0
113
111
 
114
- if cert['issues'] & (1<<2) != 0
115
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: certificate expired"
116
- end
112
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: certificate expired" if cert['issues'] & (1 << 2) != 0
117
113
 
118
- if cert['issues'] & (1<<3) != 0
119
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: hostname mismatch"
120
- end
114
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: hostname mismatch" if cert['issues'] & (1 << 3) != 0
121
115
 
122
- if cert['issues'] & (1<<4) != 0
123
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: revoked"
124
- end
116
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: revoked" if cert['issues'] & (1 << 4) != 0
125
117
 
126
- if cert['issues'] & (1<<5) != 0
127
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: bad common name"
128
- end
118
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: bad common name" if cert['issues'] & (1 << 5) != 0
129
119
 
130
- if cert['issues'] & (1<<6) != 0
131
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: self-signed"
132
- end
120
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: self-signed" if cert['issues'] & (1 << 6) != 0
133
121
 
134
- if cert['issues'] & (1<<7) != 0
135
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: blacklisted"
136
- end
122
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: blacklisted" if cert['issues'] & (1 << 7) != 0
137
123
 
138
- if cert['issues'] & (1<<8) != 0
139
- Yawast::Utilities.puts_vuln "\t\tCertificate Issue: insecure signature"
140
- end
124
+ Yawast::Utilities.puts_vuln "\t\tCertificate Issue: insecure signature" if cert['issues'] & (1 << 8) != 0
141
125
  end
142
126
 
143
127
  Yawast::Utilities.puts_info "\t\tSubject: #{cert['subject']}"
@@ -166,17 +150,56 @@ module Yawast
166
150
 
167
151
  Yawast::Utilities.puts_info "\t\tVersion: #{ossl_cert.version}"
168
152
 
169
- Yawast::Utilities.puts_info "\t\tSerial: #{ossl_cert.serial}"
153
+ serial = format('%02x', ossl_cert.serial.to_i)
154
+ serial = "0#{serial}" unless serial.length.even?
155
+ Yawast::Utilities.puts_info "\t\tSerial: #{serial}"
156
+
157
+ ## if the serial is exactly 16 hex digits, it may have an entropy issue.
158
+ if serial.length == 16
159
+ puts
160
+
161
+ Yawast::Utilities.puts_warn "\t\tSerial number is exactly 64 bits. Serial may not comply with CA/B Forum requirements."
162
+ Yawast::Utilities.puts_raw "\t\t\t See https://adamcaudill.com/2019/03/09/tls-64bit-ish-serial-numbers-mass-revocation/ for details."
163
+
164
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
165
+ 'tls_serial_exactly_64_bits',
166
+ {vulnerable: true, length: (serial.length / 2) * 8}
167
+
168
+ puts
169
+ elsif serial.length < 16
170
+ puts
171
+
172
+ Yawast::Utilities.puts_vuln "\t\tSerial number is less than 64 bits. Serial does not comply with CA/B Forum requirements."
173
+
174
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
175
+ 'tls_serial_less_than_64_bits',
176
+ {vulnerable: true, length: (serial.length / 2) * 8}
177
+
178
+ puts
179
+ else
180
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
181
+ 'tls_serial_exactly_64_bits',
182
+ {vulnerable: false, length: (serial.length / 2) * 8}
183
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
184
+ 'tls_serial_less_than_64_bits',
185
+ {vulnerable: false, length: (serial.length / 2) * 8}
186
+ end
170
187
 
171
188
  Yawast::Utilities.puts_info "\t\tIssuer: #{cert['issuerSubject']}"
172
189
 
173
190
  if cert['sigAlg'].include?('SHA1') || cert['sigAlg'].include?('MD5')
174
191
  Yawast::Utilities.puts_vuln "\t\tSignature algorithm: #{cert['sigAlg']}"
192
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
193
+ 'tls_weak_sig_alg',
194
+ {vulnerable: true, algorithm: cert['sigAlg']}
175
195
  else
176
196
  Yawast::Utilities.puts_info "\t\tSignature algorithm: #{cert['sigAlg']}"
197
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
198
+ 'tls_weak_sig_alg',
199
+ {vulnerable: false, algorithm: cert['sigAlg']}
177
200
  end
178
201
 
179
- #todo - figure out what the options for this value are
202
+ # TODO: figure out what the options for this value are
180
203
  if cert['validationType'] == 'E'
181
204
  Yawast::Utilities.puts_info "\t\tExtended Validation: Yes"
182
205
  elsif cert['validationType'] == 'D'
@@ -192,12 +215,12 @@ module Yawast
192
215
  end
193
216
 
194
217
  # check second bit, SCT in stapled OSCP response
195
- if ep['details']['hasSct'] & (1<<1) != 0
218
+ if ep['details']['hasSct'] & (1 << 1) != 0
196
219
  Yawast::Utilities.puts_info "\t\tCertificate Transparency: SCT in the stapled OCSP response"
197
220
  end
198
221
 
199
222
  # check third bit, SCT in the TLS extension
200
- if ep['details']['hasSct'] & (1<<2) != 0
223
+ if ep['details']['hasSct'] & (1 << 2) != 0
201
224
  Yawast::Utilities.puts_info "\t\tCertificate Transparency: SCT in the TLS extension (ServerHello)"
202
225
  end
203
226
  else
@@ -209,7 +232,7 @@ module Yawast
209
232
  if cert['revocationInfo'] & 1 != 0
210
233
  Yawast::Utilities.puts_info "\t\tRevocation information: CRL information available"
211
234
  end
212
- if cert['revocationInfo'] & (1<<1) != 0
235
+ if cert['revocationInfo'] & (1 << 1) != 0
213
236
  Yawast::Utilities.puts_info "\t\tRevocation information: OCSP information available"
214
237
  end
215
238
 
@@ -244,18 +267,18 @@ module Yawast
244
267
  path_count = 0
245
268
 
246
269
  # build list of trust paths
247
- trust_paths = Hash.new
270
+ trust_paths = {}
248
271
  chain['trustPaths'].each do |path|
249
272
  trusts = nil
250
273
  # in practice, it seems there is only only per path, but just in case
251
274
  path['trust'].each do |trust|
252
- if trust['isTrusted']
253
- trust_line = "#{trust['rootStore']} (trusted)"
254
- else
255
- trust_line = "#{trust['rootStore']} (#{trust['trustErrorMessage']})"
256
- end
275
+ trust_line = if trust['isTrusted']
276
+ "#{trust['rootStore']} (trusted)"
277
+ else
278
+ "#{trust['rootStore']} (#{trust['trustErrorMessage']})"
279
+ end
257
280
 
258
- if trusts == nil
281
+ if trusts.nil?
259
282
  trusts = trust_line
260
283
  else
261
284
  trusts += " #{trust_line}"
@@ -277,25 +300,31 @@ module Yawast
277
300
  puts "\t\t Root Stores: #{trust_paths[key]}"
278
301
 
279
302
  # cert chain issues
280
- if chain['issues'] & (1<<1) != 0
303
+ if chain['issues'] & (1 << 1) != 0
281
304
  Yawast::Utilities.puts_warn "\t\tCertificate Chain Issue: incomplete chain"
305
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
306
+ 'tls_chain_incomplete',
307
+ {vulnerable: true}
308
+ else
309
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
310
+ 'tls_chain_incomplete',
311
+ {vulnerable: false}
282
312
  end
283
313
 
284
- if chain['issues'] & (1<<2) != 0
314
+ if chain['issues'] & (1 << 2) != 0
285
315
  Yawast::Utilities.puts_warn "\t\tCertificate Chain Issue: chain contains unrelated/duplicate certificates"
286
316
  end
287
317
 
288
- if chain['issues'] & (1<<3) != 0
289
- Yawast::Utilities.puts_warn "\t\tCertificate Chain Issue: incorrect order"
290
- end
318
+ Yawast::Utilities.puts_warn "\t\tCertificate Chain Issue: incorrect order" if chain['issues'] & (1 << 3) != 0
291
319
 
292
- if chain['issues'] & (1<<4) != 0
293
- Yawast::Utilities.puts_warn "\t\tCertificate Chain Issue: contains anchor"
294
- end
320
+ Yawast::Utilities.puts_warn "\t\tCertificate Chain Issue: contains anchor" if chain['issues'] & (1 << 4) != 0
295
321
 
296
- if cert['issues'] & (1<<5) != 0
297
- Yawast::Utilities.puts_warn "\t\tCertificate Chain Issue: untrusted"
298
- end
322
+ Yawast::Utilities.puts_warn "\t\tCertificate Chain Issue: untrusted" if cert['issues'] & (1 << 5) != 0
323
+
324
+ # setup the log entry for a symantec root - this will overwrite if one is found
325
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
326
+ 'tls_symantec_root',
327
+ {vulnerable: false, root_hash: ''}
299
328
 
300
329
  key.each do |path_cert|
301
330
  body['certs'].each do |c|
@@ -305,11 +334,14 @@ module Yawast
305
334
 
306
335
  if Yawast::Scanner::Plugins::SSL::SSL.check_symantec_root(c['sha256Hash'])
307
336
  Yawast::Utilities.puts_vuln "\t\t\t Untrusted Symantec Root"
337
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
338
+ 'tls_symantec_root',
339
+ {vulnerable: true, :root_hash => c['sha256Hash']}
308
340
  end
309
341
 
310
342
  Yawast::Utilities.puts_info "\t\t\t https://crt.sh/?q=#{c['sha1Hash']}"
311
343
 
312
- if chain['certIds'].find_index(c['sha256Hash']) != nil
344
+ unless chain['certIds'].find_index(c['sha256Hash']).nil?
313
345
  Yawast::Utilities.puts_info "\t\t\t (provided by server)"
314
346
  end
315
347
 
@@ -327,24 +359,53 @@ module Yawast
327
359
  puts "\tConfiguration Information:"
328
360
 
329
361
  puts "\t\tProtocol Support:"
330
- protos = Hash.new
362
+ # setup JSON output
363
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
364
+ 'tls_legacy_ssl',
365
+ {vulnerable: false}
366
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
367
+ 'tls_tls10_enabled',
368
+ {vulnerable: false}
369
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
370
+ 'tls_tls13_not_enabled',
371
+ {vulnerable: true}
372
+
373
+ # check protocols
374
+ protos = {}
375
+ tls13_enabled = false
331
376
  ep['details']['protocols'].each do |proto|
332
377
  if proto['name'] == 'SSL'
333
378
  # show a vuln for SSLvX
334
379
  Yawast::Utilities.puts_vuln "\t\t\t#{proto['name']} #{proto['version']}"
380
+
381
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
382
+ 'tls_legacy_ssl',
383
+ {vulnerable: true}
335
384
  elsif proto['name'] == 'TLS' && proto['version'] == '1.0'
336
385
  # show a warn for TLSv1.0
337
386
  Yawast::Utilities.puts_warn "\t\t\t#{proto['name']} #{proto['version']}"
387
+
388
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
389
+ 'tls_tls10_enabled',
390
+ {vulnerable: true}
391
+ elsif proto['name'] == 'TLS' && proto['version'] == '1.3'
392
+ # capture TLS 1.3 status
393
+ tls13_enabled = true
394
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
395
+ 'tls_tls13_not_enabled',
396
+ {vulnerable: false}
338
397
  else
339
398
  Yawast::Utilities.puts_info "\t\t\t#{proto['name']} #{proto['version']}"
340
399
  end
341
400
 
342
401
  protos[proto['id']] = "#{proto['name']} #{proto['version']}"
343
402
  end
403
+
404
+ Yawast::Utilities.puts_warn "\t\t\tTLS 1.3 Is Not Enabled" unless tls13_enabled
344
405
  puts
345
406
 
346
407
  puts "\t\tNamed Group Support:"
347
- if ep['details']['namedGroups'] != nil
408
+ unless ep['details']['namedGroups'].nil?
348
409
  ep['details']['namedGroups']['list'].each do |group|
349
410
  Yawast::Utilities.puts_info "\t\t\t#{group['name']} #{group['bits']}"
350
411
  end
@@ -352,7 +413,21 @@ module Yawast
352
413
  end
353
414
 
354
415
  puts "\t\tCipher Suite Support:"
355
- if ep['details']['suites'] != nil
416
+ # setup JSON output
417
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
418
+ 'tls_insecure_cipher_suites',
419
+ {vulnerable: false}
420
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
421
+ 'tls_weak_cipher_suites',
422
+ {vulnerable: false}
423
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
424
+ 'tls_3des_enabled',
425
+ {vulnerable: false, suite: ''}
426
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
427
+ 'tls_rc4_enabled',
428
+ {vulnerable: false, suite: ''}
429
+
430
+ if !ep['details']['suites'].nil?
356
431
  ep['details']['suites'].each do |proto_suites|
357
432
  Yawast::Utilities.puts_info "\t\t\t#{protos[proto_suites['protocol']]}"
358
433
 
@@ -364,22 +439,40 @@ module Yawast
364
439
  # in this case, the effective strength is only 112 bits,
365
440
  # which is what we want to report. So override SSL Labs
366
441
  strength = 112
442
+
443
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
444
+ 'tls_3des_enabled',
445
+ {vulnerable: true, suite: suite['name']}
367
446
  end
368
447
 
369
- if ke != nil
370
- suite_info = "#{suite['name'].ljust(50)} - #{strength}-bits - #{ke}"
371
- else
372
- suite_info = "#{suite['name'].ljust(50)} - #{strength}-bits"
448
+ if suite['name'].include? 'RC4'
449
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
450
+ 'tls_rc4_enabled',
451
+ {vulnerable: true, suite: suite['name']}
373
452
  end
374
453
 
454
+ suite_info = if !ke.nil?
455
+ "#{suite['name'].ljust(50)} - #{strength}-bits - #{ke}"
456
+ else
457
+ "#{suite['name'].ljust(50)} - #{strength}-bits"
458
+ end
459
+
375
460
  if cipher_suite_secure? suite
376
461
  if strength >= 128
377
462
  Yawast::Utilities.puts_info "\t\t\t #{suite_info}"
378
463
  else
379
464
  Yawast::Utilities.puts_warn "\t\t\t #{suite_info}"
465
+
466
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
467
+ 'tls_weak_cipher_suites',
468
+ {vulnerable: true}
380
469
  end
381
470
  else
382
471
  Yawast::Utilities.puts_vuln "\t\t\t #{suite_info}"
472
+
473
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
474
+ 'tls_insecure_cipher_suites',
475
+ {vulnerable: true}
383
476
  end
384
477
  end
385
478
  end
@@ -390,15 +483,13 @@ module Yawast
390
483
  puts
391
484
 
392
485
  puts "\t\tHandshake Simulation:"
393
- if ep['details']['sims']['results'] != nil
486
+ if !ep['details']['sims']['results'].nil?
394
487
  ep['details']['sims']['results'].each do |sim|
395
488
  name = "#{sim['client']['name']} #{sim['client']['version']}"
396
- if sim['client']['platform'] != nil
397
- name += " / #{sim['client']['platform']}"
398
- end
489
+ name += " / #{sim['client']['platform']}" unless sim['client']['platform'].nil?
399
490
  name = name.ljust(28)
400
491
 
401
- if sim['errorCode'] == 0
492
+ if sim['errorCode'].zero?
402
493
  protocol = protos[sim['protocolId']]
403
494
 
404
495
  ke = get_key_exchange sim
@@ -427,29 +518,50 @@ module Yawast
427
518
  Yawast::Utilities.puts_vuln "\t\t\t\t#{dh['ip']}:#{dh['port']} - #{dh['status']}"
428
519
  puts "\t\t\t\thttps://test.drownattack.com/?site=#{dh['ip']}"
429
520
  end
521
+
522
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
523
+ 'tls_drown',
524
+ {vulnerable: true}
430
525
  else
431
526
  Yawast::Utilities.puts_info "\t\t\tDROWN: No"
432
- end
433
527
 
434
- if ep['details']['renegSupport'] & 1 != 0
435
- Yawast::Utilities.puts_vuln "\t\t\tSecure Renegotiation: insecure client-initiated renegotiation supported"
436
- end
437
- if ep['details']['renegSupport'] & (1<<1) != 0
438
- Yawast::Utilities.puts_info "\t\t\tSecure Renegotiation: secure renegotiation supported"
528
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
529
+ 'tls_drown',
530
+ {vulnerable: false}
439
531
  end
440
- if ep['details']['renegSupport'] & (1<<2) != 0
441
- Yawast::Utilities.puts_info "\t\t\tSecure Renegotiation: secure client-initiated renegotiation supported"
442
- end
443
- if ep['details']['renegSupport'] & (1<<3) != 0
444
- Yawast::Utilities.puts_info "\t\t\tSecure Renegotiation: server requires secure renegotiation support"
532
+
533
+ unless ep['details']['renegSupport'].nil?
534
+ if ep['details']['renegSupport'] & 1 != 0
535
+ Yawast::Utilities.puts_vuln "\t\t\tSecure Renegotiation: insecure client-initiated renegotiation supported"
536
+ end
537
+ if ep['details']['renegSupport'] & (1 << 1) != 0
538
+ Yawast::Utilities.puts_info "\t\t\tSecure Renegotiation: secure renegotiation supported"
539
+ end
540
+ if ep['details']['renegSupport'] & (1 << 2) != 0
541
+ Yawast::Utilities.puts_info "\t\t\tSecure Renegotiation: secure client-initiated renegotiation supported"
542
+ end
543
+ if ep['details']['renegSupport'] & (1 << 3) != 0
544
+ Yawast::Utilities.puts_info "\t\t\tSecure Renegotiation: server requires secure renegotiation support"
545
+ end
445
546
  end
446
547
 
447
548
  if ep['details']['poodle']
448
549
  Yawast::Utilities.puts_vuln "\t\t\tPOODLE (SSL): Vulnerable"
550
+
551
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
552
+ 'tls_poodle_ssl',
553
+ {vulnerable: true}
449
554
  else
450
555
  Yawast::Utilities.puts_info "\t\t\tPOODLE (SSL): No"
556
+
557
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
558
+ 'tls_poodle_ssl',
559
+ {vulnerable: false}
451
560
  end
452
561
 
562
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
563
+ 'tls_poodle',
564
+ {vulnerable: false}
453
565
  case ep['details']['poodleTls']
454
566
  when -3
455
567
  Yawast::Utilities.puts_info "\t\t\tPOODLE (TLS): Inconclusive (Timeout)"
@@ -463,34 +575,72 @@ module Yawast
463
575
  Yawast::Utilities.puts_info "\t\t\tPOODLE (TLS): No"
464
576
  when 2
465
577
  Yawast::Utilities.puts_vuln "\t\t\tPOODLE (TLS): Vulnerable"
578
+
579
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
580
+ 'tls_poodle',
581
+ {vulnerable: true}
466
582
  else
467
583
  Yawast::Utilities.puts_error "\t\t\tPOODLE (TLS): Unknown Response #{ep['details']['poodleTls']}"
468
584
  end
469
585
 
470
586
  if ep['details']['fallbackScsv']
471
587
  Yawast::Utilities.puts_info "\t\t\tDowngrade Prevention: Yes"
588
+
589
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
590
+ 'tls_missing_fallback_scsv',
591
+ {vulnerable: false}
472
592
  else
473
593
  Yawast::Utilities.puts_warn "\t\t\tDowngrade Prevention: No"
594
+
595
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
596
+ 'tls_missing_fallback_scsv',
597
+ {vulnerable: true}
474
598
  end
475
599
 
476
600
  if ep['details']['compressionMethods'] & 1 != 0
477
601
  Yawast::Utilities.puts_warn "\t\t\tCompression: DEFLATE"
602
+
603
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
604
+ 'tls_compression_enabled',
605
+ {vulnerable: true}
478
606
  else
479
607
  Yawast::Utilities.puts_info "\t\t\tCompression: No"
608
+
609
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
610
+ 'tls_compression_enabled',
611
+ {vulnerable: false}
480
612
  end
481
613
 
482
614
  if ep['details']['heartbeat']
483
615
  Yawast::Utilities.puts_warn "\t\t\tHeartbeat: Enabled"
616
+
617
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
618
+ 'tls_heartbeat_enabled',
619
+ {vulnerable: true}
484
620
  else
485
621
  Yawast::Utilities.puts_info "\t\t\tHeartbeat: Disabled"
622
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
623
+ 'tls_heartbeat_enabled',
624
+ {vulnerable: false}
486
625
  end
487
626
 
488
627
  if ep['details']['heartbleed']
489
628
  Yawast::Utilities.puts_vuln "\t\t\tHeartbleed: Vulnerable"
629
+
630
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
631
+ 'tls_heartblead',
632
+ {vulnerable: true}
490
633
  else
491
634
  Yawast::Utilities.puts_info "\t\t\tHeartbleed: No"
635
+
636
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
637
+ 'tls_heartblead',
638
+ {vulnerable: false}
492
639
  end
493
640
 
641
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
642
+ 'tls_ticketbleed',
643
+ {vulnerable: false}
494
644
  case ep['details']['ticketbleed']
495
645
  when -1
496
646
  Yawast::Utilities.puts_error "\t\t\tTicketbleed (CVE-2016-9244): Test Failed"
@@ -500,11 +650,17 @@ module Yawast
500
650
  Yawast::Utilities.puts_info "\t\t\tTicketbleed (CVE-2016-9244): No"
501
651
  when 2
502
652
  Yawast::Utilities.puts_vuln "\t\t\tTicketbleed (CVE-2016-9244): Vulnerable"
653
+
654
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
655
+ 'tls_ticketbleed',
656
+ {vulnerable: true}
503
657
  else
504
658
  Yawast::Utilities.puts_error "\t\t\tTicketbleed (CVE-2016-9244): Unknown Response #{ep['details']['ticketbleed']}"
505
659
  end
506
660
 
507
-
661
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
662
+ 'tls_openssl_ccs_cve20140224',
663
+ {vulnerable: false, exploitable: false}
508
664
  case ep['details']['openSslCcs']
509
665
  when -1
510
666
  Yawast::Utilities.puts_error "\t\t\tOpenSSL CCS (CVE-2014-0224): Test Failed"
@@ -514,12 +670,24 @@ module Yawast
514
670
  Yawast::Utilities.puts_info "\t\t\tOpenSSL CCS (CVE-2014-0224): No"
515
671
  when 2
516
672
  Yawast::Utilities.puts_vuln "\t\t\tOpenSSL CCS (CVE-2014-0224): Vulnerable - Not Exploitable"
673
+
674
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
675
+ 'tls_openssl_ccs_cve20140224',
676
+ {vulnerable: true, exploitable: false}
517
677
  when 3
518
678
  Yawast::Utilities.puts_vuln "\t\t\tOpenSSL CCS (CVE-2014-0224): Vulnerable"
679
+
680
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
681
+ 'tls_openssl_ccs_cve20140224',
682
+ {vulnerable: true, exploitable: true}
519
683
  else
520
684
  Yawast::Utilities.puts_error "\t\t\tOpenSSL CCS (CVE-2014-0224): Unknown Response #{ep['details']['openSslCcs']}"
521
685
  end
522
686
 
687
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
688
+ 'tls_openssl_lunckyminus20',
689
+ {vulnerable: false}
690
+
523
691
  case ep['details']['openSSLLuckyMinus20']
524
692
  when -1
525
693
  Yawast::Utilities.puts_error "\t\t\tOpenSSL Padding Oracle (CVE-2016-2107): Test Failed"
@@ -529,10 +697,17 @@ module Yawast
529
697
  Yawast::Utilities.puts_info "\t\t\tOpenSSL Padding Oracle (CVE-2016-2107): No"
530
698
  when 2
531
699
  Yawast::Utilities.puts_vuln "\t\t\tOpenSSL Padding Oracle (CVE-2016-2107): Vulnerable"
700
+
701
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
702
+ 'tls_openssl_lunckyminus20',
703
+ {vulnerable: true}
532
704
  else
533
705
  Yawast::Utilities.puts_error "\t\t\tOpenSSL Padding Oracle (CVE-2016-2107): Unknown Response #{ep['details']['openSSLLuckyMinus20']}"
534
706
  end
535
707
 
708
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
709
+ 'tls_robot',
710
+ {vulnerable: false, exploitable: false}
536
711
  case ep['details']['bleichenbacher']
537
712
  when -1
538
713
  Yawast::Utilities.puts_error "\t\t\tROBOT: Test Failed"
@@ -542,28 +717,66 @@ module Yawast
542
717
  Yawast::Utilities.puts_info "\t\t\tROBOT: No"
543
718
  when 2
544
719
  Yawast::Utilities.puts_warn "\t\t\tROBOT: Not Exploitable"
720
+
721
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
722
+ 'tls_robot',
723
+ {vulnerable: true, exploitable: false}
545
724
  when 3
546
725
  Yawast::Utilities.puts_vuln "\t\t\tROBOT: Exploitable"
726
+
727
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
728
+ 'tls_robot',
729
+ {vulnerable: true, exploitable: true}
547
730
  when nil
548
731
  # if it's null, we don't care
549
732
  else
550
733
  Yawast::Utilities.puts_error "\t\t\tROBOT: Unknown Response #{ep['details']['bleichenbacher']}"
551
734
  end
552
735
 
553
- if ep['details']['forwardSecrecy'] & (1<<2) != 0
736
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
737
+ 'tls_missing_forward_secrecy',
738
+ {vulnerable: false}
739
+
740
+ if ep['details']['forwardSecrecy'] & (1 << 2) != 0
554
741
  Yawast::Utilities.puts_info "\t\t\tForward Secrecy: Yes (all simulated clients)"
555
- elsif ep['details']['forwardSecrecy'] & (1<<1) != 0
742
+ elsif ep['details']['forwardSecrecy'] & (1 << 1) != 0
556
743
  Yawast::Utilities.puts_info "\t\t\tForward Secrecy: Yes (modern clients)"
557
744
  elsif ep['details']['forwardSecrecy'] & 1 != 0
558
745
  Yawast::Utilities.puts_warn "\t\t\tForward Secrecy: Yes (limited support)"
746
+
747
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
748
+ 'tls_missing_forward_secrecy',
749
+ {vulnerable: true}
559
750
  else
560
751
  Yawast::Utilities.puts_vuln "\t\t\tForward Secrecy: No"
752
+
753
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
754
+ 'tls_missing_forward_secrecy',
755
+ {vulnerable: true}
756
+ end
757
+
758
+ if ep['details']['supportsAead']
759
+ Yawast::Utilities.puts_info "\t\t\tAEAD Cipher Suites Supported: Yes"
760
+
761
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
762
+ 'tls_aead_support_missing',
763
+ {vulnerable: false}
764
+ else
765
+ Yawast::Utilities.puts_warn "\t\t\tAEAD Cipher Suites Supported: No"
766
+
767
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
768
+ 'tls_aead_support_missing',
769
+ {vulnerable: true}
561
770
  end
562
771
 
563
772
  Yawast::Utilities.puts_info "\t\t\tALPN: #{ep['details']['alpnProtocols']}"
564
773
 
565
774
  Yawast::Utilities.puts_info "\t\t\tNPN: #{ep['details']['npnProtocols']}"
566
775
 
776
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
777
+ 'tls_session_resumption',
778
+ {vulnerable: false}
779
+
567
780
  case ep['details']['sessionResumption']
568
781
  when 0
569
782
  Yawast::Utilities.puts_info "\t\t\tSession Resumption: Not Enabled / Empty Tickets"
@@ -571,52 +784,64 @@ module Yawast
571
784
  Yawast::Utilities.puts_info "\t\t\tSession Resumption: Enabled / No Resumption"
572
785
  when 2
573
786
  Yawast::Utilities.puts_warn "\t\t\tSession Resumption: Enabled"
787
+
788
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
789
+ 'tls_session_resumption',
790
+ {vulnerable: true}
574
791
  else
575
792
  Yawast::Utilities.puts_error "\t\t\tSession Resumption: Unknown Response #{ep['details']['sessionResumption']}"
576
793
  end
577
794
 
578
795
  if ep['details']['ocspStapling']
579
796
  Yawast::Utilities.puts_info "\t\t\tOCSP Stapling: Yes"
797
+
798
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
799
+ 'tls_ocsp_stapling_missing',
800
+ {vulnerable: false}
580
801
  else
581
802
  Yawast::Utilities.puts_warn "\t\t\tOCSP Stapling: No"
803
+
804
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
805
+ 'tls_ocsp_stapling_missing',
806
+ {vulnerable: true}
582
807
  end
583
808
 
584
- if ep['details']['miscIntolerance'] > 0
809
+ if ep['details']['miscIntolerance'].positive?
585
810
  if ep['details']['miscIntolerance'] & 1 != 0
586
811
  Yawast::Utilities.puts_warn "\t\t\tTLS Extension Intolerance: Yes"
587
812
  end
588
813
 
589
- if ep['details']['miscIntolerance'] & (1<<1) != 0
814
+ if ep['details']['miscIntolerance'] & (1 << 1) != 0
590
815
  Yawast::Utilities.puts_warn "\t\t\tLong Handshake Intolerance: Yes"
591
816
  end
592
817
 
593
- if ep['details']['miscIntolerance'] & (1<<2) != 0
818
+ if ep['details']['miscIntolerance'] & (1 << 2) != 0
594
819
  Yawast::Utilities.puts_warn "\t\t\tLong Handshake Intolerance: Workaround Success"
595
820
  end
596
821
  end
597
822
 
598
- if ep['details']['protocolIntolerance'] > 0
823
+ if ep['details']['protocolIntolerance'].positive?
599
824
  if ep['details']['protocolIntolerance'] & 1 != 0
600
825
  Yawast::Utilities.puts_warn "\t\t\tProtocol Intolerance: TLS 1.0"
601
826
  end
602
827
 
603
- if ep['details']['protocolIntolerance'] & (1<<1) != 0
828
+ if ep['details']['protocolIntolerance'] & (1 << 1) != 0
604
829
  Yawast::Utilities.puts_warn "\t\t\tProtocol Intolerance: TLS 1.1"
605
830
  end
606
831
 
607
- if ep['details']['protocolIntolerance'] & (1<<2) != 0
832
+ if ep['details']['protocolIntolerance'] & (1 << 2) != 0
608
833
  Yawast::Utilities.puts_warn "\t\t\tProtocol Intolerance: TLS 1.2"
609
834
  end
610
835
 
611
- if ep['details']['protocolIntolerance'] & (1<<3) != 0
836
+ if ep['details']['protocolIntolerance'] & (1 << 3) != 0
612
837
  Yawast::Utilities.puts_warn "\t\t\tProtocol Intolerance: TLS 1.3"
613
838
  end
614
839
 
615
- if ep['details']['protocolIntolerance'] & (1<<4) != 0
840
+ if ep['details']['protocolIntolerance'] & (1 << 4) != 0
616
841
  Yawast::Utilities.puts_warn "\t\t\tProtocol Intolerance: TLS 1.152"
617
842
  end
618
843
 
619
- if ep['details']['protocolIntolerance'] & (1<<5) != 0
844
+ if ep['details']['protocolIntolerance'] & (1 << 5) != 0
620
845
  Yawast::Utilities.puts_warn "\t\t\tProtocol Intolerance: TLS 2.152"
621
846
  end
622
847
  else
@@ -625,39 +850,83 @@ module Yawast
625
850
 
626
851
  if ep['details']['freak']
627
852
  Yawast::Utilities.puts_vuln "\t\t\tFREAK: Vulnerable (512-bit key exchange supported)"
853
+
854
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
855
+ 'tls_freak',
856
+ {vulnerable: true}
628
857
  else
629
858
  Yawast::Utilities.puts_info "\t\t\tFREAK: No"
859
+
860
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
861
+ 'tls_freak',
862
+ {vulnerable: false}
630
863
  end
631
864
 
632
865
  if ep['details']['logjam']
633
866
  Yawast::Utilities.puts_vuln "\t\t\tLogjam: Vulnerable (DH key exchange with keys smaller than 1024 bits)"
867
+
868
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
869
+ 'tls_logjam',
870
+ {vulnerable: true}
634
871
  else
635
872
  Yawast::Utilities.puts_info "\t\t\tLogjam: No"
873
+
874
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
875
+ 'tls_logjam',
876
+ {vulnerable: false}
636
877
  end
637
878
 
879
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
880
+ 'tls_dh_known_primes',
881
+ {vulnerable: false, weak: false}
882
+
638
883
  case ep['details']['dhUsesKnownPrimes']
639
884
  when 0
640
885
  Yawast::Utilities.puts_info "\t\t\tUses common DH primes: No"
641
886
  when 1
642
887
  Yawast::Utilities.puts_warn "\t\t\tUses common DH primes: Yes (not weak)"
888
+
889
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
890
+ 'tls_dh_known_primes',
891
+ {vulnerable: true, weak: false}
643
892
  when 2
644
893
  Yawast::Utilities.puts_vuln "\t\t\tUses common DH primes: Yes (weak)"
894
+
895
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
896
+ 'tls_dh_known_primes',
897
+ {vulnerable: true, weak: true}
645
898
  else
646
- unless ep['details']['dhUsesKnownPrimes'] == nil
899
+ unless ep['details']['dhUsesKnownPrimes'].nil?
647
900
  Yawast::Utilities.puts_error "\t\t\tUses common DH primes: Unknown Response #{ep['details']['dhUsesKnownPrimes']}"
648
901
  end
649
902
  end
650
903
 
651
904
  if ep['details']['dhYsReuse']
652
905
  Yawast::Utilities.puts_vuln "\t\t\tDH public server param (Ys) reuse: Yes"
906
+
907
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
908
+ 'tls_dh_public_server_param_reuse',
909
+ {vulnerable: true}
653
910
  else
654
911
  Yawast::Utilities.puts_info "\t\t\tDH public server param (Ys) reuse: No"
912
+
913
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
914
+ 'tls_dh_public_server_param_reuse',
915
+ {vulnerable: false}
655
916
  end
656
917
 
657
918
  if ep['details']['ecdhParameterReuse']
658
919
  Yawast::Utilities.puts_vuln "\t\t\tECDH Public Server Param Reuse: Yes"
920
+
921
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
922
+ 'tls_ecdh_public_server_param_reuse',
923
+ {vulnerable: true}
659
924
  else
660
925
  Yawast::Utilities.puts_info "\t\t\tECDH Public Server Param Reuse: No"
926
+
927
+ Yawast::Shared::Output.log_hash 'vulnerabilities',
928
+ 'tls_ecdh_public_server_param_reuse',
929
+ {vulnerable: false}
661
930
  end
662
931
 
663
932
  puts
@@ -667,32 +936,26 @@ module Yawast
667
936
  secure = true
668
937
 
669
938
  # check for weak DH
670
- if suite['kxStrength'] != nil && suite['kxStrength'] < 2048
671
- secure = false
672
- end
939
+ secure = false if !suite['kxStrength'].nil? && suite['kxStrength'] < 2048
673
940
  # check for RC4
674
- if suite['name'].include? 'RC4'
675
- secure = false
676
- end
941
+ secure = false if suite['name'].include? 'RC4'
677
942
  # check for weak suites
678
- if suite['cipherStrength'] < 112
679
- secure = false
680
- end
943
+ secure = false if suite['cipherStrength'] < 112
681
944
 
682
945
  secure
683
946
  end
684
947
 
685
948
  def self.get_key_exchange(suite)
686
949
  ke = nil
687
- if suite['kxType'] != nil
688
- if suite['namedGroupBits'] != nil
689
- ke = "#{suite['kxType']}-#{suite['namedGroupBits']} / #{suite['namedGroupName']} (#{suite['kxStrength']} equivalent)"
690
- else
691
- ke = "#{suite['kxType']}-#{suite['kxStrength']}"
692
- end
950
+ unless suite['kxType'].nil?
951
+ ke = if !suite['namedGroupBits'].nil?
952
+ "#{suite['kxType']}-#{suite['namedGroupBits']} / #{suite['namedGroupName']} (#{suite['kxStrength']} equivalent)"
953
+ else
954
+ "#{suite['kxType']}-#{suite['kxStrength']}"
955
+ end
693
956
  end
694
957
 
695
- return ke
958
+ ke
696
959
  end
697
960
  end
698
961
  end