From 4635bb83c3fb0240941d961072be8241dcb1aa7f Mon Sep 17 00:00:00 2001 From: OJ Date: Mon, 6 Apr 2015 12:46:23 +1000 Subject: [PATCH 1/3] 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. --- lib/rex/post/meterpreter/client.rb | 2 + lib/rex/post/meterpreter/client_core.rb | 51 ++++++++- .../ui/console/command_dispatcher/core.rb | 106 ++++++++++++++++-- lib/rex/socket/ssl_tcp.rb | 8 +- 4 files changed, 154 insertions(+), 13 deletions(-) diff --git a/lib/rex/post/meterpreter/client.rb b/lib/rex/post/meterpreter/client.rb index fbc797f9fa..240039157e 100644 --- a/lib/rex/post/meterpreter/client.rb +++ b/lib/rex/post/meterpreter/client.rb @@ -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 diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 2749fd9d59..3fdbdb434b 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -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. diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb index 779143a060..8d9e7e8e20 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -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 diff --git a/lib/rex/socket/ssl_tcp.rb b/lib/rex/socket/ssl_tcp.rb index b55c5619c7..d5ae19feac 100644 --- a/lib/rex/socket/ssl_tcp.rb +++ b/lib/rex/socket/ssl_tcp.rb @@ -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 From 7f56c07b641beed7bc1679464a492b927427878b Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Fri, 10 Apr 2015 12:40:34 -0500 Subject: [PATCH 2/3] add missing sslhash attribute --- lib/rex/socket/ssl_tcp.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rex/socket/ssl_tcp.rb b/lib/rex/socket/ssl_tcp.rb index d5ae19feac..ff34271f91 100644 --- a/lib/rex/socket/ssl_tcp.rb +++ b/lib/rex/socket/ssl_tcp.rb @@ -366,7 +366,7 @@ 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' From 0e864e1631fb1f1c04faabb041a25f762f870988 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Fri, 10 Apr 2015 12:52:28 -0500 Subject: [PATCH 3/3] update bins to 0.0.21 --- Gemfile.lock | 4 ++-- metasploit-framework.gemspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9ef1711c7b..73d82f4482 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index c3e740faa7..c0a353afe9 100644 --- a/metasploit-framework.gemspec +++ b/metasploit-framework.gemspec @@ -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