Land #5081, meterpreter certificate hash check controls

bug/bundler_fix
Brent Cook 2015-04-14 10:46:13 -05:00
commit 75b559eea3
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
6 changed files with 158 additions and 17 deletions

View File

@ -9,7 +9,7 @@ PATH
json
metasploit-concern (~> 0.3.0)
metasploit-model (~> 0.29.0)
meterpreter_bins (= 0.0.18)
meterpreter_bins (= 0.0.21)
msgpack
nokogiri
packetfu (= 1.1.9)
@ -132,7 +132,7 @@ GEM
pg
railties (< 4.0.0)
recog (~> 1.0)
meterpreter_bins (0.0.18)
meterpreter_bins (0.0.21)
method_source (0.8.2)
mime-types (1.25.1)
mini_portile (0.6.2)

View File

@ -194,6 +194,7 @@ class Client
self.sock.extend(Rex::Socket::SslTcp)
self.sock.sslsock = ssl
self.sock.sslctx = ctx
self.sock.sslhash = Rex::Text.sha1_raw(ctx.cert.to_der)
tag = self.sock.get_once(-1, 30)
if(not tag or tag !~ /^GET \//)
@ -206,6 +207,7 @@ class Client
self.sock.sslsock.close
self.sock.sslsock = nil
self.sock.sslctx = nil
self.sock.sslhash = nil
self.sock = self.sock.fd
self.sock.extend(::Rex::Socket::Tcp)
end

View File

@ -255,7 +255,7 @@ class ClientCore < Extension
return Rex::Text.md5(id)
end
def change_transport(opts={})
def transport_change(opts={})
unless valid_transport?(opts[:transport]) && opts[:lport]
return false
@ -270,7 +270,7 @@ class ClientCore < Extension
transport = VALID_TRANSPORTS[opts[:transport]]
request = Packet.create_request('core_change_transport')
request = Packet.create_request('core_transport_change')
scheme = opts[:transport].split('_')[1]
url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}"
@ -326,6 +326,53 @@ class ClientCore < Extension
return true
end
#
# Enable the SSL certificate has verificate
#
def enable_ssl_hash_verify
# Not supported unless we have a socket with SSL enabled
return nil unless self.client.sock.type? == 'tcp-ssl'
request = Packet.create_request('core_transport_setcerthash')
hash = Rex::Text.sha1_raw(self.client.sock.sslctx.cert.to_der)
request.add_tlv(TLV_TYPE_TRANS_CERT_HASH, hash)
client.send_request(request)
return hash
end
#
# Disable the SSL certificate has verificate
#
def disable_ssl_hash_verify
# Not supported unless we have a socket with SSL enabled
return nil unless self.client.sock.type? == 'tcp-ssl'
request = Packet.create_request('core_transport_setcerthash')
# send an empty request to disable it
client.send_request(request)
return true
end
#
# Attempt to get the SSL hash being used for verificaton (if any).
#
# @return 20-byte sha1 hash currently being used for verification.
#
def get_ssl_hash_verify
# Not supported unless we have a socket with SSL enabled
return nil unless self.client.sock.type? == 'tcp-ssl'
request = Packet.create_request('core_transport_getcerthash')
response = client.send_request(request)
return response.get_tlv_value(TLV_TYPE_TRANS_CERT_HASH)
end
#
# Migrates the meterpreter instance to the process specified
# by pid. The connection to the server remains established.

View File

@ -28,7 +28,6 @@ class Console::CommandDispatcher::Core
self.extensions = []
self.bgjobs = []
self.bgjob_id = 0
end
@@load_opts = Rex::Parser::Arguments.new(
@ -50,7 +49,6 @@ class Console::CommandDispatcher::Core
"irb" => "Drop into irb scripting mode",
"use" => "Deprecated alias for 'load'",
"load" => "Load one or more meterpreter extensions",
"transport" => "Change the current transport mechanism",
"machine_id" => "Get the MSF ID of the machine attached to the session",
"quit" => "Terminate the meterpreter session",
"resource" => "Run the commands stored in a file",
@ -67,10 +65,17 @@ class Console::CommandDispatcher::Core
if client.passive_service
c["detach"] = "Detach the meterpreter session (for http/https)"
end
# The only meterp that implements this right now is native Windows and for
# whatever reason it is not adding core_migrate to its list of commands.
# Use a dumb platform til it gets sorted.
#if client.commands.include? "core_migrate"
# Currently we have some windows-specific core commands`
if client.platform =~ /win/
# only support the SSL switching for HTTPS
if client.passive_service && client.sock.type? == 'tcp-ssl'
c["ssl_verify"] = "Modify the SSL certificate verification setting"
end
c["transport"] = "Change the current transport mechanism"
end
if client.platform =~ /win/ || client.platform =~ /linux/
c["migrate"] = "Migrate the server to another process"
end
@ -329,6 +334,87 @@ class Console::CommandDispatcher::Core
print_good("Machine ID: #{client.core.machine_id}")
end
#
# Arguments for ssl verification
#
@@ssl_verify_opts = Rex::Parser::Arguments.new(
'-e' => [ false, 'Enable SSL certificate verification' ],
'-d' => [ false, 'Disable SSL certificate verification' ],
'-q' => [ false, 'Query the statis of SSL certificate verification' ],
'-h' => [ false, 'Help menu' ])
#
# Help for ssl verification
#
def cmd_ssl_verify_help
print_line('Usage: ssl_verify [options]')
print_line
print_line('Change and query the current setting for SSL verification')
print_line('Only one of the following options can be used at a time')
print_line(@@ssl_verify_opts.usage)
end
#
# Handle the SSL verification querying and setting function.
#
def cmd_ssl_verify(*args)
if ( args.length == 0 or args.include?("-h") )
cmd_ssl_verify_help
return
end
query = false
enable = false
disable = false
settings = 0
@@ssl_verify_opts.parse(args) do |opt, idx, val|
case opt
when '-q'
query = true
settings += 1
when '-e'
enable = true
settings += 1
when '-d'
disable = true
settings += 1
end
end
# Make sure only one action has been chosen
if settings != 1
cmd_ssl_verify_help
return
end
if query
hash = client.core.get_ssl_hash_verify
if hash
print_good("SSL verification is enabled. SHA1 Hash: #{hash.unpack("H*")[0]}")
else
print_good("SSL verification is disabled.")
end
elsif enable
hash = client.core.enable_ssl_hash_verify
if hash
print_good("SSL verification has been enabled. SHA1 Hash: #{hash.unpack("H*")[0]}")
else
print_error("Failed to enable SSL verification")
end
else
if client.core.disable_ssl_hash_verify
print_good('SSL verification has been disabled')
else
print_error("Failed to disable SSL verification")
end
end
end
#
# Arguments for transport switching
#
@ -347,6 +433,9 @@ class Console::CommandDispatcher::Core
'-ex' => [ true, "Expiration timout (seconds) for http(s) transports (default: #{Rex::Post::Meterpreter::ClientCore::DEFAULT_SESSION_EXPIRATION})" ],
'-h' => [ false, 'Help menu' ])
#
# Display help for transport switching
#
def cmd_transport_help
print_line('Usage: transport [options]')
print_line
@ -354,6 +443,9 @@ class Console::CommandDispatcher::Core
print_line(@@transport_opts.usage)
end
#
# Change the current transport setings.
#
def cmd_transport(*args)
if ( args.length == 0 or args.include?("-h") )
cmd_transport_help
@ -409,7 +501,7 @@ class Console::CommandDispatcher::Core
end
print_status("Swapping transport ...")
if client.core.change_transport(opts)
if client.core.transport_change(opts)
client.shutdown_passive_dispatcher
shell.stop
else

View File

@ -366,7 +366,11 @@ begin
attr_reader :peer_verified # :nodoc:
attr_reader :ssl_negotiated_version # :nodoc:
attr_accessor :sslsock, :sslctx # :nodoc:
attr_accessor :sslsock, :sslctx, :sslhash # :nodoc:
def type?
return 'tcp-ssl'
end
protected
@ -377,9 +381,5 @@ protected
rescue LoadError
end
def type?
return 'tcp-ssl'
end
end

View File

@ -64,7 +64,7 @@ Gem::Specification.new do |spec|
# are needed when there's no database
spec.add_runtime_dependency 'metasploit-model', '~> 0.29.0'
# Needed for Meterpreter on Windows, soon others.
spec.add_runtime_dependency 'meterpreter_bins', '0.0.18'
spec.add_runtime_dependency 'meterpreter_bins', '0.0.21'
# Needed by msfgui and other rpc components
spec.add_runtime_dependency 'msgpack'
# Needed by anemone crawler