Skip to content

Commit d10cd2d

Browse files
committed
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.
1 parent 8022294 commit d10cd2d

File tree

2 files changed

+39
-4
lines changed
  • lib
    • metasploit/framework/data_service/remote/http
    • msf/ui/console/command_dispatcher

2 files changed

+39
-4
lines changed

lib/metasploit/framework/data_service/remote/http/core.rb

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ class RemoteHTTPDataService
2222
#
2323
# @param [String] endpoint A valid http or https URL. Cannot be nil
2424
#
25-
def initialize(endpoint)
25+
def initialize(endpoint, https_opts = {})
2626
validate_endpoint(endpoint)
2727
@endpoint = URI.parse(endpoint)
28+
@https_opts = https_opts
2829
build_client_pool(5)
2930
end
3031

@@ -244,12 +245,39 @@ def build_client_pool(size)
244245
http = Net::HTTP.new(@endpoint.host, @endpoint.port)
245246
if @endpoint.is_a?(URI::HTTPS)
246247
http.use_ssl = true
247-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
248+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
249+
unless @https_opts.empty?
250+
if @https_opts[:skip_verify]
251+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
252+
else
253+
# https://stackoverflow.com/questions/22093042/implementing-https-certificate-pubkey-pinning-with-ruby
254+
user_passed_cert = OpenSSL::X509::Certificate.new(File.read(@https_opts[:cert]))
255+
256+
http.verify_callback = lambda do |preverify_ok, cert_store|
257+
server_cert = cert_store.chain[0]
258+
return true unless server_cert.to_der == cert_store.current_cert.to_der
259+
same_public_key?(server_cert, user_passed_cert)
260+
end
261+
end
262+
end
248263
end
249264
@client_pool << http
250265
}
251266
end
252267

268+
# Tells us whether the private keys on the passed certificates match
269+
# and use the same algo
270+
def same_public_key?(ref_cert, actual_cert)
271+
pkr, pka = ref_cert.public_key, actual_cert.public_key
272+
273+
# First check if the public keys use the same crypto...
274+
return false unless pkr.class == pka.class
275+
# ...and then - that they have the same contents
276+
return false unless pkr.to_pem == pka.to_pem
277+
278+
true
279+
end
280+
253281
def try_sound_effect()
254282
sound_file = ::File.join(Msf::Config.data_directory, "sounds", "Goliath_Online_Sound_Effect.wav")
255283
Rex::Compat.play_sound(sound_file)

lib/msf/ui/console/command_dispatcher/db.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ def cmd_list_data_services()
101101
def cmd_add_data_service(*args)
102102
protocol = "http"
103103
port = 80
104+
https_opts = {}
104105
while (arg = args.shift)
105106
case arg
106107
when '-h', '--help'
@@ -110,6 +111,10 @@ def cmd_add_data_service(*args)
110111
port = args.shift
111112
when '-s', '--ssl'
112113
protocol = "https"
114+
when '-c'
115+
https_opts[:cert] = args.shift
116+
when '--skip-verify'
117+
https_opts[:skip_verify] = true
113118
else
114119
host = arg
115120
end
@@ -121,7 +126,7 @@ def cmd_add_data_service(*args)
121126
end
122127

123128
endpoint = "#{protocol}://#{host}:#{port}"
124-
remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint)
129+
remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(endpoint, https_opts)
125130
data_service_manager = Metasploit::Framework::DataService::DataProxy.instance
126131
data_service_manager.register_data_service(remote_data_service)
127132
end
@@ -131,8 +136,10 @@ def cmd_add_data_service_help
131136
print_line
132137
print_line "OPTIONS:"
133138
print_line " -h, --help Show this help information."
134-
print_line " -p <port> The port the data service is listening on. Default is 80"
139+
print_line " -p <port> The port the data service is listening on. Default is 80."
135140
print_line " -s, --ssl Enable SSL. Required for HTTPS data services."
141+
print_line " -c Certificate file matching the server's certificate. Needed when using self-signed SSL cert."
142+
print_line " --skip-verify Skip validating authenticity of server's certificate. NOT RECOMMENDED."
136143
print_line
137144
end
138145

0 commit comments

Comments
 (0)