class Yawast::Scanner::Ssl
Public Class Methods
check_cipher_strength(cipher, ssl)
click to toggle source
# File lib/scanner/ssl.rb, line 158 def self.check_cipher_strength(cipher, ssl) if cipher[2] < 112 || cipher[0].include?('RC4') # less than 112 bits or RC4, flag as a vuln Yawast::Utilities.puts_vuln "\t\tVersion: #{ssl.ssl_version.ljust(7)}\tBits: #{cipher[2]}\tCipher: #{cipher[0]}" elsif cipher[2] >= 128 # secure, probably safe Yawast::Utilities.puts_info "\t\tVersion: #{ssl.ssl_version.ljust(7)}\tBits: #{cipher[2]}\tCipher: #{cipher[0]}" else # weak, but not "omg!" weak. Yawast::Utilities.puts_warn "\t\tVersion: #{ssl.ssl_version.ljust(7)}\tBits: #{cipher[2]}\tCipher: #{cipher[0]}" end end
get_cert_chain_info(cert_chain, cert)
click to toggle source
# File lib/scanner/ssl.rb, line 89 def self.get_cert_chain_info(cert_chain, cert) if cert_chain.count == 1 # HACK: This is an ugly way to guess if it's a missing intermediate, or self-signed # It looks like a change to Ruby's OpenSSL wrapper is needed to actually fix this right. if cert.issuer == cert.subject Yawast::Utilities.puts_vuln "\t\tCertificate Is Self-Signed" else Yawast::Utilities.puts_warn "\t\tCertificate Chain Is Incomplete" end puts '' end unless cert_chain.nil? Yawast::Utilities.puts_info 'Certificate: Chain' cert_chain.each do |c| Yawast::Utilities.puts_info "\t\tIssued To: #{c.subject.common_name} / #{c.subject.organization}" Yawast::Utilities.puts_info "\t\t\tIssuer: #{c.issuer.common_name} / #{c.issuer.organization}" Yawast::Utilities.puts_info "\t\t\tExpires: #{c.not_after}" Yawast::Utilities.puts_info "\t\t\tKey: #{c.public_key.class.to_s.gsub('OpenSSL::PKey::', '')}-#{get_x509_pub_key_strength(c)}" Yawast::Utilities.puts_info "\t\t\tSignature Algorithm: #{c.signature_algorithm}" Yawast::Utilities.puts_info "\t\t\tHash: #{Digest::SHA1.hexdigest(c.to_der)}" puts '' end puts '' end end
get_cert_info(cert)
click to toggle source
# File lib/scanner/ssl.rb, line 47 def self.get_cert_info(cert) Yawast::Utilities.puts_info 'Found X509 Certificate:' Yawast::Utilities.puts_info "\t\tIssued To: #{cert.subject.common_name} / #{cert.subject.organization}" Yawast::Utilities.puts_info "\t\tIssuer: #{cert.issuer.common_name} / #{cert.issuer.organization}" Yawast::Utilities.puts_info "\t\tVersion: #{cert.version}" Yawast::Utilities.puts_info "\t\tSerial: #{cert.serial}" Yawast::Utilities.puts_info "\t\tSubject: #{cert.subject}" # check to see if cert is expired if cert.not_after > Time.now Yawast::Utilities.puts_info "\t\tExpires: #{cert.not_after}" else Yawast::Utilities.puts_vuln "\t\tExpires: #{cert.not_after} (Expired)" end # check for SHA1 & MD5 certs if cert.signature_algorithm.include?('md5') || cert.signature_algorithm.include?('sha1') Yawast::Utilities.puts_vuln "\t\tSignature Algorithm: #{cert.signature_algorithm}" else Yawast::Utilities.puts_info "\t\tSignature Algorithm: #{cert.signature_algorithm}" end Yawast::Utilities.puts_info "\t\tKey: #{cert.public_key.class.to_s.gsub('OpenSSL::PKey::', '')}-#{get_x509_pub_key_strength(cert)}" Yawast::Utilities.puts_info "\t\t\tKey Hash: #{Digest::SHA1.hexdigest(cert.public_key.to_s)}" Yawast::Utilities.puts_info "\t\tExtensions:" cert.extensions.each { |ext| Yawast::Utilities.puts_info "\t\t\t#{ext}" unless ext.oid == 'subjectAltName' || ext.oid == 'ct_precert_scts' } # ct_precert_scts Yawast::Scanner::Plugins::SSL::SSL.print_precert cert # alt names alt_names = cert.extensions.find {|e| e.oid == 'subjectAltName'} unless alt_names.nil? Yawast::Utilities.puts_info "\t\tAlternate Names:" alt_names.value.split(',').each { |name| Yawast::Utilities.puts_info "\t\t\t#{name.strip.delete('DNS:')}" } end Yawast::Scanner::Plugins::SSL::SSL.print_cert_hash cert puts end
get_ciphers(uri)
click to toggle source
# File lib/scanner/ssl.rb, line 119 def self.get_ciphers(uri) puts 'Supported Ciphers:' dns = Resolv::DNS.new ip = if IPAddress.valid? uri.host IPAddress.parse uri.host else dns.getaddresses(uri.host)[0] end protocols = %w[ssl2 ssl3 tls1.0 tls1.1 tls1.2] protocols.each do |protocol| ciphers = case protocol when 'ssl2' SSLShake::SSLv2::CIPHERS when 'ssl3' SSLShake::TLS::SSL3_CIPHERS else SSLShake::TLS::TLS_CIPHERS end puts "\tChecking for #{protocol} suites (#{ciphers.count} possible suites)" ciphers.each_key do |cipher| begin res = SSLShake.hello(ip.to_s, {port: uri.port, protocol: protocol, ciphers: cipher, servername: uri.host}) Yawast::Utilities.puts_info "\t\tCipher: #{res['cipher_suite']}" if res['error'].nil? rescue => e # rubocop:disable Style/RescueStandardError Yawast::Utilities.puts_error "SSL: Error Reading Cipher Details: #{e.message}" end end end puts '' end
info(uri, check_ciphers, tdes_session_count)
click to toggle source
# File lib/scanner/ssl.rb, line 11 def self.info(uri, check_ciphers, tdes_session_count) begin puts puts 'DEPRECATED: The Internal SSL Scanner (--internalssl) is deprecated and will not be updated.' puts 'DEPRECATED: Use a tool such as testssl.sh or sslyze instead.' puts socket = TCPSocket.new(uri.host, uri.port) ctx = OpenSSL::SSL::SSLContext.new ctx.ciphers = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ciphers] ssl = OpenSSL::SSL::SSLSocket.new(socket, ctx) ssl.hostname = uri.host ssl.connect cert = ssl.peer_cert get_cert_info cert unless cert.nil? cert_chain = ssl.peer_cert_chain get_cert_chain_info cert_chain, cert puts "\t\tQualys SSL Labs: https://www.ssllabs.com/ssltest/analyze.html?d=#{uri.host}&hideResults=on" puts '' get_ciphers(uri) if check_ciphers ssl.sysclose Yawast::Scanner::Plugins::SSL::Sweet32.get_tdes_session_msg_count(uri) if tdes_session_count rescue => e # rubocop:disable Style/RescueStandardError Yawast::Utilities.puts_error "SSL: Error Reading X509 Details: #{e.message}" end end
Private Class Methods
get_x509_pub_key_strength(cert)
click to toggle source
# File lib/scanner/ssl.rb, line 175 def get_x509_pub_key_strength(cert) begin if cert.public_key.class == OpenSSL::PKey::EC cert.public_key.group.curve_name else cert.public_key.strength end rescue => e # rubocop:disable Style/RescueStandardError "(Strength Unknown: #{e.message})" end end