metasploit-framework/modules/auxiliary/scanner/http/cert.rb

93 lines
2.6 KiB
Ruby

##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex/socket/ssl_tcp'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::WMAPScanServer
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'HTTP SSL Certificate Checker',
'Version' => '$Revision$',
'Author' => 'nebulus',
'License' => MSF_LICENSE,
'Description' => %q{
This module will check the certificate of the specified web servers
to ensure the subject and issuer match the supplied pattern and that the certificate
is not expired.
}
)
register_options(
[
Opt::RPORT(443),
OptString.new('ISSUER', [ true, "Show a warning if the Issuer doesn't match this regex", '.*']),
OptBool.new('SHOWALL', [ false, "Show all certificates regardless of match", false]),
], self.class)
end
# Fingerprint a single host
def run_host(ip)
begin
ssock = connect(false, {'SSL' => true})
cert = OpenSSL::X509::Certificate.new(ssock.peer_cert)
ssock.close
if(not cert)
print_status("#{ip} No certificate subject or CN found")
return
end
issuer_pattern = Regexp.new(datastore['ISSUER'], Regexp::EXTENDED, 'n')
sub = cert.subject.to_a
before_d = "#{cert.not_before}".split
before_t = before_d[3].split(":")
after_d = "#{cert.not_after}".split
after_t = after_d[3].split(":")
before = Time.utc(before_d[5],before_d[1],before_d[2],before_t[0],before_t[1],before_t[3])
after = Time.utc(after_d[5],after_d[1],after_d[2],after_t[0],after_t[1],after_t[3])
now = Time.now
a = now <=> before
b = now <=> after
vhostn = 'EMPTY'
sub.each do |n|
if n[0] == 'CN'
vhostn = n[1]
end
end
if ( not "#{cert.issuer}" =~ /#{issuer_pattern}/)
print_status("WARNING (Issuer): #{ip} / #{vhostn} : #{cert.issuer}" )
end
print_status("#{ip} / #{vhostn} Issuer: #{cert.issuer}") if datastore['SHOWALL']
if ( a < 1 or b > 0 )
print_status("WARNING (Expired): #{ip} / #{vhostn} : Cert is expired/invalid: Before: " + before.to_s + " After " + after.to_s)
end
print_status("#{ip} / #{vhostn} Before: " + before.to_s + " After: " + after.to_s + " Now: " + now.to_s) if datastore['SHOWALL']
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
end
end
end