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
James Barnett 2018-01-22 18:08:16 -06:00
parent 8022294d1d
commit d10cd2d92a
No known key found for this signature in database
GPG Key ID: 647983861A4EC5EA
2 changed files with 39 additions and 4 deletions

View File

@ -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)

View 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