Land #5081, meterpreter certificate hash check controls
commit
75b559eea3
|
@ -9,7 +9,7 @@ PATH
|
||||||
json
|
json
|
||||||
metasploit-concern (~> 0.3.0)
|
metasploit-concern (~> 0.3.0)
|
||||||
metasploit-model (~> 0.29.0)
|
metasploit-model (~> 0.29.0)
|
||||||
meterpreter_bins (= 0.0.18)
|
meterpreter_bins (= 0.0.21)
|
||||||
msgpack
|
msgpack
|
||||||
nokogiri
|
nokogiri
|
||||||
packetfu (= 1.1.9)
|
packetfu (= 1.1.9)
|
||||||
|
@ -132,7 +132,7 @@ GEM
|
||||||
pg
|
pg
|
||||||
railties (< 4.0.0)
|
railties (< 4.0.0)
|
||||||
recog (~> 1.0)
|
recog (~> 1.0)
|
||||||
meterpreter_bins (0.0.18)
|
meterpreter_bins (0.0.21)
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
mime-types (1.25.1)
|
mime-types (1.25.1)
|
||||||
mini_portile (0.6.2)
|
mini_portile (0.6.2)
|
||||||
|
|
|
@ -194,6 +194,7 @@ class Client
|
||||||
self.sock.extend(Rex::Socket::SslTcp)
|
self.sock.extend(Rex::Socket::SslTcp)
|
||||||
self.sock.sslsock = ssl
|
self.sock.sslsock = ssl
|
||||||
self.sock.sslctx = ctx
|
self.sock.sslctx = ctx
|
||||||
|
self.sock.sslhash = Rex::Text.sha1_raw(ctx.cert.to_der)
|
||||||
|
|
||||||
tag = self.sock.get_once(-1, 30)
|
tag = self.sock.get_once(-1, 30)
|
||||||
if(not tag or tag !~ /^GET \//)
|
if(not tag or tag !~ /^GET \//)
|
||||||
|
@ -206,6 +207,7 @@ class Client
|
||||||
self.sock.sslsock.close
|
self.sock.sslsock.close
|
||||||
self.sock.sslsock = nil
|
self.sock.sslsock = nil
|
||||||
self.sock.sslctx = nil
|
self.sock.sslctx = nil
|
||||||
|
self.sock.sslhash = nil
|
||||||
self.sock = self.sock.fd
|
self.sock = self.sock.fd
|
||||||
self.sock.extend(::Rex::Socket::Tcp)
|
self.sock.extend(::Rex::Socket::Tcp)
|
||||||
end
|
end
|
||||||
|
|
|
@ -255,7 +255,7 @@ class ClientCore < Extension
|
||||||
return Rex::Text.md5(id)
|
return Rex::Text.md5(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_transport(opts={})
|
def transport_change(opts={})
|
||||||
|
|
||||||
unless valid_transport?(opts[:transport]) && opts[:lport]
|
unless valid_transport?(opts[:transport]) && opts[:lport]
|
||||||
return false
|
return false
|
||||||
|
@ -270,7 +270,7 @@ class ClientCore < Extension
|
||||||
|
|
||||||
transport = VALID_TRANSPORTS[opts[:transport]]
|
transport = VALID_TRANSPORTS[opts[:transport]]
|
||||||
|
|
||||||
request = Packet.create_request('core_change_transport')
|
request = Packet.create_request('core_transport_change')
|
||||||
|
|
||||||
scheme = opts[:transport].split('_')[1]
|
scheme = opts[:transport].split('_')[1]
|
||||||
url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}"
|
url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}"
|
||||||
|
@ -326,6 +326,53 @@ class ClientCore < Extension
|
||||||
return true
|
return true
|
||||||
end
|
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
|
# Migrates the meterpreter instance to the process specified
|
||||||
# by pid. The connection to the server remains established.
|
# by pid. The connection to the server remains established.
|
||||||
|
|
|
@ -28,7 +28,6 @@ class Console::CommandDispatcher::Core
|
||||||
self.extensions = []
|
self.extensions = []
|
||||||
self.bgjobs = []
|
self.bgjobs = []
|
||||||
self.bgjob_id = 0
|
self.bgjob_id = 0
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@load_opts = Rex::Parser::Arguments.new(
|
@@load_opts = Rex::Parser::Arguments.new(
|
||||||
|
@ -50,7 +49,6 @@ class Console::CommandDispatcher::Core
|
||||||
"irb" => "Drop into irb scripting mode",
|
"irb" => "Drop into irb scripting mode",
|
||||||
"use" => "Deprecated alias for 'load'",
|
"use" => "Deprecated alias for 'load'",
|
||||||
"load" => "Load one or more meterpreter extensions",
|
"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",
|
"machine_id" => "Get the MSF ID of the machine attached to the session",
|
||||||
"quit" => "Terminate the meterpreter session",
|
"quit" => "Terminate the meterpreter session",
|
||||||
"resource" => "Run the commands stored in a file",
|
"resource" => "Run the commands stored in a file",
|
||||||
|
@ -67,10 +65,17 @@ class Console::CommandDispatcher::Core
|
||||||
if client.passive_service
|
if client.passive_service
|
||||||
c["detach"] = "Detach the meterpreter session (for http/https)"
|
c["detach"] = "Detach the meterpreter session (for http/https)"
|
||||||
end
|
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.
|
# Currently we have some windows-specific core commands`
|
||||||
# Use a dumb platform til it gets sorted.
|
if client.platform =~ /win/
|
||||||
#if client.commands.include? "core_migrate"
|
# 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/
|
if client.platform =~ /win/ || client.platform =~ /linux/
|
||||||
c["migrate"] = "Migrate the server to another process"
|
c["migrate"] = "Migrate the server to another process"
|
||||||
end
|
end
|
||||||
|
@ -329,6 +334,87 @@ class Console::CommandDispatcher::Core
|
||||||
print_good("Machine ID: #{client.core.machine_id}")
|
print_good("Machine ID: #{client.core.machine_id}")
|
||||||
end
|
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
|
# 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})" ],
|
'-ex' => [ true, "Expiration timout (seconds) for http(s) transports (default: #{Rex::Post::Meterpreter::ClientCore::DEFAULT_SESSION_EXPIRATION})" ],
|
||||||
'-h' => [ false, 'Help menu' ])
|
'-h' => [ false, 'Help menu' ])
|
||||||
|
|
||||||
|
#
|
||||||
|
# Display help for transport switching
|
||||||
|
#
|
||||||
def cmd_transport_help
|
def cmd_transport_help
|
||||||
print_line('Usage: transport [options]')
|
print_line('Usage: transport [options]')
|
||||||
print_line
|
print_line
|
||||||
|
@ -354,6 +443,9 @@ class Console::CommandDispatcher::Core
|
||||||
print_line(@@transport_opts.usage)
|
print_line(@@transport_opts.usage)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Change the current transport setings.
|
||||||
|
#
|
||||||
def cmd_transport(*args)
|
def cmd_transport(*args)
|
||||||
if ( args.length == 0 or args.include?("-h") )
|
if ( args.length == 0 or args.include?("-h") )
|
||||||
cmd_transport_help
|
cmd_transport_help
|
||||||
|
@ -409,7 +501,7 @@ class Console::CommandDispatcher::Core
|
||||||
end
|
end
|
||||||
|
|
||||||
print_status("Swapping transport ...")
|
print_status("Swapping transport ...")
|
||||||
if client.core.change_transport(opts)
|
if client.core.transport_change(opts)
|
||||||
client.shutdown_passive_dispatcher
|
client.shutdown_passive_dispatcher
|
||||||
shell.stop
|
shell.stop
|
||||||
else
|
else
|
||||||
|
|
|
@ -366,7 +366,11 @@ begin
|
||||||
|
|
||||||
attr_reader :peer_verified # :nodoc:
|
attr_reader :peer_verified # :nodoc:
|
||||||
attr_reader :ssl_negotiated_version # :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
|
protected
|
||||||
|
|
||||||
|
@ -377,9 +381,5 @@ protected
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
end
|
end
|
||||||
|
|
||||||
def type?
|
|
||||||
return 'tcp-ssl'
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ Gem::Specification.new do |spec|
|
||||||
# are needed when there's no database
|
# are needed when there's no database
|
||||||
spec.add_runtime_dependency 'metasploit-model', '~> 0.29.0'
|
spec.add_runtime_dependency 'metasploit-model', '~> 0.29.0'
|
||||||
# Needed for Meterpreter on Windows, soon others.
|
# 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
|
# Needed by msfgui and other rpc components
|
||||||
spec.add_runtime_dependency 'msgpack'
|
spec.add_runtime_dependency 'msgpack'
|
||||||
# Needed by anemone crawler
|
# Needed by anemone crawler
|
||||||
|
|
Loading…
Reference in New Issue