Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Kerberos encryption types from RFC8009 (AES HMAC-SHA2 familly) #1684

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 168 additions & 107 deletions examples/getST.py

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions examples/ticketer.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@

from impacket.krb5 import constants, pac
from impacket.krb5.asn1 import AP_REQ, TGS_REQ, Authenticator, seq_set, seq_set_iter, PA_FOR_USER_ENC, Ticket as TicketAsn1
from impacket.krb5.crypto import _HMACMD5, _AES256CTS, string_to_key
from impacket.krb5.crypto import _HMACMD5, string_to_key
from impacket.krb5.kerberosv5 import sendReceive
from impacket.krb5.types import Ticket
from impacket.winregistry import hexdump
Expand Down Expand Up @@ -125,7 +125,7 @@ def loadKeysFromKeytab(self, filename):
keytab = Keytab.loadFile(filename)
keyblock = keytab.getKey("%s@%s" % (options.spn, self.__domain))
if keyblock:
if keyblock["keytype"] == Enctype.AES256 or keyblock["keytype"] == Enctype.AES128:
if keyblock["keytype"] == Enctype.AES256_SHA1 or keyblock["keytype"] == Enctype.AES128_SHA1:
options.aesKey = keyblock.hexlifiedValue()
elif keyblock["keytype"] == Enctype.RC4:
options.nthash = keyblock.hexlifiedValue()
Expand Down Expand Up @@ -988,19 +988,19 @@ def signEncryptTicket(self, kdcRep, encASorTGSRepPart, encTicketPart, pacInfos):

checkSumFunctionServer = _checksum_table[serverChecksum['SignatureType']]
if serverChecksum['SignatureType'] == ChecksumTypes.hmac_sha1_96_aes256.value:
keyServer = Key(Enctype.AES256, unhexlify(self.__options.aesKey))
keyServer = Key(Enctype.AES256_SHA1, unhexlify(self.__options.aesKey))
elif serverChecksum['SignatureType'] == ChecksumTypes.hmac_sha1_96_aes128.value:
keyServer = Key(Enctype.AES128, unhexlify(self.__options.aesKey))
keyServer = Key(Enctype.AES128_SHA1, unhexlify(self.__options.aesKey))
elif serverChecksum['SignatureType'] == ChecksumTypes.hmac_md5.value:
keyServer = Key(Enctype.RC4, unhexlify(self.__options.nthash))
else:
raise Exception('Invalid Server checksum type 0x%x' % serverChecksum['SignatureType'])

checkSumFunctionPriv = _checksum_table[privSvrChecksum['SignatureType']]
if privSvrChecksum['SignatureType'] == ChecksumTypes.hmac_sha1_96_aes256.value:
keyPriv = Key(Enctype.AES256, unhexlify(self.__options.aesKey))
keyPriv = Key(Enctype.AES256_SHA1, unhexlify(self.__options.aesKey))
elif privSvrChecksum['SignatureType'] == ChecksumTypes.hmac_sha1_96_aes128.value:
keyPriv = Key(Enctype.AES128, unhexlify(self.__options.aesKey))
keyPriv = Key(Enctype.AES128_SHA1, unhexlify(self.__options.aesKey))
elif privSvrChecksum['SignatureType'] == ChecksumTypes.hmac_md5.value:
keyPriv = Key(Enctype.RC4, unhexlify(self.__options.nthash))
else:
Expand Down
14 changes: 11 additions & 3 deletions impacket/examples/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
target_regex = re.compile(r"(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)")


# Regular expression to parse credentials information
credential_regex = re.compile(r"(?:(?:([^/:]*)/)?([^:]*)(?::(.*))?)?")
# Regular expression to parse Active Directory credentials information
ad_credential_regex = re.compile(r"(?:(?:([^/:]*)/)?([^:]*)(?::(.*))?)?")

# Regular expression to parse standard Kerberos credentials information
krb5_credential_regex = re.compile(r"([^@:]*)@([^/@:]*)(?::(.*))?")

def parse_target(target):
""" Helper function to parse target information. The expected format is:
Expand All @@ -47,6 +49,8 @@ def parse_target(target):
def parse_credentials(credentials):
""" Helper function to parse credentials information. The expected format is:

<USERNAME@><DOMAIN><:PASSWORD>
OR
<DOMAIN></USERNAME><:PASSWORD>

:param credentials: credentials to parse
Expand All @@ -55,6 +59,10 @@ def parse_credentials(credentials):
:return: tuple of domain, username and password
:rtype: (string, string, string)
"""
domain, username, password = credential_regex.match(credentials).groups('')
res = krb5_credential_regex.match(credentials)
if res:
username, domain, password = res.groups('')
else:
domain, username, password = ad_credential_regex.match(credentials).groups('')

return domain, username, password
13 changes: 13 additions & 0 deletions impacket/krb5/asn1.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,19 @@ class PA_FOR_USER_ENC(univ.Sequence):
_sequence_optional_component('cksum', 2, Checksum()),
_sequence_optional_component('auth-package', 3, KerberosString()))

class S4UUserID(univ.Sequence):
componentType = namedtype.NamedTypes(
_sequence_component('nonce', 0, UInt32()),
_sequence_optional_component("cname", 1, PrincipalName()),
_sequence_component("crealm", 2, Realm()),
_sequence_optional_component("subject-certificate", 3, univ.OctetString()),
_sequence_optional_component('options', 4, univ.BitString()))

class PA_S4U_X509_USER(univ.Sequence):
componentType = namedtype.NamedTypes(
_sequence_component('user-id', 0, S4UUserID()),
_sequence_component('checksum', 1, Checksum()))

class KERB_ERROR_DATA(univ.Sequence):
componentType = namedtype.NamedTypes(
_sequence_component('data-type', 1, Int32()),
Expand Down
5 changes: 5 additions & 0 deletions impacket/krb5/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class PreAuthenticationDataTypes(Enum):
TD_REQ_SEQ = 108
PA_PAC_REQUEST = 128
PA_FOR_USER = 129
PA_S4U_X509_USER = 130
PA_FX_COOKIE = 133
PA_FX_FAST = 136
PA_FX_ERROR = 137
Expand Down Expand Up @@ -460,6 +461,8 @@ class EncryptionTypes(Enum):
des3_cbc_sha1_kd = 16
aes128_cts_hmac_sha1_96 = 17
aes256_cts_hmac_sha1_96 = 18
aes128_cts_hmac_sha256_128 = 19
aes256_cts_hmac_sha384_192 = 20
rc4_hmac = 23
rc4_hmac_exp = 24
subkey_keymaterial = 65
Expand All @@ -472,3 +475,5 @@ class ChecksumTypes(Enum):
hmac_sha1_des3_kd = 12
hmac_sha1_96_aes128 = 15
hmac_sha1_96_aes256 = 16
hmac_sha256_128_aes128 = 19
hmac_sha384_192_aes256 = 20
Loading
Loading