Inheritance: MessageBase
Beispiel #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 timestamp = DateTime.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);
            }
        }
Beispiel #2
0
        public Type3Message(Type2Message type2, Version osVersion, NtlmAuthLevel level, string userName, string password, string host, NtlmFixes fixes = NtlmFixes.None) : base(3)
        {
            this.type2 = type2;
            this.fixes = fixes;

            challenge = type2.Nonce;
            Domain    = type2.TargetName;
            OSVersion = osVersion;
            Username  = userName;
            Password  = password;
            Level     = level;
            Host      = host;
            Flags     = 0;

            if (osVersion != null)
            {
                Flags |= NtlmFlags.NegotiateVersion;
            }

            if ((type2.Flags & NtlmFlags.NegotiateUnicode) != 0)
            {
                Flags |= NtlmFlags.NegotiateUnicode;
            }
            else
            {
                Flags |= NtlmFlags.NegotiateOem;
            }

            if ((type2.Flags & NtlmFlags.NegotiateNtlm) != 0)
            {
                Flags |= NtlmFlags.NegotiateNtlm;
            }

            if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) != 0)
            {
                Flags |= NtlmFlags.NegotiateNtlm2Key;
            }

            if ((type2.Flags & NtlmFlags.NegotiateTargetInfo) != 0)
            {
                Flags |= NtlmFlags.NegotiateTargetInfo;
            }

            if ((type2.Flags & NtlmFlags.RequestTarget) != 0)
            {
                Flags |= NtlmFlags.RequestTarget;
            }
        }
Beispiel #3
0
        public static void Compute(Type2Message type2, NtlmAuthLevel level, string username, string password, string domain, out byte[] lm, out byte[] ntlm)
        {
            lm = null;

            switch (level)
            {
            case NtlmAuthLevel.LM_and_NTLM:
                lm   = ComputeLM(password, type2.Nonce);
                ntlm = ComputeNtlm(password, type2.Nonce);
                break;

            case NtlmAuthLevel.LM_and_NTLM_and_try_NTLMv2_Session:
                if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) == 0)
                {
                    goto case NtlmAuthLevel.LM_and_NTLM;
                }
                ComputeNtlmV2Session(password, type2.Nonce, out lm, out ntlm);
                break;

            case NtlmAuthLevel.NTLM_only:
                if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) != 0)
                {
                    ComputeNtlmV2Session(password, type2.Nonce, out lm, out ntlm);
                }
                else
                {
                    ntlm = ComputeNtlm(password, type2.Nonce);
                }
                break;

            case NtlmAuthLevel.NTLMv2_only:
                ntlm = ComputeNtlmV2(type2, username, password, domain);
                if (type2.TargetInfo.Timestamp != 0)
                {
                    lm = new byte[24];
                }
                break;

            default:
                throw new InvalidOperationException();
            }
        }
Beispiel #4
0
		public Type3Message (Type2Message type2, string userName, string hostName) : base (3)
		{
			this.type2 = type2;

			Level = NtlmSettings.DefaultAuthLevel;

			challenge = (byte[]) type2.Nonce.Clone ();
			domain = type2.TargetName;
			Username = userName;
			host = hostName;

			Flags = (NtlmFlags) 0x8200;
			if ((type2.Flags & NtlmFlags.NegotiateUnicode) != 0)
				Flags |= NtlmFlags.NegotiateUnicode;
			else
				Flags |= NtlmFlags.NegotiateOem;

			if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) != 0)
				Flags |= NtlmFlags.NegotiateNtlm2Key;
		}
Beispiel #5
0
        public Type3Message(Type2Message type2, NtlmAuthLevel level, string userName, string password, string host) : base(3)
        {
            this.type2 = type2;

            challenge = type2.Nonce;
            Domain    = type2.TargetName;
            Username  = userName;
            Password  = password;
            Level     = level;
            Host      = host;
            Flags     = 0;

            if ((type2.Flags & NtlmFlags.NegotiateUnicode) != 0)
            {
                Flags |= NtlmFlags.NegotiateUnicode;
            }
            else
            {
                Flags |= NtlmFlags.NegotiateOem;
            }

            if ((type2.Flags & NtlmFlags.NegotiateNtlm) != 0)
            {
                Flags |= NtlmFlags.NegotiateNtlm;
            }

            if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) != 0)
            {
                Flags |= NtlmFlags.NegotiateNtlm2Key;
            }

            if ((type2.Flags & NtlmFlags.NegotiateVersion) != 0)
            {
                Flags |= NtlmFlags.NegotiateVersion;
            }
        }
Beispiel #6
0
 public Type3Message(byte[] message, int startIndex, int length) : base(3)
 {
     Decode(message, startIndex, length);
     type2 = null;
 }
Beispiel #7
0
		public Type3Message (byte[] message, int startIndex, int length) : base (3)
		{
			Decode (message, startIndex, length);
			type2 = null;
		}
		public void TestNtlmType2MessageDecode ()
		{
			const string expectedTargetInfo = "02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000";
			var flags = NtlmFlags.NegotiateUnicode | NtlmFlags.NegotiateNtlm | NtlmFlags.TargetTypeDomain | NtlmFlags.NegotiateTargetInfo;
			var type2 = new Type2Message (NtlmType2EncodedMessage, 0, NtlmType2EncodedMessage.Length);

			Assert.AreEqual (flags, type2.Flags, "The expected flags do not match.");
			Assert.AreEqual ("DOMAIN", type2.TargetName, "The expected TargetName does not match.");

			var nonce = HexEncode (type2.Nonce);
			Assert.AreEqual ("0123456789abcdef", nonce, "The expected nonce does not match.");

			var targetInfo = HexEncode (type2.EncodedTargetInfo);
			Assert.AreEqual (expectedTargetInfo, targetInfo, "The expected TargetInfo does not match.");

			Assert.AreEqual ("DOMAIN", type2.TargetInfo.DomainName, "The expected TargetInfo domain name does not match.");
			Assert.AreEqual ("SERVER", type2.TargetInfo.ServerName, "The expected TargetInfo server name does not match.");
			Assert.AreEqual ("domain.com", type2.TargetInfo.DnsDomainName, "The expected TargetInfo DNS domain name does not match.");
			Assert.AreEqual ("server.domain.com", type2.TargetInfo.DnsServerName, "The expected TargetInfo DNS server name does not match.");

			targetInfo = HexEncode (type2.TargetInfo.Encode (true));
			Assert.AreEqual (expectedTargetInfo, targetInfo, "The expected re-encoded TargetInfo does not match.");
		}
Beispiel #9
0
		static MessageBase GetChallengeResponse (string userName, string password, string domain, byte[] token, int startIndex, int length)
		{
			var type2 = new Type2Message (token, startIndex, length);
			var type3 = new Type3Message (type2, userName, string.Empty);
			type3.Password = password;
			type3.Domain = domain;

			return type3;
		}
Beispiel #10
0
		public static void Compute (Type2Message type2, NtlmAuthLevel level, string username, string password, string domain, out byte[] lm, out byte[] ntlm)
		{
			lm = null;

			switch (level) {
			case NtlmAuthLevel.LM_and_NTLM:
				lm = ComputeLM (password, type2.Nonce);
				ntlm = ComputeNtlm (password, type2.Nonce);
				break;
			case NtlmAuthLevel.LM_and_NTLM_and_try_NTLMv2_Session:
				if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) == 0)
					goto case NtlmAuthLevel.LM_and_NTLM;
				ComputeNtlmV2Session (password, type2.Nonce, out lm, out ntlm);
				break;
			case NtlmAuthLevel.NTLM_only:
				if ((type2.Flags & NtlmFlags.NegotiateNtlm2Key) != 0)
					ComputeNtlmV2Session (password, type2.Nonce, out lm, out ntlm);
				else
					ntlm = ComputeNtlm (password, type2.Nonce);
				break;
			case NtlmAuthLevel.NTLMv2_only:
				ntlm = ComputeNtlmV2 (type2, username, password, domain);
				break;
			default:
				throw new InvalidOperationException ();
			}
		}
Beispiel #11
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;
			}
		}