
##
# 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::HttpClient
	include Msf::Auxiliary::WMAPScanServer
	include Msf::Auxiliary::Scanner
	include Msf::Auxiliary::Report
	
	include Rex::Socket::Comm

	def initialize
		super(
			'Name'        => 'HTTP SSL Certificate tester',
			'Version'     => '$Revision: 7629 $',
			'Description' => 'Display vhost associated to server using SSL certificate and check for signature algorithm',
			'Author'      => 'et',
			'License'     => MSF_LICENSE
		)
		
	end

	# Fingerprint a single host
	def run_host(ip)
		if !datastore['SSL'] 
			print_error("SSL set to false")
			return
		end	

		begin
			ssock = Rex::Socket::SslTcp.create(
				'PeerHost' => wmap_target_host,
				'PeerPort' => wmap_target_port,
				'Proxies'  => datastore['PROXIES'] 	
			)

			cert  = OpenSSL::X509::Certificate.new(ssock.peer_cert)

			ssock.close	
			
			if cert
				print_status("[#{ip}:#{datastore['RPORT']}] Subject: #{cert.subject} Signature Alg: #{cert.signature_algorithm}")
				alg = cert.signature_algorithm
				
				if alg.downcase.include? "md5"
					print_status("[#{ip}:#{datastore['RPORT']}] WARNING: Signature algorithm using MD5 (#{alg})")
				end
				
				sub = cert.subject.to_a
				
				vhostn = 'EMPTY' 
				sub.each do |n|
					#print_line "#{n[0]}"
					if n[0] == 'CN'
						#print_line "> #{n[1]}"
						vhostn = n[1]
					end
				end
			
				if vhostn
					print_status("[#{ip}:#{datastore['RPORT']}] is host #{vhostn}")
					
					report_note(
						:host	=> ip,
						:proto	=> 'HTTP',
						:port	=> rport,
						:type	=> 'VHOST',
						:data	=> "#{vhostn}"
					)
					
					report_note(
						:host	=> ip,
						:proto	=> 'HTTP',
						:port	=> rport,
						:type	=> 'X509',
						:data	=> "Subject: #{cert.subject} Algorithm: #{cert.signature_algorithm}"
					)
				end
			else
				print_status("[#{ip}:#{datastore['RPORT']}] No certificate subject or CN found")
			end			
		rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
		rescue ::Timeout::Error, ::Errno::EPIPE
		end
	end		
end

