Add verification methods to HTTPS
This commit enables peer verification for SSL. It also gives the user options to verify the server if the server uses a self-signed cert. There is an override to skip verification as well.GSoC/Meterpreter_Web_Console
parent
8022294d1d
commit
d10cd2d92a
|
@ -22,9 +22,10 @@ class RemoteHTTPDataService
|
||||||
#
|
#
|
||||||
# @param [String] endpoint A valid http or https URL. Cannot be nil
|
# @param [String] endpoint A valid http or https URL. Cannot be nil
|
||||||
#
|
#
|
||||||
def initialize(endpoint)
|
def initialize(endpoint, https_opts = {})
|
||||||
validate_endpoint(endpoint)
|
validate_endpoint(endpoint)
|
||||||
@endpoint = URI.parse(endpoint)
|
@endpoint = URI.parse(endpoint)
|
||||||
|
@https_opts = https_opts
|
||||||
build_client_pool(5)
|
build_client_pool(5)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -244,12 +245,39 @@ class RemoteHTTPDataService
|
||||||
http = Net::HTTP.new(@endpoint.host, @endpoint.port)
|
http = Net::HTTP.new(@endpoint.host, @endpoint.port)
|
||||||
if @endpoint.is_a?(URI::HTTPS)
|
if @endpoint.is_a?(URI::HTTPS)
|
||||||
http.use_ssl = true
|
http.use_ssl = true
|
||||||
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||||
|
unless @https_opts.empty?
|
||||||
|
if @https_opts[:skip_verify]
|
||||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||||
|
else
|
||||||
|
# https://stackoverflow.com/questions/22093042/implementing-https-certificate-pubkey-pinning-with-ruby
|
||||||
|
user_passed_cert = OpenSSL::X509::Certificate.new(File.read(@https_opts[:cert]))
|
||||||
|
|
||||||
|
http.verify_callback = lambda do |preverify_ok, cert_store|
|
||||||
|
server_cert = cert_store.chain[0]
|
||||||
|
return true unless server_cert.to_der == cert_store.current_cert.to_der
|
||||||
|
same_public_key?(server_cert, user_passed_cert)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
@client_pool << http
|
@client_pool << http
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Tells us whether the private keys on the passed certificates match
|
||||||
|
# and use the same algo
|
||||||
|
def same_public_key?(ref_cert, actual_cert)
|
||||||
|
pkr, pka = ref_cert.public_key, actual_cert.public_key
|
||||||
|
|
||||||
|
# First check if the public keys use the same crypto...
|
||||||
|
return false unless pkr.class == pka.class
|
||||||
|
# ...and then - that they have the same contents
|
||||||
|
return false unless pkr.to_pem == pka.to_pem
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
def try_sound_effect()
|
def try_sound_effect()
|
||||||
sound_file = ::File.join(Msf::Config.data_directory, "sounds", "Goliath_Online_Sound_Effect.wav")
|
sound_file = ::File.join(Msf::Config.data_directory, "sounds", "Goliath_Online_Sound_Effect.wav")
|
||||||
Rex::Compat.play_sound(sound_file)
|
Rex::Compat.play_sound(sound_file)
|
||||||
|
|
|
@ -101,6 +101,7 @@ module Msf
|
||||||
def cmd_add_data_service(*args)
|
def cmd_add_data_service(*args)
|
||||||
protocol = "http"
|
protocol = "http"
|
||||||
port = 80
|
port = 80
|
||||||
|
https_opts = {}
|
||||||
while (arg = args.shift)
|
while (arg = args.shift)
|
||||||
case arg
|
case arg
|
||||||
when '-h', '--help'
|
when '-h', '--help'
|
||||||
|
@ -110,6 +111,10 @@ module Msf
|
||||||
port = args.shift
|
port = args.shift
|
||||||
when '-s', '--ssl'
|
when '-s', '--ssl'
|
||||||
protocol = "https"
|
protocol = "https"
|
||||||
|
when '-c'
|
||||||
|
https_opts[:cert] = args.shift
|
||||||
|
when '--skip-verify'
|
||||||
|
https_opts[:skip_verify] = true
|
||||||
else
|
else
|
||||||
host = arg
|
host = arg
|
||||||
end
|
end
|
||||||
|
@ -121,7 +126,7 @@ module Msf
|
||||||
end
|
end
|
||||||
|
|
||||||
endpoint = "#{protocol}://#{host}:#{port}"
|
endpoint = "#{protocol}://#{host}:#{port}"
|
||||||
remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint)
|
remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint, https_opts)
|
||||||
data_service_manager = Metasploit::Framework::DataService::DataProxy.instance
|
data_service_manager = Metasploit::Framework::DataService::DataProxy.instance
|
||||||
data_service_manager.register_data_service(remote_data_service)
|
data_service_manager.register_data_service(remote_data_service)
|
||||||
end
|
end
|
||||||
|
@ -131,8 +136,10 @@ module Msf
|
||||||
print_line
|
print_line
|
||||||
print_line "OPTIONS:"
|
print_line "OPTIONS:"
|
||||||
print_line " -h, --help Show this help information."
|
print_line " -h, --help Show this help information."
|
||||||
print_line " -p <port> The port the data service is listening on. Default is 80"
|
print_line " -p <port> The port the data service is listening on. Default is 80."
|
||||||
print_line " -s, --ssl Enable SSL. Required for HTTPS data services."
|
print_line " -s, --ssl Enable SSL. Required for HTTPS data services."
|
||||||
|
print_line " -c Certificate file matching the server's certificate. Needed when using self-signed SSL cert."
|
||||||
|
print_line " --skip-verify Skip validating authenticity of server's certificate. NOT RECOMMENDED."
|
||||||
print_line
|
print_line
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue