def readEncryptedPayload(self, s, saltedMacGeneration): """ @summary: decrypt basic RDP security payload @param s: {Stream} encrypted stream @param saltedMacGeneration: {bool} use salted mac generation @return: {Stream} decrypted """ #if update is needed if self._nbDecryptedPacket == 4096: log.debug("update decrypt key") self._currentDecrytKey = updateKey( self._initialDecrytKey, self._currentDecrytKey, self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value) self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey) self._nbDecryptedPacket = 0 signature = String(readLen = CallableValue(8)) encryptedPayload = String() s.readType((signature, encryptedPayload)) decrypted = rc4.crypt(self._decryptRc4, encryptedPayload.value) #ckeck signature if not saltedMacGeneration and macData(self._macKey, decrypted)[:8] != signature.value: raise InvalidExpectedDataException("bad signature") if saltedMacGeneration and macSaltedData(self._macKey, decrypted, self._nbDecryptedPacket)[:8] != signature.value: raise InvalidExpectedDataException("bad signature") #count self._nbDecryptedPacket += 1 return Stream(decrypted)
def RC4K(key, plaintext): """ @summary: Context free of rc4 encoding @param key: {str} key @param plaintext: {str} plaintext @return {str} encrypted text """ return rc4.crypt(rc4.RC4Key(key), plaintext)
def updateKey(initialKey, currentKey, method): """ @summary: update session key @param initialKey: {str} Initial key @param currentKey: {str} Current key @return newKey: {str} key to use @see: http://msdn.microsoft.com/en-us/library/cc240792.aspx """ #generate valid key if method == gcc.EncryptionMethod.ENCRYPTION_FLAG_40BIT: tempKey128 = tempKey(initialKey[:8], currentKey[:8]) return gen40bits(rc4.crypt(rc4.RC4Key(tempKey128[:8]), tempKey128[:8])) elif method == gcc.EncryptionMethod.ENCRYPTION_FLAG_56BIT: tempKey128 = tempKey(initialKey[:8], currentKey[:8]) return gen56bits(rc4.crypt(rc4.RC4Key(tempKey128[:8]), tempKey128[:8])) elif method == gcc.EncryptionMethod.ENCRYPTION_FLAG_128BIT: tempKey128 = tempKey(initialKey, currentKey) return rc4.crypt(rc4.RC4Key(tempKey128), tempKey128)
def GSS_WrapEx(self, data): """ @summary: Encrypt function for NTLMv2 security service @param data: data to encrypt @return: {str} encrypted data """ encryptedData = rc4.crypt(self._encryptHandle, data) signature = MAC(self._encryptHandle, self._signingKey, self._seqNum, data) self._seqNum += 1 s = Stream() s.writeType(signature) return s.getvalue() + encryptedData
def GSS_UnWrapEx(self, data): """ @summary: decrypt data with key exchange in Authentication protocol @param data: {str} """ signature = MessageSignatureEx() message = String() s = Stream(data) s.readType((signature, message)) #decrypt message plaintextMessage = rc4.crypt(self._decryptHandle, message.value) checksum = rc4.crypt(self._decryptHandle, signature.Checksum.value) #recompute checksum t = Stream() t.writeType(signature.SeqNum) verify = HMAC_MD5(self._verifyKey, t.getvalue() + plaintextMessage)[:8] if verify != checksum: raise error.InvalidExpectedDataException("NTLMv2SecurityInterface : Invalid checksum") return plaintextMessage
def sendClientChallengeResponse(self, platformChallenge): """ @summary: generate valid challenge response @param platformChallenge: {ServerPlatformChallenge} """ serverEncryptedChallenge = platformChallenge.encryptedPlatformChallenge.blobData.value #decrypt server challenge #it should be TEST word in unicode format serverChallenge = rc4.crypt(rc4.RC4Key(self._licenseKey), serverEncryptedChallenge) if serverChallenge != "T\x00E\x00S\x00T\x00\x00\x00": raise InvalidExpectedDataException("bad license server challenge") #generate hwid s = Stream() s.writeType((UInt32Le(2), String(self._hostname + self._username + "\x00" * 16))) hwid = s.getvalue()[:20] message = ClientPLatformChallengeResponse() message.encryptedPlatformChallengeResponse.blobData.value = serverEncryptedChallenge message.encryptedHWID.blobData.value = rc4.crypt(rc4.RC4Key(self._licenseKey), hwid) message.MACData.value = sec.macData(self._macSalt, serverChallenge + hwid) self._transport.sendFlagged(sec.SecurityFlag.SEC_LICENSE_PKT, LicPacket(message))
def MAC(handle, SigningKey, SeqNum, Message): """ @summary: generate signature for application message @param handle: {rc4.RC4Key} handle on crypt @param SigningKey: {str} Signing key @param SeqNum: {int} Sequence number @param Message: Message to sign @see: https://msdn.microsoft.com/en-us/library/cc422952.aspx """ signature = MessageSignatureEx() signature.SeqNum.value = SeqNum #write the SeqNum s = Stream() s.writeType(signature.SeqNum) signature.Checksum.value = rc4.crypt(handle, HMAC_MD5(SigningKey, s.getvalue() + Message)[:8]) return signature
def writeEncryptedPayload(self, data, saltedMacGeneration): """ @summary: sign and crypt data @param data: {Type} raw stream @param saltedMacGeneration: {bool} use salted mac generation @return: {Tuple} (signature, encryptedData) """ if self._nbEncryptedPacket == 4096: log.debug("update encrypt key") self._currentEncryptKey = updateKey( self._initialEncryptKey, self._currentEncryptKey, self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value) self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey) self._nbEncryptedPacket = 0 self._nbEncryptedPacket += 1 s = Stream() s.writeType(data) if saltedMacGeneration: return (String(macSaltedData(self._macKey, s.getvalue(), self._nbEncryptedPacket - 1)[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue()))) else: return (String(macData(self._macKey, s.getvalue())[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue())))
def test_rc4_secret_attack_at_down(self): self.assertEqual("\x45\xA0\x1F\x64\x5F\xC3\x5B\x38\x35\x52\x54\x4B\x9B\xF5", rc4.crypt(rc4.RC4Key("Secret"), "Attack at dawn"), "RC4 bad crypt") self.assertEqual("Attack at dawn", rc4.crypt(rc4.RC4Key("Secret"), "\x45\xA0\x1F\x64\x5F\xC3\x5B\x38\x35\x52\x54\x4B\x9B\xF5"), "RC4 bad crypt")
def test_rc4_wiki_pedia(self): self.assertEqual("\x10\x21\xBF\x04\x20", rc4.crypt(rc4.RC4Key("Wiki"), "pedia"), "RC4 bad crypt") self.assertEqual("pedia", rc4.crypt(rc4.RC4Key("Wiki"), "\x10\x21\xBF\x04\x20"), "RC4 bad crypt")
def test_rc4_key_plaintext(self): self.assertEqual("\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3", rc4.crypt(rc4.RC4Key("Key"), "Plaintext"), "RC4 bad crypt") self.assertEqual("Plaintext", rc4.crypt(rc4.RC4Key("Key"), "\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3"), "RC4 bad crypt")