Fix a few issues with the SSL scanner

First, we need to handle public keys with strength not measured on the same bit
scale as RSA keys. This fixes handshakes for ECDSA and others.

Second, depending on the host we are talking to, we may not have a peer cert.
Handle this properly by checking first on the socket before using it.
bug/bundler_fix
Brent Cook 2016-03-29 00:21:24 -05:00
parent 72d631a255
commit af7eef231c
1 changed files with 29 additions and 20 deletions

View File

@ -38,56 +38,65 @@ class MetasploitModule < Msf::Auxiliary
connect(true, {"SSL" => true}) #Force SSL
if sock.respond_to? :peer_cert
cert = OpenSSL::X509::Certificate.new(sock.peer_cert)
end
disconnect
if cert
print_status("#{ip}:#{rport} Subject: #{cert.subject}")
print_status("#{ip}:#{rport} Issuer: #{cert.issuer}")
print_status("#{ip}:#{rport} Signature Alg: #{cert.signature_algorithm}")
print_status("Subject: #{cert.subject}")
print_status("Issuer: #{cert.issuer}")
print_status("Signature Alg: #{cert.signature_algorithm}")
# If we use ECDSA rather than RSA, our metrics for key size are different
public_key_size = 0
if cert.public_key.respond_to? :n
public_key_size = cert.public_key.n.num_bytes * 8
print_status("#{ip}:#{rport} Public Key Size: #{public_key_size} bits")
print_status("#{ip}:#{rport} Not Valid Before: #{cert.not_before}")
print_status("#{ip}:#{rport} Not Valid After: #{cert.not_after}")
print_status("Public Key Size: #{public_key_size} bits")
end
print_status("Not Valid Before: #{cert.not_before}")
print_status("Not Valid After: #{cert.not_after}")
# Checks for common properties of self signed certificates
caissuer = (/CA Issuers - URI:(.*?),/i).match(cert.extensions.to_s)
if caissuer.to_s.empty?
print_good("#{ip}:#{rport} Certificate contains no CA Issuers extension... possible self signed certificate")
print_good("Certificate contains no CA Issuers extension... possible self signed certificate")
else
print_status("#{ip}:#{rport} " +caissuer.to_s[0..-2])
print_status(caissuer.to_s[0..-2])
end
if cert.issuer.to_s == cert.subject.to_s
print_good("#{ip}:#{rport} Certificate Subject and Issuer match... possible self signed certificate")
print_good("Certificate Subject and Issuer match... possible self signed certificate")
end
alg = cert.signature_algorithm
if alg.downcase.include? "md5"
print_status("#{ip}:#{rport} WARNING: Signature algorithm using MD5 (#{alg})")
print_status("WARNING: Signature algorithm using MD5 (#{alg})")
end
vhostn = nil
cert.subject.to_a.each do |n|
vhostn = n[1] if n[0] == 'CN'
end
if public_key_size > 0
if public_key_size == 1024
print_status("#{ip}:#{rport} WARNING: Public Key only 1024 bits")
print_status("WARNING: Public Key only 1024 bits")
elsif public_key_size < 1024
print_status("#{ip}:#{rport} WARNING: Weak Public Key: #{public_key_size} bits")
print_status("WARNING: Weak Public Key: #{public_key_size} bits")
end
end
if cert.not_after < Time.now
print_status("#{ip}:#{rport} WARNING: Certificate not valid anymore")
print_status("WARNING: Certificate not valid anymore")
end
if cert.not_before > Time.now
print_status("#{ip}:#{rport} WARNING: Certificate not valid yet")
print_status("WARNING: Certificate not valid yet")
end
if vhostn
print_status("#{ip}:#{rport} has common name #{vhostn}")
print_status("Has common name #{vhostn}")
# Store the virtual hostname for HTTP
report_note(
@ -125,7 +134,7 @@ class MetasploitModule < Msf::Auxiliary
end
else
print_status("#{ip}:#{rport}] No certificate subject or common name found")
print_status("No certificate subject or common name found")
end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE