Exemple #1
0
    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))
Exemple #2
0
    def sendClientRandom(self):
        """
        @summary: generate and send client random and init session keys 
        """
        #generate client random
        clientRandom = rsa.random(256)
        self._macKey, self._initialDecrytKey, self._initialEncryptKey = generateKeys(
            clientRandom,
            self.getGCCServerSettings().SC_SECURITY.serverRandom.value,
            self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
        #initialize keys
        self._currentDecrytKey = self._initialDecrytKey
        self._currentEncryptKey = self._initialEncryptKey
        self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey)
        self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey)

        #verify certificate
        if not self.getGCCServerSettings(
        ).SC_SECURITY.serverCertificate.certData.verify():
            log.warning("cannot verify server identity")
        #send client random encrypted with
        serverPublicKey = self.getGCCServerSettings(
        ).SC_SECURITY.serverCertificate.certData.getPublicKey()
        message = ClientSecurityExchangePDU()
        #reverse because bignum in little endian
        message.encryptedClientRandom.value = rsa.encrypt(
            clientRandom[::-1], serverPublicKey)[::-1]
        self.sendFlagged(SecurityFlag.SEC_EXCHANGE_PKT, message)
Exemple #3
0
    def recvClientRandom(self, s):
        """
        @summary: receive client random and generate session keys
        @param s: {Stream}
        """
        #packet preambule
        securityFlag = UInt16Le()
        securityFlagHi = UInt16Le()
        s.readType((securityFlag, securityFlagHi))

        if not (securityFlag.value & SecurityFlag.SEC_EXCHANGE_PKT):
            raise InvalidExpectedDataException("waiting client random")

        message = ClientSecurityExchangePDU()
        s.readType(message)
        clientRandom = rsa.decrypt(message.encryptedClientRandom.value[::-1], self._rsaPrivateKey)[::-1]

        self._macKey, self._initialEncryptKey, self._initialDecrytKey = generateKeys(   clientRandom,
                                                                                        self.getGCCServerSettings().SC_SECURITY.serverRandom.value,
                                                                                        self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
        #initialize keys
        self._currentDecrytKey = self._initialDecrytKey
        self._currentEncryptKey = self._initialEncryptKey
        self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey)
        self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey)

        self.setNextState(self.recvInfoPkt)
Exemple #4
0
    def getAuthenticateMessage(self, challenge, authMessage):
        """
        @summary: Client last handshake message
        @param s: {Stream} challenge message stream
        @return: {(AuthenticateMessage, NTLMv2SecurityInterface)} Last handshake message and security interface use to encrypt
        @see: https://msdn.microsoft.com/en-us/library/cc236676.aspx
        """
        self._challengeMessage = ChallengeMessage()
        challenge.readType(self._challengeMessage)

        ServerChallenge = self._challengeMessage.ServerChallenge.value
        ClientChallenge = random(64)

        computeMIC = False
        ServerName = self._challengeMessage.getTargetInfo()
        infos = self._challengeMessage.getTargetInfoAsAvPairArray()
        if infos.has_key(AvId.MsvAvTimestamp):
            Timestamp = infos[AvId.MsvAvTimestamp]
            computeMIC = False
        else:
            Timestamp = CurrentFileTimes()

        NtChallengeResponse, LmChallengeResponse, SessionBaseKey = ComputeResponsev2(
            self._ResponseKeyNT, self._ResponseKeyLM, ServerChallenge,
            ClientChallenge, Timestamp, ServerName)
        KeyExchangeKey = KXKEYv2(SessionBaseKey, LmChallengeResponse,
                                 ServerChallenge)
        ExportedSessionKey = random(128)
        EncryptedRandomSessionKey = RC4K(KeyExchangeKey, ExportedSessionKey)

        domain, user = self._domain, self._user
        if self._challengeMessage.NegotiateFlags.value & Negotiate.NTLMSSP_NEGOTIATE_UNICODE:
            self._enableUnicode = True
            domain, user = UNICODE(domain), UNICODE(user)
        self._authenticateMessage = AuthenticateMessage()
        ss = Stream(type.String(authMessage))
        self._authenticateMessage.read(ss)

        if computeMIC:
            self._authenticateMessage.MIC.value = MIC(
                ExportedSessionKey, self._negotiateMessage,
                self._challengeMessage, self._authenticateMessage)
        else:
            self._authenticateMessage.MIC._conditional = lambda: False

        ClientSigningKey = SIGNKEY(ExportedSessionKey, True)
        ServerSigningKey = SIGNKEY(ExportedSessionKey, False)
        ClientSealingKey = SEALKEY(ExportedSessionKey, True)
        ServerSealingKey = SEALKEY(ExportedSessionKey, False)

        interface = NTLMv2SecurityInterface(rc4.RC4Key(ClientSealingKey),
                                            rc4.RC4Key(ServerSealingKey),
                                            ClientSigningKey, ServerSigningKey)

        return self._authenticateMessage, interface
Exemple #5
0
 def testCSSPNTLMAuthentication(self):
     negotiate_data_request = cssp.decodeDERTRequest(peer0_0.decode('base64'))
     challenge_data_request = cssp.decodeDERTRequest(peer1_0.decode('base64'))
     authenticate_data_request = cssp.decodeDERTRequest(peer0_1.decode('base64'))
     
     negotiate_data = cssp.getNegoTokens(negotiate_data_request)[0]
     challenge_data = cssp.getNegoTokens(challenge_data_request)[0]
     authenticate_data = cssp.getNegoTokens(authenticate_data_request)[0]
     
     negotiate = ntlm.NegotiateMessage()
     negotiate_data.readType(negotiate)
     
     challenge = ntlm.ChallengeMessage()
     challenge_data.readType(challenge)
     
     ServerChallenge = challenge.ServerChallenge.value
     ServerName = challenge.getTargetInfo()
 
     authenticate = ntlm.AuthenticateMessage()
     authenticate_data.readType(authenticate)
     
     NtChallengeResponseTemp = authenticate.getNtChallengeResponse()
     NTProofStr = NtChallengeResponseTemp[:16]
     temp = NtChallengeResponseTemp[16:]
     Timestamp = temp[8:16]
     ClientChallenge = temp[16:24]
     
     EncryptedRandomSessionKey = authenticate.getEncryptedRandomSession()
     domain = "coco"
     user = "******"
     password = "******"
     
     ResponseKeyNT = ntlm.NTOWFv2(password, user, domain)
     ResponseKeyLM = ntlm.LMOWFv2(password, user, domain)
     NtChallengeResponse, LmChallengeResponse, SessionBaseKey = ntlm.ComputeResponsev2(ResponseKeyNT, ResponseKeyLM, ServerChallenge, ClientChallenge, Timestamp, ServerName)
     KeyExchangeKey = ntlm.KXKEYv2(SessionBaseKey, LmChallengeResponse, ServerChallenge)
     ExportedSessionKey = ntlm.RC4K(KeyExchangeKey, EncryptedRandomSessionKey)
     
     domain, user = domain, user
     if challenge.NegotiateFlags.value & ntlm.Negotiate.NTLMSSP_NEGOTIATE_UNICODE:
         domain, user = ntlm.UNICODE(domain), ntlm.UNICODE(user)
         
     ClientSigningKey = ntlm.SIGNKEY(ExportedSessionKey, True)
     ServerSigningKey = ntlm.SIGNKEY(ExportedSessionKey, False)
     ClientSealingKey = ntlm.SEALKEY(ExportedSessionKey, True)
     ServerSealingKey = ntlm.SEALKEY(ExportedSessionKey, False)
     
     interface = ntlm.NTLMv2SecurityInterface(rc4.RC4Key(ClientSealingKey), rc4.RC4Key(ServerSealingKey), ClientSigningKey, ServerSigningKey)
     
     EncryptedPubKeySrc = cssp.getPubKeyAuth(authenticate_data_request)
     EncryptedPubKeyDst = interface.GSS_WrapEx(pubKeyHex.decode('base64'))
     
     self.assertTrue(EncryptedPubKeySrc == EncryptedPubKeyDst, "Public key must be equals")
     
Exemple #6
0
    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)
Exemple #7
0
    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())))
Exemple #8
0
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)
Exemple #9
0
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 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")