Forráskód Böngészése

IsNTLMv1ExtendedSecurity and IsNTLMv2NTResponse methods added to AuthenticationMessageUtils

Tal Aloni 8 éve
szülő
commit
6772c0c33e

+ 30 - 0
SMBLibrary/Authentication/AuthenticateMessage/AuthenticationMessageUtils.cs

@@ -58,6 +58,36 @@ namespace SMBLibrary.Authentication
             return (signature == AuthenticateMessage.ValidSignature);
         }
 
+        /// <summary>
+        /// If NTLM v1 Extended Security is used, LMResponse starts with 8-byte challenge, followed by 16 bytes of padding (set to zero).
+        /// </summary>
+        /// <remarks>
+        /// LMResponse is 24 bytes for NTLM v1, NTLM v1 Extended Security and NTLM v2.
+        /// </remarks>
+        public static bool IsNTLMv1ExtendedSecurity(byte[] lmResponse)
+        {
+            if (lmResponse.Length == 24)
+            {
+                if (ByteUtils.AreByteArraysEqual(ByteReader.ReadBytes(lmResponse, 0, 8), new byte[8]))
+                {
+                    // Challenge not present, cannot be NTLM v1 Extended Security
+                    return false;
+                }
+                return ByteUtils.AreByteArraysEqual(ByteReader.ReadBytes(lmResponse, 8, 16), new byte[16]);
+            }
+            return false;
+        }
+
+        /// <remarks>
+        /// NTLM v1 / NTLM v1 Extended Security NTResponse is 24 bytes.
+        /// </remarks>
+        public static bool IsNTLMv2NTResponse(byte[] ntResponse)
+        {
+            return (ntResponse.Length >= 48 &&
+                    ntResponse[16] == NTLMv2ClientChallenge.StructureVersion &&
+                    ntResponse[17] == NTLMv2ClientChallenge.StructureVersion);
+        }
+
         public static MessageTypeName GetMessageType(byte[] messageBytes)
         {
             return (MessageTypeName)LittleEndianConverter.ToUInt32(messageBytes, 8);

+ 7 - 3
SMBLibrary/Server/IndependentUserCollection.cs

@@ -96,7 +96,7 @@ namespace SMBLibrary.Server
                         return this[index];
                     }
 
-                    if (ntResponse.Length >= 48)
+                    if (AuthenticationMessageUtils.IsNTLMv2NTResponse(ntResponse))
                     {
                         byte[] clientNTProof = ByteReader.ReadBytes(ntResponse, 0, 16);
                         byte[] clientChallengeStructurePadded = ByteReader.ReadBytes(ntResponse, 16, ntResponse.Length - 16);
@@ -161,8 +161,12 @@ namespace SMBLibrary.Server
             User user;
             if ((message.NegotiateFlags & NegotiateFlags.ExtendedSecurity) > 0)
             {
-                user = AuthenticateV1Extended(message.UserName, m_serverChallenge, message.LmChallengeResponse, message.NtChallengeResponse);
-                if (user == null)
+                if (AuthenticationMessageUtils.IsNTLMv1ExtendedSecurity(message.LmChallengeResponse))
+                {
+                    // NTLM v1 Extended Security:
+                    user = AuthenticateV1Extended(message.UserName, m_serverChallenge, message.LmChallengeResponse, message.NtChallengeResponse);
+                }
+                else
                 {
                     // NTLM v2:
                     user = AuthenticateV2(message.DomainName, message.UserName, m_serverChallenge, message.LmChallengeResponse, message.NtChallengeResponse);

+ 2 - 1
SMBLibrary/Server/SMB1/SessionSetupHelper.cs

@@ -183,7 +183,8 @@ namespace SMBLibrary.Server.SMB1
                                                  NegotiateFlags.Version |
                                                  NegotiateFlags.Use128BitEncryption |
                                                  NegotiateFlags.Use56BitEncryption;
-            if (ntChallengeResponse.Length >= 48)
+            if (AuthenticationMessageUtils.IsNTLMv1ExtendedSecurity(lmChallengeResponse) ||
+                AuthenticationMessageUtils.IsNTLMv2NTResponse(ntChallengeResponse))
             {
                 authenticateMessage.NegotiateFlags |= NegotiateFlags.ExtendedSecurity;
             }

+ 24 - 19
SMBLibrary/Win32/Win32UserCollection.cs

@@ -82,31 +82,36 @@ namespace SMBLibrary.Server.Win32
 
             if ((message.NegotiateFlags & NegotiateFlags.ExtendedSecurity) > 0)
             {
-                // NTLM v1 extended security:
-                byte[] clientChallenge = ByteReader.ReadBytes(message.LmChallengeResponse, 0, 8);
-                byte[] emptyPasswordNTLMv1Response = NTAuthentication.ComputeNTLMv1ExtendedSecurityResponse(m_serverChallenge, clientChallenge, String.Empty);
-                if (ByteUtils.AreByteArraysEqual(emptyPasswordNTLMv1Response, message.NtChallengeResponse))
+                if (AuthenticationMessageUtils.IsNTLMv1ExtendedSecurity(message.LmChallengeResponse))
                 {
-                    return true;
-                }
-
-                // NTLM v2:
-                byte[] _LMv2ClientChallenge = ByteReader.ReadBytes(message.LmChallengeResponse, 16, 8);
-                byte[] emptyPasswordLMv2Response = NTAuthentication.ComputeLMv2Response(m_serverChallenge, _LMv2ClientChallenge, String.Empty, message.UserName, message.DomainName);
-                if (ByteUtils.AreByteArraysEqual(emptyPasswordLMv2Response, message.LmChallengeResponse))
-                {
-                    return true;
+                    // NTLM v1 extended security:
+                    byte[] clientChallenge = ByteReader.ReadBytes(message.LmChallengeResponse, 0, 8);
+                    byte[] emptyPasswordNTLMv1Response = NTAuthentication.ComputeNTLMv1ExtendedSecurityResponse(m_serverChallenge, clientChallenge, String.Empty);
+                    if (ByteUtils.AreByteArraysEqual(emptyPasswordNTLMv1Response, message.NtChallengeResponse))
+                    {
+                        return true;
+                    }
                 }
-
-                if (message.NtChallengeResponse.Length >= 48)
+                else
                 {
-                    byte[] clientNTProof = ByteReader.ReadBytes(message.NtChallengeResponse, 0, 16);
-                    byte[] clientChallengeStructurePadded = ByteReader.ReadBytes(message.NtChallengeResponse, 16, message.NtChallengeResponse.Length - 16);
-                    byte[] emptyPasswordNTProof = NTAuthentication.ComputeNTLMv2Proof(m_serverChallenge, clientChallengeStructurePadded, String.Empty, message.UserName, message.DomainName);
-                    if (ByteUtils.AreByteArraysEqual(clientNTProof, emptyPasswordNTProof))
+                    // NTLM v2:
+                    byte[] _LMv2ClientChallenge = ByteReader.ReadBytes(message.LmChallengeResponse, 16, 8);
+                    byte[] emptyPasswordLMv2Response = NTAuthentication.ComputeLMv2Response(m_serverChallenge, _LMv2ClientChallenge, String.Empty, message.UserName, message.DomainName);
+                    if (ByteUtils.AreByteArraysEqual(emptyPasswordLMv2Response, message.LmChallengeResponse))
                     {
                         return true;
                     }
+
+                    if (AuthenticationMessageUtils.IsNTLMv2NTResponse(message.NtChallengeResponse))
+                    {
+                        byte[] clientNTProof = ByteReader.ReadBytes(message.NtChallengeResponse, 0, 16);
+                        byte[] clientChallengeStructurePadded = ByteReader.ReadBytes(message.NtChallengeResponse, 16, message.NtChallengeResponse.Length - 16);
+                        byte[] emptyPasswordNTProof = NTAuthentication.ComputeNTLMv2Proof(m_serverChallenge, clientChallengeStructurePadded, String.Empty, message.UserName, message.DomainName);
+                        if (ByteUtils.AreByteArraysEqual(clientNTProof, emptyPasswordNTProof))
+                        {
+                            return true;
+                        }
+                    }
                 }
             }
             else