module Ronin::Support::Network::SSL
Top-level SSL
methods.
Constants
- VERIFY
SSL
verify modes- VERSIONS
SSL/TLS versions
Public Class Methods
Creates a new SSL
socket listening on a given host and port, accepts only one client and then stops listening.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {server}.
@!macro server_kwargs
@yield [client]
The given block will be passed the newly connected client. After the block has finished, both the client and the server will be closed.
@yieldparam [OpenSSL::SSL::SSLSocket] client
The newly connected client.
@return [nil]
@example
ssl_accept(1337) do |client| client.puts 'lol' end
@example Using a self-signed certificate:e
# $ openssl genrsa -out ssl.key 1024 # $ openssl req -new -key ssl.key -x509 -days 3653 -out ssl.crt # $ cat ssl.key ssl.crt > ssl.pem # $ chmod 600 ssl.key ssl.pem SSL.accept(port: 1337, cert: 'ssl.crt', key: 'ssl.key') do |client| client.puts 'lol' end
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 744 def self.accept(**kwargs) server_session(**kwargs) do |server| ssl_client = server.accept yield ssl_client if block_given? ssl_client.close end end
Overrides the default SSL
certificate.
@param [Crypto::Cert, OpenSSL::X509::Certificate] new_cert
The new SSL certificate.
@return [Crypto::Cert, OpenSSL::X509::Certificate]
The new default SSL certificate.
# File lib/ronin/support/network/ssl.rb, line 98 def self.cert=(new_cert) @cert = new_cert end
Establishes a SSL
connection.
@param [String] host
The host to connect to.
@param [Integer] port
The port to connect to.
@param [String, nil] hostname
Sets the hostname used for SNI.
@param [String] bind_host
The local host to bind to.
@param [Integer] bind_port
The local port to bind to.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {socket}.
@!macro context_kwargs
@yield [ssl_socket]
The given block will be passed the new SSL socket. Once the block returns the SSL socket will be closed.
@yieldparam [OpenSSL::SSL::SSLSocket] ssl_socket
The new SSL Socket.
@return [OpenSSL::SSL::SSLSocket, nil]
The new SSL Socket. If a block is given, then `nil` will be returned.
@example
socket = ssl_connect('twitter.com',443)
@example
ssl_connect('twitter.com',443) do |sock| sock.write("GET / HTTP/1.1\n\r\n\r") sock.each_line { |line| puts line } end
@see rubydoc.info/stdlib/openssl/OpenSSL/SSL/SSLSocket
@example
socket = SSL.connect('twitter.com',443)
@example
SSL.connect('twitter.com',443) do |sock| sock.write("GET / HTTP/1.1\n\r\n\r") sock.each_line { |line| puts line } end
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 375 def self.connect(host,port, hostname: host, bind_host: nil, bind_port: nil, **kwargs) socket = TCP.connect(host,port,bind_host: bind_host, bind_port: bind_port) ssl_socket = self.socket(socket,**kwargs) ssl_socket.hostname = hostname ssl_socket.connect if block_given? yield ssl_socket ssl_socket.close else return ssl_socket end end
Creates a new SSL
connection and sends the given data.
@param [String] data
The data to send through the connection.
@param [String] host
The host to connect to.
@param [Integer] port
The port to connect to.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {connect}.
@!macro connect_kwargs
@yield [ssl_socket]
The given block will be passed the newly created SSL Socket.
@yieldparam [OpenSSL::SSL::SSLSocket] ssl_socket
The newly created SSL Socket.
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 421 def self.connect_and_send(data,host,port,**kwargs) socket = connect(host,port,**kwargs) socket.write(data) yield socket if block_given? return socket end
Creates a new SSL
Context.
@param [1, 1.1, 1.2, 1.3, Symbol, nil] version
The SSL version to use.
@param [1, 1.1, 1.2, 1.3, Symbol, nil] min_version
The minimum SSL version to use.
@param [1, 1.1, 1.2, 1.3, Symbol, nil] max_version
The maximum SSL version to use.
@param [Symbol, Boolean] verify
Specifies whether to verify the SSL certificate. May be one of the following: * `:none` * `:peer` * `:fail_if_no_peer_cert` * `:client_once`
@param [Crypto::Key::RSA, OpenSSL::PKey::RSA, nil] key
The RSA key to use for the SSL context.
@param [String, nil] key_file
The path to the RSA `.key` file.
@param [Crypto::Cert, OpenSSL::X509::Certificate, nil] cert
The X509 certificate to use for the SSL context.
@param [String, nil] cert_file
The path to the SSL `.crt` or `.pem` file.
@param [String, nil] ca_bundle
Path to the CA bundle file or directory.
@return [OpenSSL::SSL::SSLContext]
The newly created SSL Context.
@raise [ArgumentError]
`cert_file:` or `cert:` keyword arguments also require a `key_file:` or `key:` keyword argument.
@api semipublic
@since 1.0.0
# File lib/ronin/support/network/ssl.rb, line 149 def self.context(version: nil, min_version: nil, max_version: nil, verify: :none, key: nil, key_file: nil, cert: nil, cert_file: nil, ca_bundle: nil) context = OpenSSL::SSL::SSLContext.new if version version = VERSIONS.fetch(version,version) context.min_version = context.max_version = version else min_version || max_version if min_version context.min_version = VERSIONS.fetch(min_version,min_version) end if max_version context.max_version = VERSIONS.fetch(max_version,max_version) end end context.verify_mode = VERIFY[verify] if (key_file || key) && (cert_file || cert) context.key = if key_file then Crypto::Key.load_file(key_file) else key end context.cert = if cert_file then Crypto::Cert.load_file(cert_file) else cert end elsif (key_file || key) || (cert_file || cert) raise(ArgumentError,"cert_file: and cert: keyword arguments also require a key_file: or key: keyword argument") end if ca_bundle if File.file?(ca_bundle) context.ca_file = ca_bundle elsif File.directory?(ca_bundle) context.ca_path = ca_bundle end end return context end
Connects to the host and port and returns the server’s certificate.
@param [String] host
The host to connect to.
@param [Integer] port
The port to connect to.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {connect}.
@!macro connect_kwargs
@return [Crypto::Cert]
The server's certificate.
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 450 def self.get_cert(host,port,**kwargs) socket = connect(host,port,**kwargs) cert = Crypto::Cert(socket.peer_cert) socket.close return cert end
The default RSA key used for all SSL
server sockets.
@return [Crypto::Key::RSA]
The default RSA key.
# File lib/ronin/support/network/ssl.rb, line 62 def self.key @key ||= LocalKey.fetch end
Overrides the default RSA key.
@param [Crypto::Key::RSA, OpenSSL::PKey::RSA] new_key
The new RSA key.
@return [Crypto::Key::RSA, OpenSSL::PKey::RSA]
The new default RSA key.
# File lib/ronin/support/network/ssl.rb, line 75 def self.key=(new_key) @key = new_key end
Tests whether a remote SSLed TCP
port is open.
@param [String] host
The host to connect to.
@param [Integer] port
The port to connect to.
@param [Integer] timeout (5)
The maximum time to attempt connecting.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {connect}.
@!macro connect_kwargs
@return [Boolean, nil]
Specifies whether the remote SSLed TCP port is open. If the connection was not accepted, `nil` will be returned.
@example
ssl_open?('www.bankofamerica.com',443)
@example Using a timeout:
ssl_open?('example.com',80, timeout: 5) # => nil
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 303 def self.open?(host,port, timeout: 5, **kwargs) Timeout.timeout(timeout) do connect(host,port,**kwargs) end return true rescue Timeout::Error return nil rescue SocketError, SystemCallError return false end
Connects to a specified host and port, sends the given data and then closes the connection.
@param [String] data
The data to send through the connection.
@param [String] host
The host to connect to.
@param [Integer] port
The port to connect to.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {connect}.
@!macro connect_kwargs
@return [true]
The data was successfully sent.
@example
buffer = "GET /#{'A' * 4096}\n\r" SSL.send(buffer,'victim.com',443) # => true
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 531 def self.send(data,host,port,**kwargs) connect(host,port,**kwargs) do |socket| socket.write(data) end return true end
Creates a new SSL
server listening on a given host and port.
@param [Integer] port
The local port to listen on.
@param [String, nil] host
The host to bind to.
@param [Integer] backlog (5)
The maximum backlog of pending connections.
@param [Crypto::Key::RSA, OpenSSL::PKey::RSA, nil] key
The RSA key to use for the SSL context.
@param [Crypto::Cert, OpenSSL::X509::Certificate, nil] cert
The X509 certificate to use for the SSL context.
@!macro context_kwargs
@yield [server]
The given block will be passed the newly created SSL server.
@yieldparam [OpenSSL::SSL::SSLServer] server
The newly created SSL server.
@return [OpenSSL::SSL::SSLServer]
The newly created SSL server.
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 602 def self.server(port: 0, host: nil, backlog: 5, key: Network::SSL.key, cert: Network::SSL.cert, **kwargs) context = self.context(key: key, cert: cert, **kwargs) tcp_server = TCP.server(port: port, host: host, backlog: backlog) ssl_server = OpenSSL::SSL::SSLServer.new(tcp_server,context) yield ssl_server if block_given? return ssl_server end
Creates a new SSL
socket listening on a given host and port, accepting clients in a loop.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {server}.
@!macro server_kwargs
@yield [client]
The given block will be passed the newly connected client. After the block has finished, the client will be closed.
@yieldparam [OpenSSL::SSL::SSLSocket] client
A newly connected client.
@return [nil]
@example
# $ openssl genrsa -out ssl.key 1024 # $ openssl req -new -key ssl.key -x509 -days 3653 -out ssl.crt # $ cat ssl.key ssl.crt > ssl.pem # $ chmod 600 ssl.key ssl.pem SSL.server_loop(port: 1337, cert: 'ssl.crt', key: 'ssl.key') do |sock| sock.puts 'lol' end
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 696 def self.server_loop(**kwargs) server(**kwargs) do |ssl_server| loop do ssl_client = ssl_server.accept yield ssl_client if block_given? ssl_client.close end end end
Creates a new temporary SSL
server listening on a given host and port.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {server}.
@!macro server_kwargs
@yield [server]
The given block will be passed the newly created SSL server. Once the block has finished, the server will be closed.
@yieldparam [OpenSSL::SSL::SSLServer] server
The newly created SSL server.
@return [OpenSSL::SSL::SSLServer]
The newly created SSL server.
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 659 def self.server_session(**kwargs,&block) ssl_server = self.server(**kwargs,&block) ssl_server.close return ssl_server end
Accepts an SSL
session from an existing TCP
socket.
@param [TCPSocket] socket
The existing TCP socket.
@param [Crypto::Key::RSA, OpenSSL::PKey::RSA, nil] key
The RSA key to use for the SSL context.
@param [Crypto::Cert, OpenSSL::X509::Certificate, nil] cert
The X509 certificate to use for the SSL context.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {socket}.
@!macro context_kwargs
@return [OpenSSL::SSL::SSLSocket]
The new SSL Socket.
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 563 def self.server_socket(socket, key: Network::SSL.key, cert: Network::SSL.cert, **kwargs) socket(socket, cert: cert, key: key, **kwargs) end
Initiates an SSL
session with an existing TCP
socket.
@param [TCPSocket] socket
The existing TCP socket.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {context}.
@!macro context_kwargs
@return [OpenSSL::SSL::SSLSocket]
The new SSL Socket.
@api public
@since 1.1.0
# File lib/ronin/support/network/ssl.rb, line 253 def self.socket(socket,**kwargs) ssl_socket = OpenSSL::SSL::SSLSocket.new(socket,context(**kwargs)) ssl_socket.sync_close = true return ssl_socket end