public static bool NTv1HashTest()
        {
            byte[] hash     = NTLMCryptography.NTOWFv1("Password");
            byte[] expected = new byte[] { 0xa4, 0xf4, 0x9c, 0x40, 0x65, 0x10, 0xbd, 0xca, 0xb6, 0x82, 0x4e, 0xe7, 0xc3, 0x0f, 0xd8, 0x52 };
            bool   success  = ByteUtils.AreByteArraysEqual(hash, expected);

            return(success);
        }
Exemple #2
0
        public void TestNTLMv1ExtendedSessionSecurityKeyExchangeMIC()
        {
            string password = "******";

            byte[] type1 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x97, 0x82, 0x08, 0xe2,
                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                        0x0a, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0f };
            byte[] type2 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00,
                                        0x38, 0x00, 0x00, 0x00, 0x15, 0x82, 0x8a, 0xe2, 0x7a, 0x6d, 0x47, 0x52, 0x11, 0x8b, 0x9f, 0x37,
                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x48, 0x00, 0x00, 0x00,
                                        0x06, 0x00, 0x71, 0x17, 0x00, 0x00, 0x00, 0x0f, 0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x2d, 0x00,
                                        0x56, 0x00, 0x4d, 0x00, 0x31, 0x00, 0x30, 0x00, 0x02, 0x00, 0x10, 0x00, 0x54, 0x00, 0x41, 0x00,
                                        0x4c, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x31, 0x00, 0x30, 0x00, 0x01, 0x00, 0x10, 0x00,
                                        0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x31, 0x00, 0x30, 0x00,
                                        0x04, 0x00, 0x10, 0x00, 0x54, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x4d, 0x00,
                                        0x31, 0x00, 0x30, 0x00, 0x03, 0x00, 0x10, 0x00, 0x54, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x2d, 0x00,
                                        0x56, 0x00, 0x4d, 0x00, 0x31, 0x00, 0x30, 0x00, 0x07, 0x00, 0x08, 0x00, 0x28, 0x9a, 0x19, 0xec,
                                        0x8d, 0x92, 0xd2, 0x01, 0x00, 0x00, 0x00, 0x00 };
            byte[] type3 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00,
                                        0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x94, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00,
                                        0x58, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x66, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00,
                                        0x6e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xac, 0x00, 0x00, 0x00, 0x15, 0x82, 0x88, 0xe2,
                                        0x0a, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0f, 0xc6, 0x21, 0x82, 0x59, 0x83, 0xda, 0xc7, 0xe7,
                                        0xfa, 0x96, 0x44, 0x67, 0x16, 0xc3, 0xb3, 0x5b, 0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x2d, 0x00,
                                        0x56, 0x00, 0x4d, 0x00, 0x36, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x54, 0x00,
                                        0x41, 0x00, 0x4c, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x36, 0x00, 0x90, 0x13, 0xb0, 0x36,
                                        0xa4, 0xa5, 0xf0, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                        0x00, 0x00, 0x00, 0x00, 0x5c, 0x46, 0xea, 0x77, 0x30, 0x44, 0xee, 0xa5, 0x98, 0x26, 0xa0, 0x93,
                                        0x71, 0x5c, 0x83, 0xff, 0x76, 0x70, 0x1d, 0xf0, 0xb8, 0xa0, 0xad, 0x4d, 0xac, 0xe9, 0xf4, 0x5c,
                                        0x3e, 0xb1, 0xb6, 0x48, 0x08, 0xa0, 0x46, 0x8c, 0x31, 0xe1, 0x2d, 0x60 };

            byte[] serverChallenge = new ChallengeMessage(type2).ServerChallenge;
            AuthenticateMessage authenticateMessage = new AuthenticateMessage(type3);

            byte[] sessionBaseKey     = new MD4().GetByteHashFromBytes(NTLMCryptography.NTOWFv1(password));
            byte[] lmowf              = NTLMCryptography.LMOWFv1(password);
            byte[] exportedSessionKey = GetExportedSessionKey(sessionBaseKey, authenticateMessage, serverChallenge, lmowf);

            // https://msdn.microsoft.com/en-us/library/cc236695.aspx
            const int micFieldOffset = 72;

            ByteWriter.WriteBytes(type3, micFieldOffset, new byte[16]);
            byte[] temp     = ByteUtils.Concatenate(ByteUtils.Concatenate(type1, type2), type3);
            byte[] mic      = new HMACMD5(exportedSessionKey).ComputeHash(temp);
            byte[] expected = new byte[] { 0xc6, 0x21, 0x82, 0x59, 0x83, 0xda, 0xc7, 0xe7, 0xfa, 0x96, 0x44, 0x67, 0x16, 0xc3, 0xb3, 0x5b };

            Assert.IsTrue(ByteUtils.AreByteArraysEqual(mic, expected));
        }
Exemple #3
0
        public void TestNTLMv1MIC()
        {
            string password = "******";

            byte[] type1 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x97, 0x82, 0x08, 0xe2,
                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                        0x0a, 0x00, 0x39, 0x38, 0x00, 0x00, 0x00, 0x0f };
            byte[] type2 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
                                        0x38, 0x00, 0x00, 0x00, 0x15, 0x02, 0x82, 0xa2, 0xe8, 0xbe, 0x2f, 0x5b, 0xc5, 0xe9, 0xf7, 0xa7,
                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x3e, 0x00, 0x00, 0x00,
                                        0x05, 0x02, 0xce, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x02, 0x00,
                                        0x06, 0x00, 0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x01, 0x00, 0x06, 0x00, 0x54, 0x00, 0x41, 0x00,
                                        0x4c, 0x00, 0x00, 0x00, 0x00, 0x00 };
            byte[] type3 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00,
                                        0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x94, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00,
                                        0x58, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x66, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00,
                                        0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x15, 0x02, 0x80, 0xa2,
                                        0x0a, 0x00, 0x39, 0x38, 0x00, 0x00, 0x00, 0x0f, 0xae, 0xa7, 0xba, 0x44, 0x4e, 0x93, 0xa7, 0xdb,
                                        0xb3, 0x0c, 0x85, 0x49, 0xc2, 0x2b, 0xba, 0x9a, 0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x2d, 0x00,
                                        0x56, 0x00, 0x4d, 0x00, 0x36, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x54, 0x00,
                                        0x41, 0x00, 0x4c, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x36, 0x00, 0xa6, 0x71, 0xbd, 0x94,
                                        0x78, 0x4f, 0x05, 0xf1, 0x3f, 0x3a, 0x7b, 0x41, 0xcf, 0x53, 0x2e, 0x36, 0x73, 0xe2, 0x14, 0x53,
                                        0xbd, 0x42, 0x5e, 0x8f, 0xa6, 0x71, 0xbd, 0x94, 0x78, 0x4f, 0x05, 0xf1, 0x3f, 0x3a, 0x7b, 0x41,
                                        0xcf, 0x53, 0x2e, 0x36, 0x73, 0xe2, 0x14, 0x53, 0xbd, 0x42, 0x5e, 0x8f };

            byte[] serverChallenge = new ChallengeMessage(type2).ServerChallenge;
            AuthenticateMessage authenticateMessage = new AuthenticateMessage(type3);

            byte[] sessionBaseKey     = new MD4().GetByteHashFromBytes(NTLMCryptography.NTOWFv1(password));
            byte[] lmowf              = NTLMCryptography.LMOWFv1(password);
            byte[] exportedSessionKey = GetExportedSessionKey(sessionBaseKey, authenticateMessage, serverChallenge, lmowf);

            // https://msdn.microsoft.com/en-us/library/cc236695.aspx
            const int micFieldOffset = 72;

            ByteWriter.WriteBytes(type3, micFieldOffset, new byte[16]);
            byte[] temp     = ByteUtils.Concatenate(ByteUtils.Concatenate(type1, type2), type3);
            byte[] mic      = new HMACMD5(exportedSessionKey).ComputeHash(temp);
            byte[] expected = new byte[] { 0xae, 0xa7, 0xba, 0x44, 0x4e, 0x93, 0xa7, 0xdb, 0xb3, 0x0c, 0x85, 0x49, 0xc2, 0x2b, 0xba, 0x9a };

            Assert.IsTrue(ByteUtils.AreByteArraysEqual(mic, expected));
        }
Exemple #4
0
        public void TestLMMIC()
        {
            string password = "******";

            byte[] type1 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x97, 0x82, 0x08, 0xe2,
                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                        0x06, 0x01, 0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f };
            byte[] type2 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
                                        0x38, 0x00, 0x00, 0x00, 0x95, 0x00, 0x82, 0xa2, 0x28, 0x96, 0xe3, 0x6a, 0xd1, 0xb7, 0x74, 0xb8,
                                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x3e, 0x00, 0x00, 0x00,
                                        0x05, 0x02, 0xce, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x02, 0x00,
                                        0x06, 0x00, 0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x01, 0x00, 0x06, 0x00, 0x54, 0x00, 0x41, 0x00,
                                        0x4c, 0x00, 0x00, 0x00, 0x00, 0x00 };
            byte[] type3 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00,
                                        0x7c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x94, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00,
                                        0x58, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x66, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00,
                                        0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x95, 0x00, 0x80, 0xa2,
                                        0x06, 0x01, 0xb1, 0x1d, 0x00, 0x00, 0x00, 0x0f, 0x4e, 0x65, 0x54, 0xe6, 0xb3, 0xdc, 0xdc, 0x16,
                                        0xef, 0xc4, 0xd0, 0x03, 0x3b, 0x81, 0x61, 0x6f, 0x54, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x2d, 0x00,
                                        0x56, 0x00, 0x4d, 0x00, 0x37, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x54, 0x00,
                                        0x41, 0x00, 0x4c, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x37, 0x00, 0xc1, 0xd1, 0x06, 0x56,
                                        0xa3, 0xa9, 0x64, 0x14, 0x0e, 0x7f, 0x43, 0x19, 0x3f, 0x29, 0xf3, 0x72, 0xa3, 0xc1, 0xbe, 0x02,
                                        0xd0, 0x6f, 0xff, 0x20, 0xc1, 0xd1, 0x06, 0x56, 0xa3, 0xa9, 0x64, 0x14, 0x0e, 0x7f, 0x43, 0x19,
                                        0x3f, 0x29, 0xf3, 0x72, 0xa3, 0xc1, 0xbe, 0x02, 0xd0, 0x6f, 0xff, 0x20 };

            byte[] serverChallenge = new ChallengeMessage(type2).ServerChallenge;
            AuthenticateMessage authenticateMessage = new AuthenticateMessage(type3);

            byte[] sessionBaseKey     = new MD4().GetByteHashFromBytes(NTLMCryptography.NTOWFv1(password));
            byte[] lmowf              = NTLMCryptography.LMOWFv1(password);
            byte[] exportedSessionKey = GetExportedSessionKey(sessionBaseKey, authenticateMessage, serverChallenge, lmowf);

            // https://msdn.microsoft.com/en-us/library/cc236695.aspx
            const int micFieldOffset = 72;

            ByteWriter.WriteBytes(type3, micFieldOffset, new byte[16]);
            byte[] temp     = ByteUtils.Concatenate(ByteUtils.Concatenate(type1, type2), type3);
            byte[] mic      = new HMACMD5(exportedSessionKey).ComputeHash(temp);
            byte[] expected = new byte[] { 0x4e, 0x65, 0x54, 0xe6, 0xb3, 0xdc, 0xdc, 0x16, 0xef, 0xc4, 0xd0, 0x03, 0x3b, 0x81, 0x61, 0x6f };

            Assert.IsTrue(ByteUtils.AreByteArraysEqual(mic, expected));
        }
Exemple #5
0
 public void NTv1HashTest()
 {
     byte[] hash     = NTLMCryptography.NTOWFv1("Password");
     byte[] expected = new byte[] { 0xa4, 0xf4, 0x9c, 0x40, 0x65, 0x10, 0xbd, 0xca, 0xb6, 0x82, 0x4e, 0xe7, 0xc3, 0x0f, 0xd8, 0x52 };
     Assert.True(ByteUtils.AreByteArraysEqual(hash, expected));
 }
Exemple #6
0
        public static byte[] GetAuthenticateMessage(byte[] securityBlob, string domainName, string userName, string password, AuthenticationMethod authenticationMethod, out byte[] sessionKey)
        {
            sessionKey = null;
            bool useGSSAPI = false;
            SimpleProtectedNegotiationTokenResponse inputToken = null;

            try
            {
                inputToken = SimpleProtectedNegotiationToken.ReadToken(securityBlob, 0, false) as SimpleProtectedNegotiationTokenResponse;
            }
            catch
            {
            }

            ChallengeMessage challengeMessage;

            if (inputToken != null)
            {
                challengeMessage = GetChallengeMessage(inputToken.ResponseToken);
                useGSSAPI        = true;
            }
            else
            {
                challengeMessage = GetChallengeMessage(securityBlob);
            }

            if (challengeMessage == null)
            {
                return(null);
            }

            DateTime time = DateTime.UtcNow;

            byte[] clientChallenge = new byte[8];
            new Random().NextBytes(clientChallenge);

            AuthenticateMessage authenticateMessage = new AuthenticateMessage();

            // https://msdn.microsoft.com/en-us/library/cc236676.aspx
            authenticateMessage.NegotiateFlags = NegotiateFlags.Sign |
                                                 NegotiateFlags.NTLMSessionSecurity |
                                                 NegotiateFlags.AlwaysSign |
                                                 NegotiateFlags.Version |
                                                 NegotiateFlags.Use128BitEncryption |
                                                 NegotiateFlags.Use56BitEncryption;
            if ((challengeMessage.NegotiateFlags & NegotiateFlags.UnicodeEncoding) > 0)
            {
                authenticateMessage.NegotiateFlags |= NegotiateFlags.UnicodeEncoding;
            }
            else
            {
                authenticateMessage.NegotiateFlags |= NegotiateFlags.OEMEncoding;
            }

            if ((challengeMessage.NegotiateFlags & NegotiateFlags.KeyExchange) > 0)
            {
                authenticateMessage.NegotiateFlags |= NegotiateFlags.KeyExchange;
            }

            if (authenticationMethod == AuthenticationMethod.NTLMv1)
            {
                authenticateMessage.NegotiateFlags |= NegotiateFlags.LanManagerSessionKey;
            }
            else
            {
                authenticateMessage.NegotiateFlags |= NegotiateFlags.ExtendedSessionSecurity;
            }

            authenticateMessage.UserName    = userName;
            authenticateMessage.DomainName  = domainName;
            authenticateMessage.WorkStation = Environment.MachineName;
            byte[] sessionBaseKey;
            byte[] keyExchangeKey;
            if (authenticationMethod == AuthenticationMethod.NTLMv1 || authenticationMethod == AuthenticationMethod.NTLMv1ExtendedSessionSecurity)
            {
                if (authenticationMethod == AuthenticationMethod.NTLMv1)
                {
                    authenticateMessage.LmChallengeResponse = NTLMCryptography.ComputeLMv1Response(challengeMessage.ServerChallenge, password);
                    authenticateMessage.NtChallengeResponse = NTLMCryptography.ComputeNTLMv1Response(challengeMessage.ServerChallenge, password);
                }
                else // NTLMv1ExtendedSessionSecurity
                {
                    authenticateMessage.LmChallengeResponse = ByteUtils.Concatenate(clientChallenge, new byte[16]);
                    authenticateMessage.NtChallengeResponse = NTLMCryptography.ComputeNTLMv1ExtendedSessionSecurityResponse(challengeMessage.ServerChallenge, clientChallenge, password);
                }
                // https://msdn.microsoft.com/en-us/library/cc236699.aspx
                sessionBaseKey = new MD4().GetByteHashFromBytes(NTLMCryptography.NTOWFv1(password));
                byte[] lmowf = NTLMCryptography.LMOWFv1(password);
                keyExchangeKey = NTLMCryptography.KXKey(sessionBaseKey, authenticateMessage.NegotiateFlags, authenticateMessage.LmChallengeResponse, challengeMessage.ServerChallenge, lmowf);
            }
            else // NTLMv2
            {
                NTLMv2ClientChallenge clientChallengeStructure = new NTLMv2ClientChallenge(time, clientChallenge, challengeMessage.TargetInfo);
                byte[] clientChallengeStructurePadded          = clientChallengeStructure.GetBytesPadded();
                byte[] ntProofStr = NTLMCryptography.ComputeNTLMv2Proof(challengeMessage.ServerChallenge, clientChallengeStructurePadded, password, userName, domainName);

                authenticateMessage.LmChallengeResponse = NTLMCryptography.ComputeLMv2Response(challengeMessage.ServerChallenge, clientChallenge, password, userName, challengeMessage.TargetName);
                authenticateMessage.NtChallengeResponse = ByteUtils.Concatenate(ntProofStr, clientChallengeStructurePadded);

                // https://msdn.microsoft.com/en-us/library/cc236700.aspx
                byte[] responseKeyNT = NTLMCryptography.NTOWFv2(password, userName, domainName);
                sessionBaseKey = new HMACMD5(responseKeyNT).ComputeHash(ntProofStr);
                keyExchangeKey = sessionBaseKey;
            }
            authenticateMessage.Version = NTLMVersion.Server2003;

            // https://msdn.microsoft.com/en-us/library/cc236676.aspx
            if ((challengeMessage.NegotiateFlags & NegotiateFlags.KeyExchange) > 0)
            {
                sessionKey = new byte[16];
                new Random().NextBytes(sessionKey);
                authenticateMessage.EncryptedRandomSessionKey = RC4.Encrypt(keyExchangeKey, sessionKey);
            }
            else
            {
                sessionKey = keyExchangeKey;
            }

            if (useGSSAPI)
            {
                SimpleProtectedNegotiationTokenResponse outputToken = new SimpleProtectedNegotiationTokenResponse();
                outputToken.ResponseToken = authenticateMessage.GetBytes();
                return(outputToken.GetBytes());
            }
            else
            {
                return(authenticateMessage.GetBytes());
            }
        }