Skip to content

Commit af7eef2

Browse files
author
Brent Cook
committed
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.
1 parent 72d631a commit af7eef2

File tree

1 file changed

+29
-20
lines changed
  • modules/auxiliary/scanner/http

1 file changed

+29
-20
lines changed

modules/auxiliary/scanner/http/ssl.rb

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,56 +38,65 @@ def run_host(ip)
3838

3939
connect(true, {"SSL" => true}) #Force SSL
4040

41-
cert = OpenSSL::X509::Certificate.new(sock.peer_cert)
41+
if sock.respond_to? :peer_cert
42+
cert = OpenSSL::X509::Certificate.new(sock.peer_cert)
43+
end
4244

4345
disconnect
4446

4547
if cert
46-
print_status("#{ip}:#{rport} Subject: #{cert.subject}")
47-
print_status("#{ip}:#{rport} Issuer: #{cert.issuer}")
48-
print_status("#{ip}:#{rport} Signature Alg: #{cert.signature_algorithm}")
49-
public_key_size = cert.public_key.n.num_bytes * 8
50-
print_status("#{ip}:#{rport} Public Key Size: #{public_key_size} bits")
51-
print_status("#{ip}:#{rport} Not Valid Before: #{cert.not_before}")
52-
print_status("#{ip}:#{rport} Not Valid After: #{cert.not_after}")
48+
print_status("Subject: #{cert.subject}")
49+
print_status("Issuer: #{cert.issuer}")
50+
print_status("Signature Alg: #{cert.signature_algorithm}")
51+
52+
# If we use ECDSA rather than RSA, our metrics for key size are different
53+
public_key_size = 0
54+
if cert.public_key.respond_to? :n
55+
public_key_size = cert.public_key.n.num_bytes * 8
56+
print_status("Public Key Size: #{public_key_size} bits")
57+
end
58+
print_status("Not Valid Before: #{cert.not_before}")
59+
print_status("Not Valid After: #{cert.not_after}")
5360

5461
# Checks for common properties of self signed certificates
5562
caissuer = (/CA Issuers - URI:(.*?),/i).match(cert.extensions.to_s)
5663

5764
if caissuer.to_s.empty?
58-
print_good("#{ip}:#{rport} Certificate contains no CA Issuers extension... possible self signed certificate")
65+
print_good("Certificate contains no CA Issuers extension... possible self signed certificate")
5966
else
60-
print_status("#{ip}:#{rport} " +caissuer.to_s[0..-2])
67+
print_status(caissuer.to_s[0..-2])
6168
end
6269

6370
if cert.issuer.to_s == cert.subject.to_s
64-
print_good("#{ip}:#{rport} Certificate Subject and Issuer match... possible self signed certificate")
71+
print_good("Certificate Subject and Issuer match... possible self signed certificate")
6572
end
6673

6774
alg = cert.signature_algorithm
6875

6976
if alg.downcase.include? "md5"
70-
print_status("#{ip}:#{rport} WARNING: Signature algorithm using MD5 (#{alg})")
77+
print_status("WARNING: Signature algorithm using MD5 (#{alg})")
7178
end
7279

7380
vhostn = nil
7481
cert.subject.to_a.each do |n|
7582
vhostn = n[1] if n[0] == 'CN'
7683
end
77-
if public_key_size == 1024
78-
print_status("#{ip}:#{rport} WARNING: Public Key only 1024 bits")
79-
elsif public_key_size < 1024
80-
print_status("#{ip}:#{rport} WARNING: Weak Public Key: #{public_key_size} bits")
84+
if public_key_size > 0
85+
if public_key_size == 1024
86+
print_status("WARNING: Public Key only 1024 bits")
87+
elsif public_key_size < 1024
88+
print_status("WARNING: Weak Public Key: #{public_key_size} bits")
89+
end
8190
end
8291
if cert.not_after < Time.now
83-
print_status("#{ip}:#{rport} WARNING: Certificate not valid anymore")
92+
print_status("WARNING: Certificate not valid anymore")
8493
end
8594
if cert.not_before > Time.now
86-
print_status("#{ip}:#{rport} WARNING: Certificate not valid yet")
95+
print_status("WARNING: Certificate not valid yet")
8796
end
8897

8998
if vhostn
90-
print_status("#{ip}:#{rport} has common name #{vhostn}")
99+
print_status("Has common name #{vhostn}")
91100

92101
# Store the virtual hostname for HTTP
93102
report_note(
@@ -125,7 +134,7 @@ def run_host(ip)
125134

126135
end
127136
else
128-
print_status("#{ip}:#{rport}] No certificate subject or common name found")
137+
print_status("No certificate subject or common name found")
129138
end
130139
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
131140
rescue ::Timeout::Error, ::Errno::EPIPE

0 commit comments

Comments
 (0)