diff --git a/lib/rex/socket.rb b/lib/rex/socket.rb index f7597b1..cee793e 100644 --- a/lib/rex/socket.rb +++ b/lib/rex/socket.rb @@ -805,6 +805,7 @@ def initsock(params = nil) if (params) self.peerhost = params.peerhost self.peerhostname = params.peerhostname + self.sslkeylogfile = params.sslkeylogfile self.peerport = params.peerport self.localhost = params.localhost self.localport = params.localport @@ -888,6 +889,10 @@ def type? # attr_reader :peerhostname # + # The SSL key log file path. + # + attr_reader :sslkeylogfile + # # The peer port of the connected socket. # attr_reader :peerport @@ -912,7 +917,7 @@ def type? protected - attr_writer :peerhost, :peerhostname, :peerport, :localhost, :localport # :nodoc: + attr_writer :peerhost, :peerhostname, :sslkeylogfile, :peerport, :localhost, :localport # :nodoc: attr_writer :context # :nodoc: attr_writer :ipv # :nodoc: diff --git a/lib/rex/socket/parameters.rb b/lib/rex/socket/parameters.rb index 50e749e..952b49d 100644 --- a/lib/rex/socket/parameters.rb +++ b/lib/rex/socket/parameters.rb @@ -51,6 +51,8 @@ def self.from_hash(hash) # # @option hash [String] 'PeerHost' The remote host to connect to # @option hash [String] 'PeerHostname' The unresolved remote hostname, used to specify Server Name Indication (SNI) + # @option hash [String] 'SSLKeyLogFile' The SSL key log file path, used for network capture + # decryption which is useful to decrypt TLS traffic in wireshark # @option hash [String] 'PeerAddr' (alias for 'PeerHost') # @option hash [Fixnum] 'PeerPort' The remote port to connect to # @option hash [String] 'LocalHost' The local host to communicate from, if any @@ -116,6 +118,10 @@ def initialize(hash = {}) self.sslctx = hash['SSLContext'] end + if (hash['SSLKeyLogFile']) + self.sslkeylogfile = hash['SSLKeyLogFile'] + end + self.ssl_version = hash.fetch('SSLVersion', nil) supported_ssl_verifiers = %W{CLIENT_ONCE FAIL_IF_NO_PEER_CERT NONE PEER} @@ -302,6 +308,11 @@ def v6? # @return [String] attr_accessor :peerhostname + # The SSL key log file path, equivalent to the sslkeylogfile parameter hash + # key. + # @return [String] + attr_accessor :sslkeylogfile + # The remote port. Equivalent to the PeerPort parameter hash key. # @return [Fixnum] attr_writer :peerport diff --git a/lib/rex/socket/ssl_tcp.rb b/lib/rex/socket/ssl_tcp.rb index c8aed31..10f512e 100644 --- a/lib/rex/socket/ssl_tcp.rb +++ b/lib/rex/socket/ssl_tcp.rb @@ -84,6 +84,20 @@ def initsock_with_ssl_version(params, version) # Build the SSL connection self.sslctx = OpenSSL::SSL::SSLContext.new(version) + # writing to the sslkeylogfile is required, it adds support for network capture decryption which is useful to + # decrypt TLS traffic in wireshark + if sslkeylogfile + unless self.sslctx.respond_to?(:keylog_cb) + raise 'Unable to create sslkeylogfile - Ruby 3.2 or above required for this functionality' + end + + self.sslctx.keylog_cb = proc do |_sock, line| + File.open(sslkeylogfile, 'ab') do |file| + file.write("#{line}\n") + end + end + end + # Configure client certificate if params and params.ssl_client_cert self.sslctx.cert = OpenSSL::X509::Certificate.new(params.ssl_client_cert)