Skip to content

Commit

Permalink
test.py now has a working example. Take encrypted DsBindResponse from…
Browse files Browse the repository at this point in the history
… dcshadow wireshark decrypt it, and produces again same encrypted stuff with same signature by taking the padding bytes and the confounder from the encrypted message
  • Loading branch information
MrAle98 committed Feb 29, 2024
1 parent 82ddd83 commit 30cf541
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
9 changes: 8 additions & 1 deletion impacket/krb5/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,13 @@ def encrypt(cls, key, keyusage, plaintext, confounder):
print(f"confounder len={len(confounder)}")
hexdump.hexdump(confounder)
print(f"cls.padsize = {cls.padsize}")
print(f"cls.macsize = {cls.macsize}")
basic_plaintext = confounder + _zeropad(plaintext, cls.padsize)
print(f"basic_plaintext len={len(basic_plaintext)}")
hexdump.hexdump(basic_plaintext)
hmac = HMAC.new(ki.contents, basic_plaintext, cls.hashmod).digest()
print(f"hmac len={len(hmac)}")
hexdump.hexdump(hmac)
enc = cls.basic_encrypt(ke, basic_plaintext) + hmac[:cls.macsize]
print("returning from encrypt")
return enc
Expand All @@ -237,7 +239,12 @@ def decrypt(cls, key, keyusage, ciphertext):

print("in decrypt")
print(f"ciphertext len={len(ciphertext)}")
hexdump.hexdump(ciphertext)
dumpciphertext = None
if type(ciphertext) != type(bytearray) and type(ciphertext) != type(bytes):
dumpciphertext = bytes(ciphertext)
else:
dumpciphertext = ciphertext
hexdump.hexdump(dumpciphertext)

if len(ciphertext) < cls.blocksize + cls.macsize:
raise ValueError('ciphertext too short')
Expand Down
14 changes: 10 additions & 4 deletions impacket/krb5/gssapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,21 +253,24 @@ def GSS_Wrap(self, sessionKey, data, sequenceNumber, direction = 'init', encrypt
token = self.WRAP()
print("in GSS_Wrap")
cipher = self.cipherType()
print(f"data len={len(data)}")

if padding:
pad = len(padding)
padStr = padding
pad = len(padding)
data += padStr

else:
#Let's pad the data
pad = (cipher.blocksize - (len(data) % cipher.blocksize)) & 15
pad = (cipher.blocksize - (len(data) % cipher.blocksize)) & 16
padStr = b'\xFF' * pad
data += padStr

print(f"pad: {pad}")
print(f"cipher.blocksize: {cipher.blocksize}")
print(f"len(data) % cipher.blocksize): {len(data) % cipher.blocksize}")
print(f"padding")
hexdump.hexdump(padding)
hexdump.hexdump(padStr)
# The RRC field ([RFC4121] section 4.2.5) is 12 if no encryption is requested or 28 if encryption
# is requested. The RRC field is chosen such that all the data can be encrypted in place.
rrc = 28
Expand All @@ -285,7 +288,7 @@ def GSS_Wrap(self, sessionKey, data, sequenceNumber, direction = 'init', encrypt
hexdump.hexdump(data)
cipherText = cipher.encrypt(sessionKey, keyUsage, data + token.getData(), confounder)
print(f"cipherText len={len(cipherText)}")

hexdump.hexdump(cipherText)
token['RRC'] = rrc

cipherText = self.rotate(cipherText, token['RRC'] + token['EC'])
Expand Down Expand Up @@ -316,6 +319,9 @@ def GSS_Unwrap(self, sessionKey, data, sequenceNumber, direction = 'init', encry
print("again in GSS_Unwrap")
print(f"plaintText before unpadding {len(plainText)}")
hexdump.hexdump(plainText)
signedtoken = self.WRAP(plainText[-16:])
print(signedtoken.fields)
print(f"SND_SEQ: {int.from_bytes(signedtoken['SND_SEQ'])}")
print(f"final plainText after unpadding {len(plainText[:-(token['EC']+len(self.WRAP()))])}")
hexdump.hexdump(plainText[:-(token['EC']+len(self.WRAP()))])

Expand Down

0 comments on commit 30cf541

Please sign in to comment.