Class: Rex::Proto::Gss::Kerberos::MessageEncryptor

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/proto/gss/kerberos/message_encryptor.rb

Overview

Encrypt messages according to RFC4121 (Kerberos with GSS) Performs wrapping of tokens in the GSS structure, filler bytes, rotation and sequence number tracking and verification.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key, encrypt_sequence_number, decrypt_sequence_number, is_initiator: true, use_acceptor_subkey: true, dce_style: false) ⇒ MessageEncryptor

Returns a new instance of MessageEncryptor.

Parameters:

  • key (Rex::Proto::Kerberos::Model::EncryptionKey)

    The encryption key used to perform encryption and decryption

  • encrypt_sequence_number (Integer)

    The starting sequence number used to encrypt messages

  • decrypt_sequence_number (Integer)

    The starting sequence number we expect to see when we decrypt messages

  • is_initiator (Boolean) (defaults to: true)

    Are we the initiator in this communication (used for setting flags and key usage values)

  • use_acceptor_subkey (Boolean) (defaults to: true)

    Are we using the subkey provided by the acceptor? (used for setting appropriate flags)

  • dce_style (Boolean) (defaults to: false)

    Is the format of the encrypted blob DCE-style?



18
19
20
21
22
23
24
25
26
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 18

def initialize(key, encrypt_sequence_number, decrypt_sequence_number, is_initiator: true, use_acceptor_subkey: true, dce_style: false)
  @key = key
  @encrypt_sequence_number = encrypt_sequence_number
  @decrypt_sequence_number = decrypt_sequence_number
  @is_initiator = is_initiator
  @use_acceptor_subkey = use_acceptor_subkey
  @dce_style = dce_style
  @encryptor = Rex::Proto::Kerberos::Crypto::Encryption::from_etype(key.type)
end

Instance Attribute Details

#dce_styleObject

Boolean

Whether this encryptor will be used for DCERPC purposes (since the behaviour is subtly different)

See MS-KILE 3.4.5.4.1 for details about the exception to the rule: learn.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/e94b3acd-8415-4d0d-9786-749d0c39d550

“For [MS-RPCE], the length field in the above pseudo ASN.1 header does not include the length of the concatenated data if [RFC1964] is used.”



86
87
88
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 86

def dce_style
  @dce_style
end

#decrypt_sequence_numberObject

The sequence number we expect to see after decrypting, which is expected to be incremented for each message



61
62
63
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 61

def decrypt_sequence_number
  @decrypt_sequence_number
end

#encrypt_sequence_numberObject

The sequence number to use when we are encrypting, which should be incremented for each message



56
57
58
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 56

def encrypt_sequence_number
  @encrypt_sequence_number
end

#encryptorObject

Rex::Proto::Kerberos::Crypto::*

Encryption class for encrypting/decrypting messages



91
92
93
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 91

def encryptor
  @encryptor
end

#is_initiatorObject

Are we (the encryptor) also the initiator in this interaction (vs being the Acceptor) This refers to the term used in RFC2743/RFC4121



72
73
74
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 72

def is_initiator
  @is_initiator
end

#keyObject

Rex::Proto::Kerberos::Model::EncryptionKey

The encryption key to use for encryption and decryption



66
67
68
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 66

def key
  @key
end

#use_acceptor_subkeyObject

Boolean

Whether the acceptor subkey is used for these operations



77
78
79
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 77

def use_acceptor_subkey
  @use_acceptor_subkey
end

Instance Method Details

#calculate_encrypted_length(plaintext_len) ⇒ Object



49
50
51
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 49

def calculate_encrypted_length(plaintext_len)
  encryptor.calculate_encrypted_length(plaintext_len)
end

#decrypt_and_verify(data) ⇒ Object

Decrypt a ciphertext, and verify its validity



42
43
44
45
46
47
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 42

def decrypt_and_verify(data)
  result = encryptor.gss_unwrap(data, @key, @decrypt_sequence_number, @is_initiator, use_acceptor_subkey: @use_acceptor_subkey)
  @decrypt_sequence_number += 1

  result
end

#encrypt_and_increment(data) ⇒ String, Integer

Encrypt the message, wrapping it in GSS structures, and increment the sequence number

Returns:

  • (String, Integer, Integer)

    The encrypted data, the length of its header, and the length of padding added to it prior to encryption



32
33
34
35
36
37
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 32

def encrypt_and_increment(data)
  result = encryptor.gss_wrap(data, @key, @encrypt_sequence_number, @is_initiator, use_acceptor_subkey: @use_acceptor_subkey, dce_style: @dce_style)
  @encrypt_sequence_number += 1  
  
  result
end