public void LMv1ResponseTest() { byte[] challenge = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; byte[] response = NTLMCryptography.ComputeLMv1Response(challenge, "Password"); byte[] expected = { 0x98, 0xde, 0xf7, 0xb8, 0x7f, 0x88, 0xaa, 0x5d, 0xaf, 0xe2, 0xdf, 0x77, 0x96, 0x88, 0xa1, 0x72, 0xde, 0xf1, 0x1c, 0x7d, 0x5c, 0xcd, 0xef, 0x13 }; Assert.True(ByteUtils.AreByteArraysEqual(response, expected)); }
public void NTLMv1ResponseTest() { byte[] challenge = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; byte[] response = NTLMCryptography.ComputeNTLMv1Response(challenge, "Password"); byte[] expected = { 0x67, 0xc4, 0x30, 0x11, 0xf3, 0x02, 0x98, 0xa2, 0xad, 0x35, 0xec, 0xe6, 0x4f, 0x16, 0x33, 0x1c, 0x44, 0xbd, 0xbe, 0xd9, 0x27, 0x84, 0x1f, 0x94 }; Assert.True(ByteUtils.AreByteArraysEqual(response, expected)); }
public static bool LMv1HashTest() { byte[] hash = NTLMCryptography.LMOWFv1("Password"); byte[] expected = new byte[] { 0xe5, 0x2c, 0xac, 0x67, 0x41, 0x9a, 0x9a, 0x22, 0x4a, 0x3b, 0x10, 0x8f, 0x3f, 0xa6, 0xcb, 0x6d }; bool success = ByteUtils.AreByteArraysEqual(hash, expected); return(success); }
public void LMv2ResponseTest() { byte[] serverChallenge = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; byte[] clientChallenge = new byte[] { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; byte[] response = NTLMCryptography.ComputeLMv2Response(serverChallenge, clientChallenge, "Password", "User", "Domain"); byte[] expected = new byte[] { 0x86, 0xc3, 0x50, 0x97, 0xac, 0x9c, 0xec, 0x10, 0x25, 0x54, 0x76, 0x4a, 0x57, 0xcc, 0xcc, 0x19, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; Assert.True(ByteUtils.AreByteArraysEqual(response, expected)); }
public static bool NTv2HashTest() { byte[] hash = NTLMCryptography.NTOWFv2("Password", "User", "Domain"); byte[] expected = new byte[] { 0x0c, 0x86, 0x8a, 0x40, 0x3b, 0xfd, 0x7a, 0x93, 0xa3, 0x00, 0x1e, 0xf2, 0x2e, 0xf0, 0x2e, 0x3f }; bool success = ByteUtils.AreByteArraysEqual(hash, expected); return(success); }
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); }
public static bool LMv1ResponseTest() { byte[] challenge = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; byte[] response = NTLMCryptography.ComputeLMv1Response(challenge, "Password"); byte[] expected = { 0x98, 0xde, 0xf7, 0xb8, 0x7f, 0x88, 0xaa, 0x5d, 0xaf, 0xe2, 0xdf, 0x77, 0x96, 0x88, 0xa1, 0x72, 0xde, 0xf1, 0x1c, 0x7d, 0x5c, 0xcd, 0xef, 0x13 }; bool success = ByteUtils.AreByteArraysEqual(response, expected); return(success); }
public void NTLMv2ResponseTest() { byte[] serverChallenge = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; byte[] clientChallenge = new byte[] { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; DateTime time = DateTime.FromFileTimeUtc(0); // same as new byte[8] NTLMv2ClientChallenge clientChallengeStructure = new NTLMv2ClientChallenge(time, clientChallenge, "Domain", "Server"); byte[] clientChallengeStructurePadded = clientChallengeStructure.GetBytesPadded(); byte[] clientNTProof = NTLMCryptography.ComputeNTLMv2Proof(serverChallenge, clientChallengeStructurePadded, "Password", "User", "Domain"); byte[] expectedNTProof = new byte[] { 0x68, 0xcd, 0x0a, 0xb8, 0x51, 0xe5, 0x1c, 0x96, 0xaa, 0xbc, 0x92, 0x7b, 0xeb, 0xef, 0x6a, 0x1c }; Assert.True(ByteUtils.AreByteArraysEqual(clientNTProof, expectedNTProof)); }
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)); }
public static bool NTLMv2AuthenticateMessageTest() { byte[] expected = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x54, 0x00, 0x54, 0x00, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x48, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x54, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x35, 0x82, 0x88, 0xe2, 0x05, 0x01, 0x28, 0x0a, 0x00, 0x00, 0x00, 0x0f, 0x44, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x43, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x50, 0x00, 0x55, 0x00, 0x54, 0x00, 0x45, 0x00, 0x52, 0x00, 0x86, 0xc3, 0x50, 0x97, 0xac, 0x9c, 0xec, 0x10, 0x25, 0x54, 0x76, 0x4a, 0x57, 0xcc, 0xcc, 0x19, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x68, 0xcd, 0x0a, 0xb8, 0x51, 0xe5, 0x1c, 0x96, 0xaa, 0xbc, 0x92, 0x7b, 0xeb, 0xef, 0x6a, 0x1c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xda, 0xd2, 0x54, 0x4f, 0xc9, 0x79, 0x90, 0x94, 0xce, 0x1c, 0xe9, 0x0b, 0xc9, 0xd0, 0x3e }; AuthenticateMessage cmp = new AuthenticateMessage(expected); byte[] sessionKey = { 0xc5, 0xda, 0xd2, 0x54, 0x4f, 0xc9, 0x79, 0x90, 0x94, 0xce, 0x1c, 0xe9, 0x0b, 0xc9, 0xd0, 0x3e }; byte[] serverChallenge = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; byte[] clientChallenge = new byte[] { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; byte[] serverAVPair = AVPairUtils.GetAVPairSequence("Domain", "Server"); DateTime time = DateTime.FromFileTimeUtc(0); // same as new byte[8] NTLMv2ClientChallenge clientChallengeStructure = new NTLMv2ClientChallenge(time, clientChallenge, "Domain", "Server"); byte[] clientChallengeStructurePadded = clientChallengeStructure.GetBytesPadded(); byte[] clientNTProof = NTLMCryptography.ComputeNTLMv2Proof(serverChallenge, clientChallengeStructurePadded, "Password", "User", "Domain"); AuthenticateMessage message = new AuthenticateMessage(); message.EncryptedRandomSessionKey = sessionKey; message.Version = new NTLMVersion(5, 1, 2600, NTLMVersion.NTLMSSP_REVISION_W2K3); message.NegotiateFlags = NegotiateFlags.UnicodeEncoding | NegotiateFlags.TargetNameSupplied | NegotiateFlags.Sign | NegotiateFlags.Seal | NegotiateFlags.NTLMSessionSecurity | NegotiateFlags.AlwaysSign | NegotiateFlags.ExtendedSessionSecurity | NegotiateFlags.TargetInfo | NegotiateFlags.Version | NegotiateFlags.Use128BitEncryption | NegotiateFlags.KeyExchange | NegotiateFlags.Use56BitEncryption; message.DomainName = "Domain"; message.WorkStation = "COMPUTER"; message.UserName = "******"; message.LmChallengeResponse = NTLMCryptography.ComputeLMv2Response(serverChallenge, clientChallenge, "Password", "User", "Domain"); message.NtChallengeResponse = ByteUtils.Concatenate(clientNTProof, clientChallengeStructurePadded); byte[] messageBytes = message.GetBytes(); // The payload entries may be distributed differently so we use cmp.GetBytes() bool success = ByteUtils.AreByteArraysEqual(messageBytes, cmp.GetBytes()); return(success); }
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)); }
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)); }
private static byte[] GetExportedSessionKey(byte[] sessionBaseKey, AuthenticateMessage message, byte[] serverChallenge, byte[] lmowf) { byte[] keyExchangeKey; if (AuthenticationMessageUtils.IsNTLMv2NTResponse(message.NtChallengeResponse)) { keyExchangeKey = sessionBaseKey; } else { keyExchangeKey = NTLMCryptography.KXKey(sessionBaseKey, message.NegotiateFlags, message.LmChallengeResponse, serverChallenge, lmowf); } if ((message.NegotiateFlags & NegotiateFlags.KeyExchange) > 0) { return(RC4.Decrypt(keyExchangeKey, message.EncryptedRandomSessionKey)); } else { return(keyExchangeKey); } }
public NTStatus Login(string domainName, string userName, string password, AuthenticationMethod authenticationMethod) { if (!m_isConnected) { throw new InvalidOperationException("A connection must be successfully established before attempting login"); } Capabilities clientCapabilities = Capabilities.NTSMB | Capabilities.RpcRemoteApi | Capabilities.NTStatusCode | Capabilities.NTFind; if (m_unicode) { clientCapabilities |= Capabilities.Unicode; } if (m_largeFiles) { clientCapabilities |= Capabilities.LargeFiles; } if (m_largeRead) { clientCapabilities |= Capabilities.LargeRead; } if (m_serverChallenge != null) { SessionSetupAndXRequest request = new SessionSetupAndXRequest(); request.MaxBufferSize = ClientMaxBufferSize; request.MaxMpxCount = m_maxMpxCount; request.Capabilities = clientCapabilities; request.AccountName = userName; request.PrimaryDomain = domainName; byte[] clientChallenge = new byte[8]; new Random().NextBytes(clientChallenge); if (authenticationMethod == AuthenticationMethod.NTLMv1) { request.OEMPassword = NTLMCryptography.ComputeLMv1Response(m_serverChallenge, password); request.UnicodePassword = NTLMCryptography.ComputeNTLMv1Response(m_serverChallenge, password); } else if (authenticationMethod == AuthenticationMethod.NTLMv1ExtendedSessionSecurity) { // [MS-CIFS] CIFS does not support Extended Session Security because there is no mechanism in CIFS to negotiate Extended Session Security throw new ArgumentException("SMB Extended Security must be negotiated in order for NTLMv1 Extended Session Security to be used"); } else // NTLMv2 { // Note: NTLMv2 over non-extended security session setup is not supported under Windows Vista and later which will return STATUS_INVALID_PARAMETER. // https://msdn.microsoft.com/en-us/library/ee441701.aspx // https://msdn.microsoft.com/en-us/library/cc236700.aspx request.OEMPassword = NTLMCryptography.ComputeLMv2Response(m_serverChallenge, clientChallenge, password, userName, domainName); NTLMv2ClientChallenge clientChallengeStructure = new NTLMv2ClientChallenge(DateTime.UtcNow, clientChallenge, AVPairUtils.GetAVPairSequence(domainName, Environment.MachineName)); byte[] temp = clientChallengeStructure.GetBytesPadded(); byte[] proofStr = NTLMCryptography.ComputeNTLMv2Proof(m_serverChallenge, temp, password, userName, domainName); request.UnicodePassword = ByteUtils.Concatenate(proofStr, temp); } TrySendMessage(request); SMB1Message reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX); if (reply != null) { m_isLoggedIn = (reply.Header.Status == NTStatus.STATUS_SUCCESS); return(reply.Header.Status); } return(NTStatus.STATUS_INVALID_SMB); } else // m_securityBlob != null { byte[] negotiateMessage = NTLMAuthenticationHelper.GetNegotiateMessage(m_securityBlob, domainName, authenticationMethod); if (negotiateMessage == null) { return(NTStatus.SEC_E_INVALID_TOKEN); } SessionSetupAndXRequestExtended request = new SessionSetupAndXRequestExtended(); request.MaxBufferSize = ClientMaxBufferSize; request.MaxMpxCount = m_maxMpxCount; request.Capabilities = clientCapabilities; request.SecurityBlob = negotiateMessage; TrySendMessage(request); SMB1Message reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX); if (reply != null) { if (reply.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED && reply.Commands[0] is SessionSetupAndXResponseExtended) { SessionSetupAndXResponseExtended response = (SessionSetupAndXResponseExtended)reply.Commands[0]; byte[] authenticateMessage = NTLMAuthenticationHelper.GetAuthenticateMessage(response.SecurityBlob, domainName, userName, password, authenticationMethod, out m_sessionKey); if (authenticateMessage == null) { return(NTStatus.SEC_E_INVALID_TOKEN); } m_userID = reply.Header.UID; request = new SessionSetupAndXRequestExtended(); request.MaxBufferSize = ClientMaxBufferSize; request.MaxMpxCount = m_maxMpxCount; request.Capabilities = clientCapabilities; request.SecurityBlob = authenticateMessage; TrySendMessage(request); reply = WaitForMessage(CommandName.SMB_COM_SESSION_SETUP_ANDX); if (reply != null) { m_isLoggedIn = (reply.Header.Status == NTStatus.STATUS_SUCCESS); return(reply.Header.Status); } } else { return(reply.Header.Status); } } return(NTStatus.STATUS_INVALID_SMB); } }
public void TestNTLMv2KeyExchangeMIC() { byte[] responseKeyNT = NTLMCryptography.NTOWFv2("Password", "User", "TAL-VM6"); 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, 0x63, 0x74, 0x79, 0x77, 0xe1, 0xea, 0x35, 0x51, 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, 0x1f, 0x8a, 0xd4, 0xff, 0x01, 0x91, 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, 0x02, 0x01, 0x02, 0x01, 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, 0x96, 0x01, 0x00, 0x00, 0x15, 0x82, 0x88, 0xe2, 0x0a, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x0f, 0x82, 0x3c, 0xff, 0x48, 0xa9, 0x03, 0x13, 0x4c, 0x33, 0x3c, 0x09, 0x87, 0xf3, 0x16, 0x59, 0x89, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x06, 0x65, 0xe3, 0x9f, 0x03, 0xe1, 0xc3, 0xd8, 0x28, 0x7c, 0x9c, 0x35, 0x0d, 0x32, 0x4c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x8a, 0xd4, 0xff, 0x01, 0x91, 0xd2, 0x01, 0x77, 0x71, 0x91, 0x94, 0xb1, 0x6e, 0x66, 0x28, 0x00, 0x00, 0x00, 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, 0x1f, 0x8a, 0xd4, 0xff, 0x01, 0x91, 0xd2, 0x01, 0x06, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x19, 0x0d, 0x73, 0xca, 0x97, 0x30, 0x2a, 0xa7, 0x7a, 0x1f, 0xb6, 0xad, 0xe2, 0xe5, 0x4a, 0x59, 0x4a, 0x93, 0x7e, 0x37, 0xcd, 0x0c, 0xd7, 0x90, 0x25, 0xc4, 0xaf, 0x8a, 0x17, 0x99, 0x69, 0x56, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x1a, 0x00, 0x63, 0x00, 0x69, 0x00, 0x66, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x54, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x31, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x7c, 0xce, 0x0b, 0x92, 0x46, 0x46, 0x0d, 0x5b, 0x3b, 0x11, 0xb4, 0xde, 0x86, 0x28, 0x11 }; byte[] serverChallenge = new ChallengeMessage(type2).ServerChallenge; AuthenticateMessage authenticateMessage = new AuthenticateMessage(type3); byte[] ntProofStr = ByteReader.ReadBytes(authenticateMessage.NtChallengeResponse, 0, 16); byte[] sessionBaseKey = new HMACMD5(responseKeyNT).ComputeHash(ntProofStr); byte[] exportedSessionKey = GetExportedSessionKey(sessionBaseKey, authenticateMessage, serverChallenge, null); // 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[] { 0x82, 0x3c, 0xff, 0x48, 0xa9, 0x03, 0x13, 0x4c, 0x33, 0x3c, 0x09, 0x87, 0xf3, 0x16, 0x59, 0x89 }; Assert.IsTrue(ByteUtils.AreByteArraysEqual(mic, expected)); }
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()); } }
public void LMv1HashTest() { byte[] hash = NTLMCryptography.LMOWFv1("Password"); byte[] expected = new byte[] { 0xe5, 0x2c, 0xac, 0x67, 0x41, 0x9a, 0x9a, 0x22, 0x4a, 0x3b, 0x10, 0x8f, 0x3f, 0xa6, 0xcb, 0x6d }; Assert.True(ByteUtils.AreByteArraysEqual(hash, expected)); }
public void NTv2HashTest() { byte[] hash = NTLMCryptography.NTOWFv2("Password", "User", "Domain"); byte[] expected = new byte[] { 0x0c, 0x86, 0x8a, 0x40, 0x3b, 0xfd, 0x7a, 0x93, 0xa3, 0x00, 0x1e, 0xf2, 0x2e, 0xf0, 0x2e, 0x3f }; Assert.True(ByteUtils.AreByteArraysEqual(hash, expected)); }
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)); }