Path: blob/master/modules/auxiliary/scanner/http/cert.rb
19664 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Exploit::Remote::Tcp7include Msf::Auxiliary::WmapScanSSL8include Msf::Auxiliary::Scanner9include Msf::Auxiliary::Report1011def initialize12super(13'Name' => 'HTTP SSL Certificate Checker',14'Author' => 'nebulus',15'License' => MSF_LICENSE,16'Description' => %q{17This module will check the certificate of the specified web servers18to ensure the subject and issuer match the supplied pattern and that the certificate19is not expired.20}21)2223register_options(24[25Opt::RPORT(443),26OptRegexp.new('ISSUER', [ true, "Show a warning if the Issuer doesn't match this regex", '.*']),27OptBool.new('SHOWALL', [ false, "Show all certificates (issuer,time) regardless of match", false]),28]29)30end3132# Fingerprint a single host33def run_host(ip)34connect(true, { "SSL" => true }) # Force SSL35cert = OpenSSL::X509::Certificate.new(sock.peer_cert)36disconnect3738if (not cert)39print_status("#{ip} No certificate subject or CN found")40return41end42sub = cert.subject.to_a4344before = Time.parse("#{cert.not_before}")45after = Time.parse("#{cert.not_after}")4647now = Time.now48a = now <=> before49b = now <=> after5051vhostn = 'EMPTY'52sub.each do |n|53if n[0] == 'CN'54vhostn = n[1]55end56end5758if cert.issuer.to_s !~ /#{datastore['ISSUER'].source}/n59print_good("#{ip} - '#{vhostn}' : #{cert.issuer} (BAD ISSUER)")60elsif datastore['SHOWALL']61# show verbose as status62print_status("#{ip} - '#{vhostn}' : #{cert.issuer}")63end6465if (a < 1 or b > 0)66print_good("#{ip} - '#{vhostn}' : '" + before.to_s + "' - '" + after.to_s + "' (EXPIRED)'")67else68# show verbose as status69print_status("#{ip} - '#{vhostn}' : '" + before.to_s + "' - '" + after.to_s + "'")70end7172report_note(73:host => ip,74:port => rport,75:proto => 'tcp',76:type => 'http.vhost',77:data => { :name => vhostn }78) if vhostn7980# Store the SSL certificate itself81report_note(82:host => ip,83:proto => 'tcp',84:port => rport,85:type => 'ssl.certificate',86:data => {87:cn => vhostn,88:subject => cert.subject.to_a,89:algorithm => cert.signature_algorithm9091}92) if vhostn9394# Update the server hostname if necessary95if vhostn !~ /localhost|snakeoil/i96report_host(97:host => ip,98:name => vhostn99)100end101rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout102rescue ::Timeout::Error, ::Errno::EPIPE103rescue ::OpenSSL::SSL::SSLError => e104return if (e.to_s.match(/^SSL_connect /)) # strange errors / exception if SSL connection aborted105rescue ::Exception => e106return if (e.to_s =~ /execution expired/)107108print_error("Error: '#{ip}' '#{e.class}' '#{e}' '#{e.backtrace}'")109end110end111112113