Пример #1
0
        private static AuthenticateMessage CreateAuthenticateMessage(string accountNameToAuth, byte[] lmChallengeResponse, byte[] ntChallengeResponse)
        {
            AuthenticateMessage authenticateMessage = new AuthenticateMessage();

            authenticateMessage.NegotiateFlags = NegotiateFlags.UnicodeEncoding |
                                                 NegotiateFlags.OEMEncoding |
                                                 NegotiateFlags.Sign |
                                                 NegotiateFlags.NTLMSessionSecurity |
                                                 NegotiateFlags.AlwaysSign |
                                                 NegotiateFlags.Version |
                                                 NegotiateFlags.Use128BitEncryption |
                                                 NegotiateFlags.Use56BitEncryption;
            if (AuthenticationMessageUtils.IsNTLMv1ExtendedSessionSecurity(lmChallengeResponse) ||
                AuthenticationMessageUtils.IsNTLMv2NTResponse(ntChallengeResponse))
            {
                authenticateMessage.NegotiateFlags |= NegotiateFlags.ExtendedSessionSecurity;
            }
            else
            {
                authenticateMessage.NegotiateFlags |= NegotiateFlags.LanManagerSessionKey;
            }
            authenticateMessage.UserName            = accountNameToAuth;
            authenticateMessage.LmChallengeResponse = lmChallengeResponse;
            authenticateMessage.NtChallengeResponse = ntChallengeResponse;
            authenticateMessage.Version             = NTLMVersion.Server2003;
            return(authenticateMessage);
        }
Пример #2
0
 private static ChallengeMessage GetChallengeMessage(byte[] messageBytes)
 {
     if (AuthenticationMessageUtils.IsSignatureValid(messageBytes))
     {
         MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(messageBytes);
         if (messageType == MessageTypeName.Challenge)
         {
             try
             {
                 return(new ChallengeMessage(messageBytes));
             }
             catch
             {
                 return(null);
             }
         }
     }
     return(null);
 }
Пример #3
0
        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));
            }

            return(keyExchangeKey);
        }
Пример #4
0
        public virtual NTStatus AcceptSecurityContext(ref GssContext?context, byte[] inputToken, out byte[]?outputToken)
        {
            outputToken = null;
            SimpleProtectedNegotiationToken?spnegoToken = null;

            try
            {
                spnegoToken = SimpleProtectedNegotiationToken.ReadToken(inputToken, 0, false);
            }
            catch
            {
                // ignored
            }

            if (spnegoToken != null)
            {
                if (spnegoToken is SimpleProtectedNegotiationTokenInit tokenInit)
                {
                    if (tokenInit.MechanismTypeList.Count == 0)
                    {
                        return(NTStatus.SEC_E_INVALID_TOKEN);
                    }

                    // RFC 4178: Note that in order to avoid an extra round trip, the first context establishment token
                    // of the initiator's preferred mechanism SHOULD be embedded in the initial negotiation message.
                    byte[]        preferredMechanism   = tokenInit.MechanismTypeList[0];
                    IGssMechanism?mechanism            = FindMechanism(preferredMechanism);
                    bool          isPreferredMechanism = (mechanism != null);
                    if (!isPreferredMechanism)
                    {
                        mechanism = FindMechanism(tokenInit.MechanismTypeList);
                    }

                    if (mechanism == null)
                    {
                        return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
                    }
                    NTStatus status;
                    context = new GssContext(mechanism, null);
                    if (isPreferredMechanism)
                    {
                        status      = mechanism.AcceptSecurityContext(ref context.MechanismContext, tokenInit.MechanismToken, out byte[] mechanismOutput);
                        outputToken = GetSpnegoTokenResponseBytes(mechanismOutput, status, mechanism.Identifier);
                    }
                    else
                    {
                        status      = NTStatus.SEC_I_CONTINUE_NEEDED;
                        outputToken = GetSpnegoTokenResponseBytes(null, status, mechanism.Identifier);
                    }
                    return(status);
                }
                else // SimpleProtectedNegotiationTokenResponse
                {
                    if (context == null)
                    {
                        return(NTStatus.SEC_E_INVALID_TOKEN);
                    }
                    IGssMechanism mechanism = context.Mechanism;
                    SimpleProtectedNegotiationTokenResponse tokenResponse = (SimpleProtectedNegotiationTokenResponse)spnegoToken;
                    NTStatus status = mechanism.AcceptSecurityContext(ref context.MechanismContext, tokenResponse.ResponseToken, out byte[] mechanismOutput);
                    outputToken = GetSpnegoTokenResponseBytes(mechanismOutput, status, null);
                    return(status);
                }
            }

            // [MS-SMB] The Windows GSS implementation supports raw Kerberos / NTLM messages in the SecurityBlob.
            // [MS-SMB2] Windows [..] will also accept raw Kerberos messages and implicit NTLM messages as part of GSS authentication.
            if (!AuthenticationMessageUtils.IsSignatureValid(inputToken))
            {
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(inputToken);
            IGssMechanism?  ntlmAuthenticationProvider = FindMechanism(NtlmSspIdentifier);

            if (ntlmAuthenticationProvider == null)
            {
                return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
            }

            if (messageType == MessageTypeName.Negotiate)
            {
                context = new GssContext(ntlmAuthenticationProvider, null);
            }

            if (context == null)
            {
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            return(ntlmAuthenticationProvider.AcceptSecurityContext(ref context.MechanismContext, inputToken, out outputToken));
        }
Пример #5
0
        public NTStatus AcceptSecurityContext(ref object context, byte[] inputToken, out byte[] outputToken)
        {
            outputToken = null;
            SimpleProtectedNegotiationToken spnegoToken = SimpleProtectedNegotiationToken.ReadToken(inputToken, 0);

            if (spnegoToken != null)
            {
                if (spnegoToken is SimpleProtectedNegotiationTokenInit)
                {
                    SimpleProtectedNegotiationTokenInit tokenInit = (SimpleProtectedNegotiationTokenInit)spnegoToken;
                    IGSSMechanism mechanism = FindMechanism(tokenInit.MechanismTypeList);
                    if (mechanism != null)
                    {
                        byte[]   mechanismOutput;
                        NTStatus status = mechanism.AcceptSecurityContext(ref context, tokenInit.MechanismToken, out mechanismOutput);
                        outputToken = GetSPNEGOTokenResponseBytes(mechanismOutput, status, mechanism.Identifier);
                        m_contextToMechanism[context] = mechanism;
                        return(status);
                    }
                    return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
                }
                else // SimpleProtectedNegotiationTokenResponse
                {
                    IGSSMechanism mechanism;
                    if (!m_contextToMechanism.TryGetValue(context, out mechanism))
                    {
                        // We assume that the problem is not with our implementation and that the client has sent
                        // SimpleProtectedNegotiationTokenResponse without first sending SimpleProtectedNegotiationTokenInit.
                        return(NTStatus.SEC_E_INVALID_TOKEN);
                    }
                    SimpleProtectedNegotiationTokenResponse tokenResponse = (SimpleProtectedNegotiationTokenResponse)spnegoToken;
                    byte[]   mechanismOutput;
                    NTStatus status = mechanism.AcceptSecurityContext(ref context, tokenResponse.ResponseToken, out mechanismOutput);
                    outputToken = GetSPNEGOTokenResponseBytes(mechanismOutput, status, null);
                    return(status);
                }
            }
            else
            {
                // [MS-SMB] The Windows GSS implementation supports raw Kerberos / NTLM messages in the SecurityBlob.
                // [MS-SMB2] Windows [..] will also accept raw Kerberos messages and implicit NTLM messages as part of GSS authentication.
                if (AuthenticationMessageUtils.IsSignatureValid(inputToken))
                {
                    MessageTypeName messageType = AuthenticationMessageUtils.GetMessageType(inputToken);
                    IGSSMechanism   ntlmAuthenticationProvider = FindMechanism(NTLMSSPIdentifier);
                    if (ntlmAuthenticationProvider != null)
                    {
                        NTStatus status = ntlmAuthenticationProvider.AcceptSecurityContext(ref context, inputToken, out outputToken);
                        if (messageType == MessageTypeName.Negotiate)
                        {
                            m_contextToMechanism[context] = ntlmAuthenticationProvider;
                        }
                        return(status);
                    }
                    else
                    {
                        return(NTStatus.SEC_E_SECPKG_NOT_FOUND);
                    }
                }
            }
            return(NTStatus.SEC_E_INVALID_TOKEN);
        }