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, rc4_pad_style: :single_byte) ⇒ 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
27
# 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, rc4_pad_style: :single_byte)
  @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
  @rc4_pad_style = rc4_pad_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.”



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

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



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

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



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

def encrypt_sequence_number
  @encrypt_sequence_number
end

#encryptorObject

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

Encryption class for encrypting/decrypting messages



105
106
107
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 105

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



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

def is_initiator
  @is_initiator
end

#keyObject

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

The encryption key to use for encryption and decryption



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

def key
  @key
end

#rc4_pad_styleObject

Symbol

The RC4 spec (RFC4757) section 7.3 implies that RC4-HMAC only needs one byte of padding,

although it doesn’t come straight out and say it. Some protocols (LDAP, at least on a DC) complain if you give it more than a single byte of paddding. Other protocols (DRSR) complain if you don’t align it perfectly with an 8-byte boundary. The MS-RPCE spec is a little vague on why exactly that might be, but we can at least show empirically that it is happy if you just give it an 8-byte aligned encrypted stub. Yet other protocols are happy whatever the padding (WinRM). Here, we allow customising the behaviour of the RC4-HMAC GSSAPI crypto scheme by providing either:

  • :single_byte -> Puts a single ‘x01’ byte of padding at the end

  • :eight_byte_aligned -> Puts between 1 and 8 bytes of PKCS#5 padding



100
101
102
# File 'lib/rex/proto/gss/kerberos/message_encryptor.rb', line 100

def rc4_pad_style
  @rc4_pad_style
end

#use_acceptor_subkeyObject

Boolean

Whether the acceptor subkey is used for these operations



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

def use_acceptor_subkey
  @use_acceptor_subkey
end

Instance Method Details

#calculate_encrypted_length(plaintext_len) ⇒ Object



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

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



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

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 unless @decrypt_sequence_number.nil?

  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



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

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, rc4_pad_style: @rc4_pad_style)
  @encrypt_sequence_number += 1  
  
  result
end