示例#1
0
        static byte[] ComputeNtlmV2(Type2Message type2, string username, string password, string domain)
        {
            var ntlm_hash = ComputeNtlmPassword(password);

            var ubytes = Encoding.Unicode.GetBytes(username.ToUpperInvariant());
            var tbytes = Encoding.Unicode.GetBytes(domain);

            var bytes = new byte[ubytes.Length + tbytes.Length];

            ubytes.CopyTo(bytes, 0);
            Array.Copy(tbytes, 0, bytes, ubytes.Length, tbytes.Length);

            byte[] ntlm_v2_hash;

            using (var md5 = new HMACMD5(ntlm_hash))
                ntlm_v2_hash = md5.ComputeHash(bytes);

            Array.Clear(ntlm_hash, 0, ntlm_hash.Length);

            using (var md5 = new HMACMD5(ntlm_v2_hash)) {
                var now       = DateTime.Now;
                var timestamp = now.Ticks - 504911232000000000;
                var nonce     = new byte[8];

                using (var rng = RandomNumberGenerator.Create())
                    rng.GetBytes(nonce);

                var targetInfo = type2.EncodedTargetInfo;
                var blob       = new byte[28 + targetInfo.Length];
                blob[0] = 0x01;
                blob[1] = 0x01;

                Buffer.BlockCopy(BitConverterLE.GetBytes(timestamp), 0, blob, 8, 8);

                Buffer.BlockCopy(nonce, 0, blob, 16, 8);
                Buffer.BlockCopy(targetInfo, 0, blob, 28, targetInfo.Length);

                var challenge = type2.Nonce;

                var hashInput = new byte[challenge.Length + blob.Length];
                challenge.CopyTo(hashInput, 0);
                blob.CopyTo(hashInput, challenge.Length);

                var blobHash = md5.ComputeHash(hashInput);

                var response = new byte[blob.Length + blobHash.Length];
                blobHash.CopyTo(response, 0);
                blob.CopyTo(response, blobHash.Length);

                Array.Clear(ntlm_v2_hash, 0, ntlm_v2_hash.Length);
                Array.Clear(hashInput, 0, hashInput.Length);
                Array.Clear(blobHash, 0, blobHash.Length);
                Array.Clear(nonce, 0, nonce.Length);
                Array.Clear(blob, 0, blob.Length);

                return(response);
            }
        }
示例#2
0
        public static void ComputeNtlmV2(NtlmChallengeMessage type2, string domain, string userName, string password, byte[] targetInfo, byte[] clientChallenge, long?time, out byte[] ntChallengeResponse, out byte[] lmChallengeResponse, out byte[] sessionBaseKey)
        {
            if (userName.Length == 0 && password.Length == 0)
            {
                // Special case for anonymous authentication
                ntChallengeResponse = null;
                lmChallengeResponse = Z1;
                sessionBaseKey      = null;
                return;
            }

            var timestamp   = (time ?? DateTime.UtcNow.Ticks) - 504911232000000000;
            var responseKey = NTOWFv2(domain, userName, password);

            // Note: If NTLM v2 authentication is used, the client SHOULD send the timestamp in the CHALLENGE_MESSAGE.
            if (type2.TargetInfo?.Timestamp != null)
            {
                timestamp = type2.TargetInfo.Timestamp.Value;
            }

            var temp  = ConcatenationOf(Responserversion, HiResponserversion, Z6, BitConverterLE.GetBytes(timestamp), clientChallenge, Z4, targetInfo, Z4);
            var proof = HMACMD5(responseKey, type2.ServerChallenge, temp);

            sessionBaseKey = HMACMD5(responseKey, proof);

            ntChallengeResponse = ConcatenationOf(proof, temp);
            Array.Clear(proof, 0, proof.Length);
            Array.Clear(temp, 0, temp.Length);

            var hash = HMACMD5(responseKey, type2.ServerChallenge, clientChallenge);

            Array.Clear(responseKey, 0, responseKey.Length);

            // Note: If NTLM v2 authentication is used and the CHALLENGE_MESSAGE TargetInfo field (section 2.2.1.2) has an
            // MsvAvTimestamp present, the client SHOULD NOT send the LmChallengeResponse and SHOULD send Z(24) instead.
            if (type2.TargetInfo?.Timestamp == null)
            {
                lmChallengeResponse = ConcatenationOf(hash, clientChallenge);
            }
            else
            {
                lmChallengeResponse = Z24;
            }
            Array.Clear(hash, 0, hash.Length);
        }