Implement ssl verification toggling
Add support to meterpreter that allows for the querying and toggling of SSL certificate verification on the fly. In order to verify that the socket was SSL-enabled, some rejigging had to be done of the type? method in the ssl socket class.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -258,7 +258,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
|
||||
@@ -273,7 +273,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]}"
|
||||
@@ -322,6 +322,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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -368,6 +368,10 @@ begin
|
||||
attr_reader :ssl_negotiated_version # :nodoc:
|
||||
attr_accessor :sslsock, :sslctx # :nodoc:
|
||||
|
||||
def type?
|
||||
return 'tcp-ssl'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_writer :peer_verified # :nodoc:
|
||||
@@ -377,9 +381,5 @@ protected
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
def type?
|
||||
return 'tcp-ssl'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user