示例#1
0
	def __decryptHash(self, record):
		# logging.debug('Decrypting hash for user: %s' % record[self.NAME_TO_INTERNAL['name']])
		
		sid = SAMR_RPC_SID(record[self.NAME_TO_INTERNAL['objectSid']].decode('hex'))
		rid = sid.formatCanonical().split('-')[-1]

		if record[self.NAME_TO_INTERNAL['dBCSPwd']] is not None:
			encryptedLMHash = self.CRYPTED_HASH(record[self.NAME_TO_INTERNAL['dBCSPwd']].decode('hex'))
			tmpLMHash = self.__removeRC4Layer(encryptedLMHash)
			LMHash = self.__removeDESLayer(tmpLMHash, rid)
		else:
			LMHash = ntlm.LMOWFv1('','')
			encryptedLMHash = None

		if record[self.NAME_TO_INTERNAL['unicodePwd']] is not None:
			encryptedNTHash = self.CRYPTED_HASH(record[self.NAME_TO_INTERNAL['unicodePwd']].decode('hex'))
			tmpNTHash = self.__removeRC4Layer(encryptedNTHash)
			NTHash = self.__removeDESLayer(tmpNTHash, rid)
		else:
			NTHash = ntlm.NTOWFv1('','')
			encryptedNTHash = None

		if record[self.NAME_TO_INTERNAL['userPrincipalName']] is not None:
			domain = record[self.NAME_TO_INTERNAL['userPrincipalName']].split('@')[-1]
			userName = '******' % (domain, record[self.NAME_TO_INTERNAL['sAMAccountName']])
		else: 
			userName = '******' % record[self.NAME_TO_INTERNAL['sAMAccountName']]
 
		answer =  "%s:%s:%s:%s:::" % (userName, rid, LMHash.encode('hex'), NTHash.encode('hex'))
		self.__hashesFound[record[self.NAME_TO_INTERNAL['objectSid']].decode('hex')] = answer
		# print answer
	  
		if self.__history:
			LMHistory = []
			NTHistory = []
			if record[self.NAME_TO_INTERNAL['lmPwdHistory']] is not None:
				lmPwdHistory = record[self.NAME_TO_INTERNAL['lmPwdHistory']]
				encryptedLMHistory = self.CRYPTED_HISTORY(record[self.NAME_TO_INTERNAL['lmPwdHistory']].decode('hex'))
				tmpLMHistory = self.__removeRC4Layer(encryptedLMHistory)
				for i in range(0, len(tmpLMHistory)/16):
					LMHash = self.__removeDESLayer(tmpLMHistory[i*16:(i+1)*16], rid)
					LMHistory.append(LMHash)

			if record[self.NAME_TO_INTERNAL['ntPwdHistory']] is not None:
				ntPwdHistory = record[self.NAME_TO_INTERNAL['ntPwdHistory']]
				encryptedNTHistory = self.CRYPTED_HISTORY(record[self.NAME_TO_INTERNAL['ntPwdHistory']].decode('hex'))
				tmpNTHistory = self.__removeRC4Layer(encryptedNTHistory)
				for i in range(0, len(tmpNTHistory)/16):
					NTHash = self.__removeDESLayer(tmpNTHistory[i*16:(i+1)*16], rid)
					NTHistory.append(NTHash)

			for i, (LMHash, NTHash) in enumerate(map(lambda l,n: (l,n) if l else ('',n), LMHistory[1:], NTHistory[1:])):
				if self.__noLMHash:
					lmhash = ntlm.LMOWFv1('','').encode('hex')
				else:
					lmhash = LMHash.encode('hex')
			
				answer =  "%s_history%d:%s:%s:%s:::" % (userName, i, rid, lmhash, NTHash.encode('hex'))
				self.__hashesFound[record[self.NAME_TO_INTERNAL['objectSid']].decode('hex')+str(i)] = answer
示例#2
0
    def dump(self):
        NTPASSWORD = "******"
        LMPASSWORD = "******"

        if self.__samFile is None:
            # No SAM file provided
            return

        self.getHBootKey()
        usersKey = 'SAM\\Domains\\Account\\Users'

        # Enumerate all the RIDs
        rids = self.enumKey(usersKey)
        # Remove the Names item
        try:
            rids.remove('Names')
        except:
            pass

        for rid in rids:
            userAccount = USER_ACCOUNT_V(
                self.getValue(ntpath.join(usersKey, rid, 'V'))[1])
            rid = int(rid, 16)

            baseOffset = len(USER_ACCOUNT_V())

            V = userAccount['Data']

            userName = V[userAccount['NameOffset']:userAccount['NameOffset'] +
                         userAccount['NameLength']].decode('utf-16le')

            if userAccount['LMHashLength'] == 20:
                encLMHash = V[userAccount['LMHashOffset'] +
                              4:userAccount['LMHashOffset'] +
                              userAccount['LMHashLength']]
            else:
                encLMHash = ''

            if userAccount['NTHashLength'] == 20:
                encNTHash = V[userAccount['NTHashOffset'] +
                              4:userAccount['NTHashOffset'] +
                              userAccount['NTHashLength']]
            else:
                encNTHash = ''

            lmHash = self.__decryptHash(rid, encLMHash, LMPASSWORD)
            ntHash = self.__decryptHash(rid, encNTHash, NTPASSWORD)

            if lmHash == '':
                lmHash = ntlm.LMOWFv1('', '')
            if ntHash == '':
                ntHash = ntlm.NTOWFv1('', '')

            answer = "%s:%d:%s:%s:::" % (userName, rid, lmHash.encode('hex'),
                                         ntHash.encode('hex'))
            self.__itemsFound[rid] = answer

        return self.__itemsFound
示例#3
0
    def test_NetrLogonSamLogonWithFlags(self):
        dce, rpctransport = self.connect()
        request = nrpc.NetrLogonSamLogonWithFlags()
        request['LogonServer'] = '\x00'
        request['ComputerName'] = self.serverName + '\x00'
        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation']['LogonInteractive']['Identity'][
            'LogonDomainName'] = self.domain
        request['LogonInformation']['LogonInteractive']['Identity'][
            'ParameterControl'] = 2 + 2**14 + 2**7 + 2**9 + 2**5 + 2**11
        request['LogonInformation']['LogonInteractive']['Identity'][
            'UserName'] = self.username
        request['LogonInformation']['LogonInteractive']['Identity'][
            'Workstation'] = ''
        if len(self.hashes) > 0:
            lmhash, nthash = self.hashes.split(':')
            lmhash = unhexlify(lmhash)
            nthash = unhexlify(nthash)
        else:
            lmhash = ntlm.LMOWFv1(self.password)
            nthash = ntlm.NTOWFv1(self.password)

        try:
            from Cryptodome.Cipher import ARC4
        except Exception:
            print(
                "Warning: You don't have any crypto installed. You need pycryptodomex"
            )
            print("See https://pypi.org/project/pycryptodomex/")

        rc4 = ARC4.new(self.sessionKey)
        lmhash = rc4.encrypt(lmhash)
        rc4 = ARC4.new(self.sessionKey)
        nthash = rc4.encrypt(nthash)

        request['LogonInformation']['LogonInteractive'][
            'LmOwfPassword'] = lmhash
        request['LogonInformation']['LogonInteractive'][
            'NtOwfPassword'] = nthash
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4
        request['Authenticator'] = self.update_authenticator()
        request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
        request['ReturnAuthenticator']['Timestamp'] = 0
        request['ExtraFlags'] = 0
        try:
            resp = dce.request(request)
            resp.dump()
        except Exception as e:
            if str(e).find('STATUS_NO_SUCH_USER') < 0:
                raise
示例#4
0
    def test_NetrLogonSamLogon(self):
        dce, rpctransport = self.connect()
        self.authenticate(dce)
        request = nrpc.NetrLogonSamLogon()
        request['LogonServer'] = self.serverName + '\x00'
        request['ComputerName'] = self.machine_user + '\x00'
        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation']['LogonInteractive']['Identity'][
            'LogonDomainName'] = self.domain
        request['LogonInformation']['LogonInteractive']['Identity'][
            'ParameterControl'] = 2
        request['LogonInformation']['LogonInteractive']['Identity'][
            'UserName'] = self.username
        request['LogonInformation']['LogonInteractive']['Identity'][
            'Workstation'] = ''
        if len(self.hashes):
            blmhash = self.blmhash
            bnthash = self.bnthash
        else:
            blmhash = ntlm.LMOWFv1(self.password)
            bnthash = ntlm.NTOWFv1(self.password)

        try:
            from Cryptodome.Cipher import ARC4
        except Exception:
            print(
                "Warning: You don't have any crypto installed. You need PyCrypto"
            )
            print("See http://www.pycrypto.org/")

        rc4 = ARC4.new(self.sessionKey)
        blmhash = rc4.encrypt(blmhash)
        rc4 = ARC4.new(self.sessionKey)
        bnthash = rc4.encrypt(bnthash)

        request['LogonInformation']['LogonInteractive'][
            'LmOwfPassword'] = blmhash
        request['LogonInformation']['LogonInteractive'][
            'NtOwfPassword'] = bnthash
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo2
        request['Authenticator'] = self.update_authenticator()
        request['ReturnAuthenticator']['Credential'] = b'\x00' * 8
        request['ReturnAuthenticator']['Timestamp'] = 0

        try:
            dce.request(request)
        except DCERPCException as e:
            if str(e).find('STATUS_NO_SUCH_USER') < 0:
                raise
    def test_NetrLogonSamLogon(self):
        dce, rpctransport = self.connect()
        request = nrpc.NetrLogonSamLogon()
        request['LogonServer'] = '\x00'
        request['ComputerName'] = self.serverName + '\x00'
        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation']['LogonInteractive']['Identity'][
            'LogonDomainName'] = self.domain
        request['LogonInformation']['LogonInteractive']['Identity'][
            'ParameterControl'] = 2
        request['LogonInformation']['LogonInteractive']['Identity'][
            'UserName'] = self.username
        request['LogonInformation']['LogonInteractive']['Identity'][
            'Workstation'] = ''
        if len(self.hashes) > 0:
            lmhash, nthash = self.hashes.split(':')
            lmhash = lmhash.decode('hex')
            nthash = nthash.decode('hex')
        else:
            lmhash = ntlm.LMOWFv1(self.password)
            nthash = ntlm.NTOWFv1(self.password)

        try:
            from Crypto.Cipher import ARC4
        except Exception:
            print "Warning: You don't have any crypto installed. You need PyCrypto"
            print "See http://www.pycrypto.org/"

        from impacket import crypto
        rc4 = ARC4.new(self.sessionKey)
        lmhash = rc4.encrypt(lmhash)
        rc4 = ARC4.new(self.sessionKey)
        nthash = rc4.encrypt(nthash)

        request['LogonInformation']['LogonInteractive'][
            'LmOwfPassword'] = lmhash
        request['LogonInformation']['LogonInteractive'][
            'NtOwfPassword'] = nthash
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo2
        request['Authenticator'] = self.update_authenticator()
        request['ReturnAuthenticator']['Credential'] = '\x00' * 8
        request['ReturnAuthenticator']['Timestamp'] = 0
        try:
            resp = dce.request(request)
            resp.dump()
        except Exception, e:
            if str(e).find('STATUS_NO_SUCH_USER') < 0:
                raise
示例#6
0
    def test_NetrLogonSamLogonEx(self):
        dce, rpctransport = self.connect()
        self.authenticate(dce)
        request = nrpc.NetrLogonSamLogonEx()
        request['LogonServer'] = self.serverName + '\x00'
        request['ComputerName'] = self.machine_user + '\x00'
        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation']['LogonInteractive']['Identity'][
            'LogonDomainName'] = self.domain
        request['LogonInformation']['LogonInteractive']['Identity'][
            'ParameterControl'] = 2 + 2**14 + 2**7 + 2**9 + 2**5 + 2**11
        request['LogonInformation']['LogonInteractive']['Identity'][
            'UserName'] = self.username
        request['LogonInformation']['LogonInteractive']['Identity'][
            'Workstation'] = ''

        if len(self.hashes):
            blmhash = self.blmhash
            bnthash = self.bnthash
        else:
            blmhash = ntlm.LMOWFv1(self.password)
            bnthash = ntlm.NTOWFv1(self.password)
        try:
            from Cryptodome.Cipher import ARC4
        except Exception:
            print(
                "Warning: You don't have any crypto installed. You need pycryptodomex"
            )
            print("See https://pypi.org/project/pycryptodomex/")

        rc4 = ARC4.new(self.sessionKey)
        blmhash = rc4.encrypt(blmhash)
        rc4 = ARC4.new(self.sessionKey)
        bnthash = rc4.encrypt(bnthash)

        request['LogonInformation']['LogonInteractive'][
            'LmOwfPassword'] = blmhash
        request['LogonInformation']['LogonInteractive'][
            'NtOwfPassword'] = bnthash
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4
        request['ExtraFlags'] = 1

        try:
            dce.request(request)
        except DCERPCException as e:
            if str(e).find('STATUS_INTERNAL_ERROR') < 0:
                raise
    def test_NetrLogonSamLogonEx(self):
        dce, rpctransport = self.connect()
        request = nrpc.NetrLogonSamLogonEx()
        request['LogonServer'] = '\x00'
        request['ComputerName'] = self.serverName + '\x00'
        request[
            'LogonLevel'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation'][
            'tag'] = nrpc.NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation
        request['LogonInformation']['LogonInteractive']['Identity'][
            'LogonDomainName'] = self.domain
        request['LogonInformation']['LogonInteractive']['Identity'][
            'ParameterControl'] = 2 + 2**14 + 2**7 + 2**9 + 2**5 + 2**11
        request['LogonInformation']['LogonInteractive']['Identity'][
            'UserName'] = self.username
        request['LogonInformation']['LogonInteractive']['Identity'][
            'Workstation'] = ''
        if len(self.hashes) > 0:
            lmhash, nthash = self.hashes.split(':')
            lmhash = lmhash.decode('hex')
            nthash = nthash.decode('hex')
        else:
            lmhash = ntlm.LMOWFv1(self.password)
            nthash = ntlm.NTOWFv1(self.password)
        try:
            from Crypto.Cipher import ARC4
        except Exception:
            print "Warning: You don't have any crypto installed. You need PyCrypto"
            print "See http://www.pycrypto.org/"

        from impacket import crypto
        rc4 = ARC4.new(self.sessionKey)
        lmhash = rc4.encrypt(lmhash)
        rc4 = ARC4.new(self.sessionKey)
        nthash = rc4.encrypt(nthash)

        request['LogonInformation']['LogonInteractive'][
            'LmOwfPassword'] = lmhash
        request['LogonInformation']['LogonInteractive'][
            'NtOwfPassword'] = nthash
        request[
            'ValidationLevel'] = nrpc.NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4
        request['ExtraFlags'] = 1
        resp = dce.request(request)
        resp.dump()
示例#8
0
    def dumpSAM(self):
        NTPASSWORD = b"NTPASSWORD\0"
        LMPASSWORD = b"LMPASSWORD\0"

        if self.__samFile is None:
            # No SAM file provided
            return

        logger.info('Dumping local SAM hashes (uid:rid:lmhash:nthash)')
        self.getHBootKey()
        usersKey = 'SAM\\Domains\\Account\\Users'

        # Enumerate all the RIDs
        rids = self.enumKey(usersKey)
        # Remove the Names item
        try:
            rids.remove('Names')
        except:
            pass
        for rid in rids:
            try:
                userAccount = USER_ACCOUNT_V(
                    self.getValue(ntpath.join(usersKey, rid, 'V'))[1])
                rid = int(rid, 16)
                logger.debug("Dumping %s from SAM" % str(rid))

                V = userAccount['Data']

                userName = V[
                    userAccount['NameOffset']:userAccount['NameOffset'] +
                    userAccount['NameLength']].decode('utf-16le')

                encNTHash = b''
                if V[userAccount['NTHashOffset']:][2:3] == b'\x01':
                    # Old Style hashes
                    newStyle = False
                    logger.debug('NewStyle hashes is: %s' % newStyle)
                    if userAccount['LMHashLength'] == 20:
                        encLMHash = SAM_HASH(V[userAccount['LMHashOffset']:]
                                             [:userAccount['LMHashLength']])
                    if userAccount['NTHashLength'] == 20:
                        encNTHash = SAM_HASH(V[userAccount['NTHashOffset']:]
                                             [:userAccount['NTHashLength']])
                else:
                    # New Style hashes
                    newStyle = True
                    logger.debug('NewStyle hashes is: %s' % newStyle)
                    if userAccount['LMHashLength'] == 24:
                        encLMHash = SAM_HASH_AES(
                            V[userAccount['LMHashOffset']:]
                            [:userAccount['LMHashLength']])
                    encNTHash = SAM_HASH_AES(V[userAccount['NTHashOffset']:]
                                             [:userAccount['NTHashLength']])

                if userAccount['LMHashLength'] >= 20:
                    lmHash = self.__decryptHash(rid, encLMHash, LMPASSWORD,
                                                newStyle)
                else:
                    lmHash = b''

                if encNTHash != b'':
                    ntHash = self.__decryptHash(rid, encNTHash, NTPASSWORD,
                                                newStyle)
                else:
                    ntHash = b''

                if lmHash == b'':
                    lmHash = ntlm.LMOWFv1('', '')
                if ntHash == b'':
                    ntHash = ntlm.NTOWFv1('', '')

                answer = "%s:%d:%s:%s:::" % (userName, rid,
                                             hexlify(lmHash).decode('utf-8'),
                                             hexlify(ntHash).decode('utf-8'))
                self.__itemsFound[rid] = answer
                self.__perSecretCallback(answer)
            except Exception as e:
                logger.error('Error encountered when dumping SAM for user ' +
                             userName + ': ' + str(e))
示例#9
0
    def test_ntlmv1(self):
        print("####### 4.2.2 NTLMv1 Authentication")
        ntlm.USE_NTLMv2 = False
        print("4.2.2.1 LMOWFv1()")
        res = ntlm.LMOWFv1(self.password)
        hexdump(res)
        self.assertTrue(
            res == bytearray(b'\xe5,\xacgA\x9a\x9a"J;\x10\x8f?\xa6\xcbm'))
        print("\n")
        print("4.2.2.1.2 NTOWFv1()")
        res = ntlm.NTOWFv1(self.password)
        hexdump(res)
        self.assertTrue(res == bytearray(
            b'\xa4\xf4\x9c\x40\x65\x10\xbd\xca\xb6\x82\x4e\xe7\xc3\x0f\xd8\x52'
        ))
        print("\n")
        print("4.2.2.1.3 Session Base Key and Key Exchange Key")
        ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(
            int(self.flags), self.serverChallenge, self.clientChallenge,
            self.serverName, self.domain, self.user, self.password, '', '')
        hexdump(sessionBaseKey)
        self.assertTrue(sessionBaseKey == bytearray(
            b'\xD8\x72\x62\xB0\xCD\xE4\xB1\xCB\x74\x99\xBE\xCC\xCD\xF1\x07\x84'
        ))
        print("\n")
        print("4.2.2.2.1 NTLMv1 Response")
        hexdump(ntResponse)
        self.assertTrue(ntResponse == bytearray(
            b'\x67\xC4\x30\x11\xF3\x02\x98\xA2\xAD\x35\xEC\xE6\x4F\x16\x33\x1C\x44\xBD\xBE\xD9\x27\x84\x1F\x94'
        ))
        print("\n")
        print("4.2.2.2.2 LMv1 Response")
        hexdump(lmResponse)
        self.assertTrue(lmResponse == bytearray(
            b'\x98\xDE\xF7\xB8\x7F\x88\xAA\x5D\xAF\xE2\xDF\x77\x96\x88\xA1\x72\xde\xf1\x1c\x7d\x5c\xcd\xef\x13'
        ))
        print("\n")
        print("4.2.2.2.2 LMv1 Response with NTLMSSP_NEGOTIATE_LM_KEY set")
        flags2 = self.flags
        #flags2 = flags | ntlm.NTLMSSP_LM_KEY
        #hexdump(struct.pack('<L',flags2))
        ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(
            int(flags2), self.serverChallenge, self.clientChallenge,
            self.serverName, self.domain, self.user, self.password, '', '')
        hexdump(lmResponse)
        print("\n")
        print("4.2.2.2.3 Encrypted Session Key ")
        ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(
            int(self.flags), self.serverChallenge, self.clientChallenge,
            self.serverName, self.domain, self.user, self.password, '', '')
        keyExchangeKey = ntlm.KXKEY(self.flags, sessionBaseKey, lmResponse,
                                    self.serverChallenge, self.password, '',
                                    '')
        encryptedSessionKey = ntlm.generateEncryptedSessionKey(
            keyExchangeKey, self.randomSessionKey)
        hexdump(encryptedSessionKey)
        self.assertTrue(encryptedSessionKey == bytearray(
            b'\x51\x88\x22\xB1\xB3\xF3\x50\xC8\x95\x86\x82\xEC\xBB\x3E\x3C\xB7'
        ))
        print("\n")
        print("4.2.2.2.3 Encrypted Session Key (NTLMSSP_NON_NT_KEY)")
        flags2 = self.flags | ntlm.NTLMSSP_REQUEST_NON_NT_SESSION_KEY
        keyExchangeKey = ntlm.KXKEY(flags2, sessionBaseKey, lmResponse,
                                    self.serverChallenge, self.password, '',
                                    '')
        encryptedSessionKey = ntlm.generateEncryptedSessionKey(
            keyExchangeKey, self.randomSessionKey)
        hexdump(encryptedSessionKey)
        #ToDo Fix this
        #self.assertTrue(encryptedSessionKey==bytearray(b'\x74\x52\xca\x55\xc2\x25\xa1\xca\x04\xb4\x8f\xae\x32\xcf\x56\xfc'))
        print("\n")
        print("4.2.2.2.3 Encrypted Session Key (NTLMSSP_LM_KEY)")
        flags2 = self.flags | ntlm.NTLMSSP_NEGOTIATE_LM_KEY
        #hexdump(struct.pack('<L',flags2))
        keyExchangeKey = ntlm.KXKEY(flags2, sessionBaseKey, lmResponse,
                                    self.serverChallenge, self.password, '',
                                    '')
        encryptedSessionKey = ntlm.generateEncryptedSessionKey(
            keyExchangeKey, self.randomSessionKey)
        hexdump(encryptedSessionKey)
        #ToDo Fix this
        #self.assertTrue(encryptedSessionKey==bytearray(b'\x4c\xd7\xbb\x57\xd6\x97\xef\x9b\x54\x9f\x02\xb8\xf9\xb3\x78\x64')
        print("\n")
        print("4.2.2.3 AUTHENTICATE MESSAGE")
        ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(
            int(self.flags), self.serverChallenge, self.clientChallenge,
            self.serverName, self.domain, self.user, self.password, '', '')
        keyExchangeKey = ntlm.KXKEY(self.flags, sessionBaseKey, lmResponse,
                                    self.serverChallenge, self.password, '',
                                    '')
        encryptedSessionKey = ntlm.generateEncryptedSessionKey(
            keyExchangeKey, self.randomSessionKey)
        ntlmChallengeResponse = ntlm.NTLMAuthChallengeResponse(
            self.user, self.password, self.serverChallenge)
        ntlmChallengeResponse['flags'] = flags2
        ntlmChallengeResponse['host_name'] = self.workstationName.encode(
            'utf-16le')
        ntlmChallengeResponse['domain_name'] = self.domain.encode('utf-16le')
        ntlmChallengeResponse['lanman'] = lmResponse
        ntlmChallengeResponse['ntlm'] = ntResponse
        ntlmChallengeResponse['session_key'] = encryptedSessionKey
        hexdump(ntlmChallengeResponse.getData())
        self.assertTrue(ntlmChallengeResponse.getData() == bytearray(
            b'NTLMSSP\x00\x03\x00\x00\x00\x18\x00\x18\x00|\x00\x00\x00\x18\x00\x18\x00\x94\x00\x00\x00\x0c\x00\x0c\x00X\x00\x00\x00\x08\x00\x08\x00d\x00\x00\x00\x10\x00\x10\x00l\x00\x00\x00\x10\x00\x10\x00\xac\x00\x00\x00\xb3\x82\x02\xe2D\x00o\x00m\x00a\x00i\x00n\x00U\x00s\x00e\x00r\x00C\x00O\x00M\x00P\x00U\x00T\x00E\x00R\x00\x98\xde\xf7\xb8\x7f\x88\xaa]\xaf\xe2\xdfw\x96\x88\xa1r\xde\xf1\x1c}\\\xcd\xef\x13g\xc40\x11\xf3\x02\x98\xa2\xad5\xec\xe6O\x163\x1cD\xbd\xbe\xd9\'\x84\x1f\x94Q\x88"\xb1\xb3\xf3P\xc8\x95\x86\x82\xec\xbb><\xb7'
        ))
        print("\n")

        print("4.2.2.4 GSS_WrapEx")
        print("Output of SEAL()")
        from Cryptodome.Cipher import ARC4
        cipher = ARC4.new(self.randomSessionKey)
        handle = cipher.encrypt
        print("Plaintext")
        hexdump(self.plaintext)
        print("\n")
        sealedMsg, signature = ntlm.SEAL(self.flags, self.nonce, self.nonce,
                                         self.plaintext, self.plaintext,
                                         self.seqNum, handle)
        #signature = ntlm.SIGN(flags, nonce, plaintext, seqNum, handle)
        hexdump(sealedMsg)
        self.assertTrue(sealedMsg == bytearray(
            b'V\xfe\x04\xd8a\xf91\x9a\xf0\xd7#\x8a.;ME\x7f\xb8'))
        print("\n")
        hexdump(signature.getData())
        self.assertTrue(signature.getData() == bytearray(
            b'\x01\x00\x00\x00\x00\x00\x00\x00\t\xdc\xd1\xdf.E\x9d6'))
        print("\n")

        print("####### 4.2.3 NTLMv1 with Client Challenge")
        flags =  ntlm.NTLMSSP_NEGOTIATE_56 | ntlm.NTLMSSP_NEGOTIATE_VERSION | ntlm.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY \
                 | ntlm.NTLMSSP_TARGET_TYPE_SERVER | ntlm.NTLMSSP_NEGOTIATE_ALWAYS_SIGN | ntlm.NTLMSSP_NEGOTIATE_NTLM |\
                 ntlm.NTLMSSP_NEGOTIATE_SEAL | ntlm.NTLMSSP_NEGOTIATE_SIGN | ntlm.NTLM_NEGOTIATE_OEM | ntlm.NTLMSSP_NEGOTIATE_UNICODE
        print("Flags")
        hexdump(struct.pack('<L', flags))
        print("\n")
        print("4.2.3.1.1 NTOWFv1(password)")
        hexdump(ntlm.NTOWFv1(self.password))
        print("\n")
        print("4.2.3.1.2 Session Base Key")
        ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(
            int(flags), self.serverChallenge, self.clientChallenge,
            self.serverName, self.domain, self.user, self.password, '', '')
        hexdump(sessionBaseKey)
        self.assertTrue(sessionBaseKey == bytearray(
            b'\xd8rb\xb0\xcd\xe4\xb1\xcbt\x99\xbe\xcc\xcd\xf1\x07\x84'))
        print("\n")
        print("4.2.3.1.3 Key Exchange Key")
        keyExchangeKey = ntlm.KXKEY(flags, sessionBaseKey, lmResponse,
                                    self.serverChallenge, self.password, '',
                                    '')
        hexdump(keyExchangeKey)
        # ToDo: Fix this
        #self.assertTrue(keyExchangeKey==bytearray(b'\xeb\x93\x42\x9a\x8b\xd9\x52\xf8\xb8\x9c\x55\xb8\x7f\x47\x5e\xdc'))
        print("\n")

        print("4.2.3.2.1 LMv1 Response")
        hexdump(lmResponse)
        #self.assertTrue(lmResponse==bytearray(b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
        print("\n")

        print("4.2.3.2.2 NTLMv1 Response")
        hexdump(ntResponse)
        # ToDo: Fix this
        #self.assertTrue(ntResponse==bytearray(b'\x75\x37\xf8\x03\xae\x36\x71\x28\xca\x45\x82\x04\xbd\xe7\xca\xf8\x1e\x97\xed\x26\x83\x26\x72\x32'))
        print("\n")
        print("AUTHENTICATE MESSAGE")
        ntlm.generateEncryptedSessionKey(keyExchangeKey, self.randomSessionKey)
        ntlmChallengeResponse = ntlm.NTLMAuthChallengeResponse(
            self.user, self.password, self.serverChallenge)
        ntlmChallengeResponse['flags'] = flags2
        ntlmChallengeResponse['host_name'] = self.workstationName.encode(
            'utf-16le')
        ntlmChallengeResponse['domain_name'] = self.domain.encode('utf-16le')
        ntlmChallengeResponse['lanman'] = lmResponse
        ntlmChallengeResponse['ntlm'] = ntResponse
        hexdump(ntlmChallengeResponse.getData())
        self.assertTrue(ntlmChallengeResponse.getData() == bytearray(
            b'NTLMSSP\x00\x03\x00\x00\x00\x18\x00\x18\x00|\x00\x00\x00\x18\x00\x18\x00\x94\x00\x00\x00\x0c\x00\x0c\x00X\x00\x00\x00\x08\x00\x08\x00d\x00\x00\x00\x10\x00\x10\x00l\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\xb3\x82\x02\xe2D\x00o\x00m\x00a\x00i\x00n\x00U\x00s\x00e\x00r\x00C\x00O\x00M\x00P\x00U\x00T\x00E\x00R\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u7\xf8\x03\xae6q(\xcaE\x82\x04\xbd\xe7\xca\xf8\x1e\x97\xed&\x83&r2'
        ))

        print("\n")
        print("4.2.3.4 GSS_WrapEx")
        print("Plaintext")
        hexdump(self.plaintext)
        print("\n")
        print("Output of SEAL()")

        exportedSessionKey = keyExchangeKey
        clientSigningKey = ntlm.SIGNKEY(flags, exportedSessionKey)
        clientSealingKey = ntlm.SEALKEY(flags, exportedSessionKey)

        from Cryptodome.Cipher import ARC4
        cipher = ARC4.new(clientSigningKey)

        cipher2 = ARC4.new(clientSealingKey)
        client_sealing_h = cipher2.encrypt
        print("SEALKEY()")
        hexdump(clientSealingKey)
        print("\n")
        print("SIGNKEY()")
        hexdump(clientSigningKey)
        print("\n")
        print("Sealed Data")
        sealedMsg, signature = ntlm.SEAL(flags, clientSealingKey,
                                         clientSigningKey, self.plaintext,
                                         self.plaintext, self.seqNum,
                                         client_sealing_h)
        #signature = ntlm.SIGN(flags, clientSigningKey, plaintext, seqNum, client_sealing_h)
        hexdump(sealedMsg)
        # ToDo: Fix this
        #self.assertTrue(ntResponse==bytearray(b'\xa0\x23\x72\xf6\x53\x02\x73\xf3\xaa\x1e\xb9\x01\x90\xce\x52\x00\xc9\x9d'))
        print("\n")
        print("Signature")
        hexdump(signature.getData())
        # ToDo: Fix this
        #self.assertTrue(ntResponse==bytearray(b'\x01\x00\x00\x00\xff\x2a\xeb\x52\xf6\x81\x79\x3a\x00\x00\x00\x00')
        print("\n")
示例#10
0
    def __decryptHash(self,
                      record,
                      rid=None,
                      prefixTable=None,
                      outputFile=None):
        if self.__useVSSMethod is True:
            logging.debug('Decrypting hash for user: %s' %
                          record[self.NAME_TO_INTERNAL['name']])

            sid = SAMR_RPC_SID(
                unhexlify(record[self.NAME_TO_INTERNAL['objectSid']]))
            rid = sid.formatCanonical().split('-')[-1]

            if record[self.NAME_TO_INTERNAL['dBCSPwd']] is not None:
                encryptedLMHash = self.CRYPTED_HASH(
                    unhexlify(record[self.NAME_TO_INTERNAL['dBCSPwd']]))
                tmpLMHash = self.__removeRC4Layer(encryptedLMHash)
                LMHash = self.__removeDESLayer(tmpLMHash, rid)
            else:
                LMHash = ntlm.LMOWFv1('', '')

            if record[self.NAME_TO_INTERNAL['unicodePwd']] is not None:
                encryptedNTHash = self.CRYPTED_HASH(
                    unhexlify(record[self.NAME_TO_INTERNAL['unicodePwd']]))
                tmpNTHash = self.__removeRC4Layer(encryptedNTHash)
                NTHash = self.__removeDESLayer(tmpNTHash, rid)
            else:
                NTHash = ntlm.NTOWFv1('', '')

            if record[self.NAME_TO_INTERNAL['userPrincipalName']] is not None:
                domain = record[
                    self.NAME_TO_INTERNAL['userPrincipalName']].split('@')[-1]
                userName = '******' % (
                    domain, record[self.NAME_TO_INTERNAL['sAMAccountName']])
            else:
                userName = '******' % record[
                    self.NAME_TO_INTERNAL['sAMAccountName']]

            if record[self.NAME_TO_INTERNAL['pwdLastSet']] is not None:
                pwdLastSet = self.__fileTimeToDateTime(
                    record[self.NAME_TO_INTERNAL['pwdLastSet']])
            else:
                pwdLastSet = 'N/A'

            answer = "%s:%s:%s:%s:::" % (userName, rid, hexlify(LMHash),
                                         hexlify(NTHash))
            if outputFile is not None:
                self.__writeOutput(outputFile, answer + '\n')

            if self.__pwdLastSet is True:
                answer = "%s (pwdLastSet=%s)" % (answer, pwdLastSet)
            self.__logger.highlight(answer)

            if self.__history:
                LMHistory = []
                NTHistory = []
                if record[self.NAME_TO_INTERNAL['lmPwdHistory']] is not None:
                    encryptedLMHistory = self.CRYPTED_HISTORY(
                        unhexlify(
                            record[self.NAME_TO_INTERNAL['lmPwdHistory']]))
                    tmpLMHistory = self.__removeRC4Layer(encryptedLMHistory)
                    for i in range(0, len(tmpLMHistory) / 16):
                        LMHash = self.__removeDESLayer(
                            tmpLMHistory[i * 16:(i + 1) * 16], rid)
                        LMHistory.append(LMHash)

                if record[self.NAME_TO_INTERNAL['ntPwdHistory']] is not None:
                    encryptedNTHistory = self.CRYPTED_HISTORY(
                        unhexlify(
                            record[self.NAME_TO_INTERNAL['ntPwdHistory']]))
                    tmpNTHistory = self.__removeRC4Layer(encryptedNTHistory)
                    for i in range(0, len(tmpNTHistory) / 16):
                        NTHash = self.__removeDESLayer(
                            tmpNTHistory[i * 16:(i + 1) * 16], rid)
                        NTHistory.append(NTHash)

                for i, (LMHash, NTHash) in enumerate(
                        map(lambda l, n: (l, n)
                            if l else ('', n), LMHistory[1:], NTHistory[1:])):
                    if self.__noLMHash:
                        lmhash = hexlify(ntlm.LMOWFv1('', ''))
                    else:
                        lmhash = hexlify(LMHash)

                    answer = "%s_history%d:%s:%s:%s:::" % (
                        userName, i, rid, lmhash, hexlify(NTHash))
                    if outputFile is not None:
                        self.__writeOutput(outputFile, answer + '\n')
                    self.__logger.highlight(answer)
        else:
            logging.debug('Decrypting hash for user: %s' %
                          record['pmsgOut']['V6']['pNC']['StringName'][:-1])
            domain = None
            if self.__history:
                LMHistory = []
                NTHistory = []
            for attr in record['pmsgOut']['V6']['pObjects']['Entinf'][
                    'AttrBlock']['pAttr']:
                try:
                    attId = drsuapi.OidFromAttid(prefixTable, attr['attrTyp'])
                    LOOKUP_TABLE = self.ATTRTYP_TO_ATTID
                except Exception, e:
                    logging.debug(
                        'Failed to execute OidFromAttid with error %s, fallbacking to fixed table'
                        % e)
                    # Fallbacking to fixed table and hope for the best
                    attId = attr['attrTyp']
                    LOOKUP_TABLE = self.NAME_TO_ATTRTYP

                if attId == LOOKUP_TABLE['dBCSPwd']:
                    if attr['AttrVal']['valCount'] > 0:
                        encrypteddBCSPwd = ''.join(
                            attr['AttrVal']['pAVal'][0]['pVal'])
                        encryptedLMHash = drsuapi.DecryptAttributeValue(
                            self.__remoteOps.getDrsr(), encrypteddBCSPwd)
                        LMHash = drsuapi.removeDESLayer(encryptedLMHash, rid)
                    else:
                        LMHash = ntlm.LMOWFv1('', '')
                elif attId == LOOKUP_TABLE['unicodePwd']:
                    if attr['AttrVal']['valCount'] > 0:
                        encryptedUnicodePwd = ''.join(
                            attr['AttrVal']['pAVal'][0]['pVal'])
                        encryptedNTHash = drsuapi.DecryptAttributeValue(
                            self.__remoteOps.getDrsr(), encryptedUnicodePwd)
                        NTHash = drsuapi.removeDESLayer(encryptedNTHash, rid)
                    else:
                        NTHash = ntlm.NTOWFv1('', '')
                elif attId == LOOKUP_TABLE['userPrincipalName']:
                    if attr['AttrVal']['valCount'] > 0:
                        try:
                            domain = ''.join(
                                attr['AttrVal']['pAVal'][0]['pVal']).decode(
                                    'utf-16le').split('@')[-1]
                        except:
                            domain = None
                    else:
                        domain = None
                elif attId == LOOKUP_TABLE['sAMAccountName']:
                    if attr['AttrVal']['valCount'] > 0:
                        try:
                            userName = ''.join(attr['AttrVal']['pAVal'][0]
                                               ['pVal']).decode('utf-16le')
                        except:
                            logging.error('Cannot get sAMAccountName for %s' %
                                          record['pmsgOut']['V6']['pNC']
                                          ['StringName'][:-1])
                            userName = '******'
                    else:
                        logging.error(
                            'Cannot get sAMAccountName for %s' %
                            record['pmsgOut']['V6']['pNC']['StringName'][:-1])
                        userName = '******'
                elif attId == LOOKUP_TABLE['objectSid']:
                    if attr['AttrVal']['valCount'] > 0:
                        objectSid = ''.join(
                            attr['AttrVal']['pAVal'][0]['pVal'])
                    else:
                        logging.error(
                            'Cannot get objectSid for %s' %
                            record['pmsgOut']['V6']['pNC']['StringName'][:-1])
                        objectSid = rid
                elif attId == LOOKUP_TABLE['pwdLastSet']:
                    if attr['AttrVal']['valCount'] > 0:
                        try:
                            pwdLastSet = self.__fileTimeToDateTime(
                                unpack(
                                    '<Q', ''.join(attr['AttrVal']['pAVal'][0]
                                                  ['pVal']))[0])
                        except:
                            traceback.print_exc()
                            logging.error('Cannot get pwdLastSet for %s' %
                                          record['pmsgOut']['V6']['pNC']
                                          ['StringName'][:-1])
                            pwdLastSet = 'N/A'

                if self.__history:
                    if attId == LOOKUP_TABLE['lmPwdHistory']:
                        if attr['AttrVal']['valCount'] > 0:
                            encryptedLMHistory = ''.join(
                                attr['AttrVal']['pAVal'][0]['pVal'])
                            tmpLMHistory = drsuapi.DecryptAttributeValue(
                                self.__remoteOps.getDrsr(), encryptedLMHistory)
                            for i in range(0, len(tmpLMHistory) / 16):
                                LMHashHistory = drsuapi.removeDESLayer(
                                    tmpLMHistory[i * 16:(i + 1) * 16], rid)
                                LMHistory.append(LMHashHistory)
                        else:
                            logging.debug('No lmPwdHistory for user %s' %
                                          record['pmsgOut']['V6']['pNC']
                                          ['StringName'][:-1])
                    elif attId == LOOKUP_TABLE['ntPwdHistory']:
                        if attr['AttrVal']['valCount'] > 0:
                            encryptedNTHistory = ''.join(
                                attr['AttrVal']['pAVal'][0]['pVal'])
                            tmpNTHistory = drsuapi.DecryptAttributeValue(
                                self.__remoteOps.getDrsr(), encryptedNTHistory)
                            for i in range(0, len(tmpNTHistory) / 16):
                                NTHashHistory = drsuapi.removeDESLayer(
                                    tmpNTHistory[i * 16:(i + 1) * 16], rid)
                                NTHistory.append(NTHashHistory)
                        else:
                            logging.debug('No ntPwdHistory for user %s' %
                                          record['pmsgOut']['V6']['pNC']
                                          ['StringName'][:-1])

            if domain is not None:
                userName = '******' % (domain, userName)

            answer = "%s:%s:%s:%s:::" % (userName, rid, hexlify(LMHash),
                                         hexlify(NTHash))

            if outputFile is not None:
                self.__writeOutput(outputFile, answer + '\n')

            if self.__pwdLastSet is True:
                answer = "%s (pwdLastSet=%s)" % (answer, pwdLastSet)
            self.__logger.highlight(answer)

            if self.__history:
                for i, (LMHashHistory, NTHashHistory) in enumerate(
                        map(lambda l, n: (l, n)
                            if l else ('', n), LMHistory[1:], NTHistory[1:])):
                    if self.__noLMHash:
                        lmhash = hexlify(ntlm.LMOWFv1('', ''))
                    else:
                        lmhash = hexlify(LMHashHistory)

                    answer = "%s_history%d:%s:%s:%s:::" % (
                        userName, i, rid, lmhash, hexlify(NTHashHistory))
                    self.__logger.highlight(answer)
                    if outputFile is not None:
                        self.__writeOutput(outputFile, answer + '\n')
示例#11
0
    def dump(self):
        NTPASSWORD = "******"
        LMPASSWORD = "******"
        sam_hashes = []

        if self.__samFile is None:
            # No SAM file provided
            return

        self.__logger.success(
            'Dumping local SAM hashes (uid:rid:lmhash:nthash)')
        self.getHBootKey()

        usersKey = 'SAM\\Domains\\Account\\Users'

        # Enumerate all the RIDs
        rids = self.enumKey(usersKey)
        # Remove the Names item
        try:
            rids.remove('Names')
        except:
            pass

        for rid in rids:
            userAccount = USER_ACCOUNT_V(
                self.getValue(ntpath.join(usersKey, rid, 'V'))[1])
            rid = int(rid, 16)

            V = userAccount['Data']

            userName = V[userAccount['NameOffset']:userAccount['NameOffset'] +
                         userAccount['NameLength']].decode('utf-16le')

            if userAccount['LMHashLength'] == 20:
                encLMHash = V[userAccount['LMHashOffset'] +
                              4:userAccount['LMHashOffset'] +
                              userAccount['LMHashLength']]
            else:
                encLMHash = ''

            if userAccount['NTHashLength'] == 20:
                encNTHash = V[userAccount['NTHashOffset'] +
                              4:userAccount['NTHashOffset'] +
                              userAccount['NTHashLength']]
            else:
                encNTHash = ''

            lmHash = self.__decryptHash(rid, encLMHash, LMPASSWORD)
            ntHash = self.__decryptHash(rid, encNTHash, NTPASSWORD)

            if lmHash == '':
                lmHash = ntlm.LMOWFv1('', '')
            if ntHash == '':
                ntHash = ntlm.NTOWFv1('', '')

            answer = "%s:%d:%s:%s:::" % (userName, rid, hexlify(lmHash),
                                         hexlify(ntHash))
            self.__itemsFound[rid] = answer
            self.__logger.highlight(answer)
            sam_hashes.append(answer)
            self.__db.add_credential(
                'hash', self.__hostname, userName,
                '{}:{}'.format(hexlify(lmHash), hexlify(ntHash)))

        return sam_hashes
seqNum = 0
nonce = '\x00' * 4
plaintext = 'Plaintext'.encode('utf-16le')

print "## BEFORE RUNNING THESE TESTS"
print "Don't forget to set up aTime = '\\x00'*8 in computeResponseNTLMv2 otherwise the results won't be right. "
print "Look for that in ntlm.py and uncomment the lines, comment the other ones and don't forget to revert everything back whenever finished testing"
print "Flags"
hexdump(struct.pack('<L', flags))
print "####### 4.2.2 NTLMv1 Authentication"
ntlm.USE_NTLMv2 = False
print "4.2.2.1 LMOWFv1()"
hexdump(ntlm.LMOWFv1(password))
print "\n"
print "4.2.2.1.2 NTOWFv1()"
hexdump(ntlm.NTOWFv1(password))
print "\n"
print "4.2.2.1.3 Session Base Key and Key Exchange Key"
ntResponse, lmResponse, sessionBaseKey = ntlm.computeResponseNTLMv1(
    long(flags), serverChallenge, clientChallenge, serverName, domain, user,
    password, '', '')
hexdump(sessionBaseKey)
print "\n"
print "4.2.2.2.1 NTLMv1 Response"
hexdump(ntResponse)
print "\n"
print "4.2.2.2.2 LMv1 Response"
hexdump(lmResponse)
print "\n"
print "4.2.2.2.2 LMv1 Response with NTLMSSP_NEGOTIATE_LM_KEY set"
flags2 = flags