def calc_signkey(self, mode='Client'): if NegotiateFlags.NEGOTIATE_EXTENDED_SESSIONSECURITY in self.ntlmChallenge.NegotiateFlags: if mode == 'Client': md5 = hashlib.new('md5') md5.update( self.RandomSessionKey + b"session key to client-to-server signing key magic constant\x00" ) signkey = md5.digest() else: md5 = hashlib.new('md5') md5.update( self.RandomSessionKey + b"session key to server-to-client signing key magic constant\x00" ) signkey = md5.digest() else: signkey = None if mode == 'Client': self.SignKey_client = signkey else: self.SignKey_server = signkey return signkey
def calc_sealkey(self, mode='Client'): if NegotiateFlags.NEGOTIATE_EXTENDED_SESSIONSECURITY in self.ntlmChallenge.NegotiateFlags: if NegotiateFlags.NEGOTIATE_128 in self.ntlmChallenge.NegotiateFlags: sealkey = self.RandomSessionKey elif NegotiateFlags.NEGOTIATE_56 in self.ntlmChallenge.NegotiateFlags: sealkey = self.RandomSessionKey[:7] else: sealkey = self.RandomSessionKey[:5] if mode == 'Client': md5 = hashlib.new('md5') md5.update( sealkey + b'session key to client-to-server sealing key magic constant\x00' ) sealkey = md5.digest() else: md5 = hashlib.new('md5') md5.update( sealkey + b'session key to server-to-client sealing key magic constant\x00' ) sealkey = md5.digest() elif NegotiateFlags.NEGOTIATE_56 in self.ntlmChallenge.NegotiateFlags: sealkey = self.RandomSessionKey[:7] + b'\xa0' else: sealkey = self.RandomSessionKey[:5] + b'\xe5\x38\xb0' if mode == 'Client': self.SealKey_client = sealkey else: self.SealKey_server = sealkey return sealkey
def test_rc4(self): cred = KerberosCredential() cred.username = self.username salt = (self.domain.upper() + self.username).encode() cred.kerberos_key_rc4 = hashlib.new( 'md4', self.password.encode('utf-16-le')).hexdigest() cred.domain = self.domain kcomm = KerbrosComm(cred, self.kerberos_socet) kcomm.get_TGT()
def DecryptAttributeValue(sessionKey, attribute): encryptedPayload = ENCRYPTED_PAYLOAD(attribute) md5 = hashlib.new('md5') md5.update(sessionKey) md5.update(encryptedPayload['Salt']) finalMD5 = md5.digest() cipher = RC4(finalMD5) plainText = cipher.decrypt(attribute[16:]) #chkSum = (binascii.crc32(plainText[4:])) & 0xffffffff #if unpack('<L',plainText[:4])[0] != chkSum: # print "RECEIVED 0x%x" % unpack('<L',plainText[:4])[0] # print "CALCULATED 0x%x" % chkSum return plainText[4:]
async def authenticate(self, authData, flags=None, seq_number=0, cb_data=None): if self.mode.upper() == 'CLIENT': if self.iteration_cnt == 0: if authData is not None: raise Exception( 'First call as client MUST be with empty data!') self.iteration_cnt += 1 #negotiate message was already calulcated in setup self.ntlmNegotiate = NTLMNegotiate.construct( self.flags, domainname=self.settings.template['domain_name'], workstationname=self.settings.template['workstation_name'], version=self.settings.template.get('version')) self.ntlmNegotiate_raw = self.ntlmNegotiate.to_bytes() return self.ntlmNegotiate_raw, True, None else: #server challenge incoming self.ntlmChallenge_raw = authData self.ntlmChallenge = NTLMChallenge.from_bytes(authData) ##################self.flags = self.ntlmChallenge.NegotiateFlags #we need to calculate the response based on the credential and the settings flags if self.settings.ntlm_downgrade == True: #NTLMv1 authentication # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/464551a8-9fc4-428e-b3d3-bc5bfb2e73a5 #check if we authenticate as guest if self.settings.credential.is_guest == True: lmresp = LMResponse() lmresp.Response = b'\x00' self.ntlmAuthenticate = NTLMAuthenticate.construct( self.flags, lm_response=lmresp) return self.ntlmAuthenticate.to_bytes(), False, None if self.flags & NegotiateFlags.NEGOTIATE_EXTENDED_SESSIONSECURITY: #Extended auth! self.ntlm_credentials = netntlm_ess.construct( self.ntlmChallenge.ServerChallenge, self.challenge, self.settings.credential) self.KeyExchangeKey = self.ntlm_credentials.calc_key_exchange_key( ) self.setup_crypto() self.ntlmAuthenticate = NTLMAuthenticate.construct( self.flags, lm_response=self.ntlm_credentials.LMResponse, nt_response=self.ntlm_credentials.NTResponse, version=self.ntlmNegotiate.Version, encrypted_session=self.EncryptedRandomSessionKey) else: self.ntlm_credentials = netntlm.construct( self.ntlmChallenge.ServerChallenge, self.settings.credential) self.KeyExchangeKey = self.ntlm_credentials.calc_key_exchange_key( with_lm=self.flags & NegotiateFlags.NEGOTIATE_LM_KEY, non_nt_session_key=self.flags & NegotiateFlags.REQUEST_NON_NT_SESSION_KEY) self.setup_crypto() self.ntlmAuthenticate = NTLMAuthenticate.construct( self.flags, lm_response=self.ntlm_credentials.LMResponse, nt_response=self.ntlm_credentials.NTResponse, version=self.ntlmNegotiate.Version, encrypted_session=self.EncryptedRandomSessionKey) else: #NTLMv2 # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3 if self.settings.credential.is_guest == True: lmresp = LMResponse() lmresp.Response = b'\x00' self.ntlmAuthenticate = NTLMAuthenticate.construct( self.flags, lm_response=lmresp) return self.ntlmAuthenticate.to_bytes(), False, None else: #comment this out for testing! ti = self.ntlmChallenge.TargetInfo ti[AVPAIRType.MsvAvTargetName] = 'ldaps/%s' % ti[ AVPAIRType.MsvAvDnsComputerName] if cb_data is not None: md5_ctx = hashlib.new('md5') md5_ctx.update(cb_data) ti[AVPAIRType.MsvChannelBindings] = md5_ctx.digest( ) ### self.ntlm_credentials = netntlmv2.construct( self.ntlmChallenge.ServerChallenge, self.challenge, ti, self.settings.credential, timestamp=self.timestamp) self.KeyExchangeKey = self.ntlm_credentials.calc_key_exchange_key( ) self.setup_crypto() #TODO: if "ti" / targetinfo in the challenge message has "MsvAvFlags" type and the bit for MIC is set (0x00000002) we need to send a MIC. probably... mic = None self.ntlmAuthenticate = NTLMAuthenticate.construct( self.flags, domainname=self.settings.credential.domain, workstationname=self.settings.credential. workstation, username=self.settings.credential.username, lm_response=self.ntlm_credentials.LMResponse, nt_response=self.ntlm_credentials.NTResponse, version=self.ntlmNegotiate.Version, encrypted_session=self.EncryptedRandomSessionKey, mic=mic) self.ntlmAuthenticate_raw = self.ntlmAuthenticate.to_bytes() return self.ntlmAuthenticate_raw, False, None elif self.mode.upper() == 'RELAY': if self.iteration_cnt == 0: self.ntlmNegotiate_raw = authData self.ntlmNegotiate = NTLMNegotiate.from_bytes(authData) self.iteration_cnt += 1 elif self.iteration_cnt == 1: self.ntlmChallenge_raw = authData self.ntlmChallenge = NTLMChallenge.from_bytes(authData) self.iteration_cnt += 1 elif self.iteration_cnt == 2: self.ntlmChallenge_raw = authData self.ntlmChallenge = NTLMChallenge.from_bytes(authData) self.iteration_cnt += 1 else: raise Exception('Too many iterations for relay mode!')
ccred = KerberosCredential() ccred.username = '******' ccred.domain = 'TEST.corp' ccred2 = KerberosCredential() ccred2.username = '******' ccred2.domain = 'TEST.corp' creds = [ccred, ccred2] ks = KerberosSocket('192.168.9.1') ar = APREPRoast(ks) res = ar.run(creds) rep = res[0] print(res) x, a, enctype, checksum, data = rep.split('$') password = '******' cipher = _enctype_table[int(enctype)] key = Key(int(enctype), hashlib.new('md4', password.encode('utf-16-le')).digest()) cipherText = bytes.fromhex(checksum + data) temp = cipher.decrypt(key, 3, cipherText) print() print() print(temp.hex()) enc_as_rep_part = EncASRepPart.load(temp).native