class Rex::Proto::Kerberos::Client

This class is a representation of a kerberos client.

Attributes

connection[RW]

@!attribute connection

@return [IO] The connection established through Rex sockets
context[RW]

@!attribute context

@return [Hash] The Msf context where the connection belongs to
host[RW]

@!attribute host

@return [String] The kerberos server host
port[RW]

@!attribute port

@return [Fixnum] The kerberos server port
protocol[RW]

@todo Support UDP @!attribute protocol

@return [String] The transport protocol used (tcp/udp)
timeout[RW]

@!attribute timeout

@return [Fixnum] The connect / read timeout

Public Class Methods

new(opts = {}) click to toggle source
# File lib/rex/proto/kerberos/client.rb, line 27
def initialize(opts = {})
  self.host = opts[:host]
  self.port     = (opts[:port] || 88).to_i
  self.timeout  = (opts[:timeout] || 10).to_i
  self.protocol = opts[:protocol] || 'tcp'
  self.context  = opts[:context] || {}
end

Public Instance Methods

close() click to toggle source

Closes the connection

# File lib/rex/proto/kerberos/client.rb, line 55
def close
  if connection
    connection.shutdown
    connection.close unless connection.closed?
  end

  self.connection = nil
end
connect() click to toggle source

Creates a connection through a Rex socket

@return [Rex::Socket::Tcp] @raise [RuntimeError] if the connection can not be created

# File lib/rex/proto/kerberos/client.rb, line 39
def connect
  return connection if connection

  case protocol
  when 'tcp'
    self.connection = create_tcp_connection
  when 'udp'
    raise ::NotImplementedError, 'Kerberos Client: UDP not supported'
  else
    raise ::RuntimeError, 'Kerberos Client: unknown transport protocol'
  end

  connection
end
recv_response() click to toggle source

Receives a kerberos response through the connection

@return [<Rex::Proto::Kerberos::Model::KrbError, Rex::Proto::Kerberos::Model::KdcResponse>] the kerberos

response message

@raise [RuntimeError] if the connection isn't established, the transport protocol is unknown, not supported

or the response can't be parsed

@raise [NotImplementedError] if the transport protocol isn't supported

# File lib/rex/proto/kerberos/client.rb, line 93
def recv_response
  if connection.nil?
    raise ::RuntimeError, 'Kerberos Client: connection not established'
  end

  res = nil
  case protocol
  when 'tcp'
    res = recv_response_tcp
  when 'udp'
    res = recv_response_udp
  else
    raise ::RuntimeError, 'Kerberos Client: unknown transport protocol'
  end

  res
end
send_recv(req) click to toggle source

Sends a kerberos request, and reads the response through the connection

@param req [Rex::Proto::Kerberos::Model::KdcRequest] the request to send @return [<Rex::Proto::Kerberos::Model::KrbError, Rex::Proto::Kerberos::Model::KdcResponse>] The kerberos message @raise [RuntimeError] if the transport protocol is unknown or the response can't be parsed. @raise [NotImplementedError] if the transport protocol isn't supported

# File lib/rex/proto/kerberos/client.rb, line 117
def send_recv(req)
  send_request(req)
  res = recv_response

  res
end
send_request(req) click to toggle source

Sends a kerberos request through the connection

@param req [Rex::Proto::Kerberos::Model::KdcRequest] the request to send @return [Fixnum] the number of bytes sent @raise [RuntimeError] if the transport protocol is unknown @raise [NotImplementedError] if the transport protocol isn't supported

# File lib/rex/proto/kerberos/client.rb, line 70
def send_request(req)
  connect

  sent = 0
  case protocol
  when 'tcp'
    sent = send_request_tcp(req)
  when 'udp'
    sent = send_request_udp(req)
  else
    raise ::RuntimeError, 'Kerberos Client: unknown transport protocol'
  end

  sent
end

Private Instance Methods

create_tcp_connection() click to toggle source

Creates a TCP connection using Rex::Socket::Tcp

@return [Rex::Socket::Tcp]

# File lib/rex/proto/kerberos/client.rb, line 129
def create_tcp_connection
  self.connection = Rex::Socket::Tcp.create(
    'PeerHost'   => host,
    'PeerPort'   => port.to_i,
    'Context'    => context,
    'Timeout'    => timeout
  )
end
decode_kerb_response(data) click to toggle source

Decodes a Kerberos response

@param data [String] the raw response message @return [<Rex::Proto::Kerberos::Model::KrbError, Rex::Proto::Kerberos::Model::KdcResponse>] the kerberos message response @raise [RuntimeError] if the response can't be processed

# File lib/rex/proto/kerberos/client.rb, line 192
def decode_kerb_response(data)
  asn1 = OpenSSL::ASN1.decode(data)
  msg_type = asn1.value[0].value[1].value[0].value

  case msg_type
  when Rex::Proto::Kerberos::Model::KRB_ERROR
    res = Rex::Proto::Kerberos::Model::KrbError.decode(asn1)
  when Rex::Proto::Kerberos::Model::AS_REP
    res = Rex::Proto::Kerberos::Model::KdcResponse.decode(asn1)
  when Rex::Proto::Kerberos::Model::TGS_REP
    res = Rex::Proto::Kerberos::Model::KdcResponse.decode(asn1)
  else
    raise ::RuntimeError, 'Kerberos Client: Unknown response'
  end

  res
end
recv_response_tcp() click to toggle source

Receives a Kerberos Response over a tcp connection

@return [<Rex::Proto::Kerberos::Model::KrbError, Rex::Proto::Kerberos::Model::KdcResponse>] the kerberos message response @raise [RuntimeError] if the response can't be processed @raise [EOFError] if expected data can't be read

# File lib/rex/proto/kerberos/client.rb, line 161
def recv_response_tcp
  length_raw = connection.get_once(4, timeout)
  unless length_raw && length_raw.length == 4
    raise ::RuntimeError, 'Kerberos Client: failed to read response'
  end
  length = length_raw.unpack('N')[0]

  data = connection.get_once(length, timeout)
  unless data && data.length == length
    raise ::RuntimeError, 'Kerberos Client: failed to read response'
  end

  res = decode_kerb_response(data)

  res
end
recv_response_udp() click to toggle source

UDP isn't supported

@raise [NotImplementedError]

# File lib/rex/proto/kerberos/client.rb, line 181
def recv_response_udp
  raise ::NotImplementedError, 'Kerberos Client: UDP unsupported'
end
send_request_tcp(req) click to toggle source

Sends a Kerberos Request over a tcp connection

@param req [Rex::Proto::Kerberos::Model::KdcRequest] the request to send @return [Fixnum] the number of bytes sent @raise [RuntimeError] if the request can't be encoded

# File lib/rex/proto/kerberos/client.rb, line 143
def send_request_tcp(req)
  data = req.encode
  length = [data.length].pack('N')
  connection.put(length + data)
end
send_request_udp(req) click to toggle source

UDP isn't supported

@raise [NotImplementedError]

# File lib/rex/proto/kerberos/client.rb, line 152
def send_request_udp(req)
  raise ::NotImplementedError, 'Kerberos Client: UDP unsupported'
end