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

NTLM History extraction from ntds.dit fails when "Win2016 TP4 decryption" is used #656

Closed
crackmeifyoucan opened this issue Jul 30, 2019 · 6 comments

Comments

@crackmeifyoucan
Copy link

I believe I have found an issue with using secretsdump.py with a NTDS.dit that is from a Windows 2016 Server. When we would dump the histories hashes, they would not crack. But the current hashes would crack.

I believe I found a problem in impacket/impacket/examples/secretsdump.py around line 2142

The code checks to see if the header starts with 1300, if it finds it, it should run a CRYPTED_HASHW16 against the value. But it does not.

By simply adding a single line of:

encryptedNTHistory = self.CRYPTED_HASHW16(unhexlify(record[self.NAME_TO_INTERNAL['ntPwdHistory']]))

you can fix it (at line 2142)

            if record[self.NAME_TO_INTERNAL['ntPwdHistory']] is not None:
                encryptedNTHistory = self.CRYPTED_HISTORY(unhexlify(record[self.NAME_TO_INTERNAL['ntPwdHistory']]))

                if encryptedNTHistory['Header'][:4] == b'\x13\x00\x00\x00':
                    # Win2016 TP4 decryption is different
                    encryptedNTHistory = self.CRYPTED_HASHW16(unhexlify(record[self.NAME_TO_INTERNAL['ntPwdHistory']]))
                    pekIndex = hexlify(encryptedNTHistory['Header'])
                    tmpNTHistory = self.__cryptoCommon.decryptAES(self.__PEK[int(pekIndex[8:10])],
                                                                  encryptedNTHistory['EncryptedHash'],
                                                                  encryptedNTHistory['KeyMaterial'])
                else:
                    tmpNTHistory = self.__removeRC4Layer(encryptedNTHistory)

Minga (KoreLogic)
@crackmeifyoucan

@crackmeifyoucan
Copy link
Author

Side note:

I do not know if the function __decryptSupplementalInfo needs a similar fix. It appears to be missing a CRYPTED_HASHW16 call as well. But I haven't tested that theory.

@crackmeifyoucan
Copy link
Author

crackmeifyoucan commented Jul 30, 2019

Just noticed, my patch needs work because it only works with one history entry, and then fails on the rest.

[-] Error while processing row for user [santized]
[-] b2a_hex() argument 1 must be string or buffer, not None

@joswr1ght
Copy link

Any progress on this issue? I can reproduce this issue where password hash history content is incorrectly extracted from NTDS.dit/ntdsutil dumps.

@Hyperjag
Copy link

I think I found a fix for this issue by building on crackmeifyoucan's change. I dumped the password history from an NTDS.dit where I knew four of an account's previous passwords and all cracked successfully. I'm not sure if the fix is universal as I only had one NTDS database to test with. If it seems to work for others, I can submit a PR.

The changes involve adding a new data structure class, then using that to store the encryptedNTHistory.

After the class CRYPTED_HISTORY(Structure) definition that is around line 1799, add class CRYPTED_HISTORYW16(Structure):

class CRYPTED_HISTORY(Structure):
    structure = (
        ('Header','8s=b""'),
        ('KeyMaterial','16s=b""'),
        ('EncryptedHash',':'),
    )

class CRYPTED_HISTORYW16(Structure):
    structure = (
        ('Header','8s=b""'),
        ('KeyMaterial','16s=b""'),
        ('Unknown','<L=0'),
        ('EncryptedHash',':'),
    )

class CRYPTED_BLOB(Structure):
    structure = (
        ('Header','8s=b""'),
        ('KeyMaterial','16s=b""'),
        ('EncryptedHash',':'),
    )

Finally, around what is originally line 2142, add the line encryptedNTHistory = self.CRYPTED_HISTORYW16(unhexlify(record[self.NAME_TO_INTERNAL['ntPwdHistory']]))

                if encryptedNTHistory['Header'][:4] == b'\x13\x00\x00\x00':
                    # Win2016 TP4 decryption is different
                    encryptedNTHistory = self.CRYPTED_HISTORYW16(unhexlify(record[self.NAME_TO_INTERNAL['ntPwdHistory']]))
                    pekIndex = hexlify(encryptedNTHistory['Header'])

@0xdeaddood
Copy link
Collaborator

Hi folks! I created this PR-> #783 that addresses the issue using the solution suggested by @crackmeifyoucan and @Hyperjag. Please check it and let me know if everything it's OK. Thanks for the collaboration guys!!

@asolino
Copy link
Collaborator

asolino commented Mar 9, 2020

Closing as fixed.

@asolino asolino closed this as completed Mar 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants